本文へスキップ

メンション入力

「@」を打つとユーザー候補のドロップダウンが絞り込み表示され、選ぶと藍色のメンションchipとして本文に挿入される。候補は矢印キーで移動、Enterで確定、Escで閉じられる。

プレビュー

入力

操作実際に入力して試せます。

仕様書

向く場面
  • コメント・チャットで特定の人に通知する入力
  • 候補を絞りながら選ばせたいメンション
  • 本文中にチップとして挿入したい場面
避ける場面
  • プレーンテキストしか保存できない入力欄
  • 候補が数千件で全件検索できないケース
構成要素
  • ラベル
  • 編集領域
  • メンションチップ
  • 候補メニュー
  • 候補項目
  • ヒント
持っている状態
  • 通常
  • フォーカス
  • ホバー
  • 押下中
  • 空
キーボード

@ で候補が開き、↑↓ で循環移動、Enter で確定、Esc で閉じる。候補は Tab 不可(mousedown で選択し、編集領域の選択範囲を保つ)

支援技術

編集領域は role=textbox+aria-multiline+aria-labelledby に aria-expanded/controls/activedescendant を同期。候補は role=listbox/option+aria-selected。チップは contenteditable=false

動き

なし

デザインの要点

  • 候補は「直前の空白+@」から caret までの文字列で絞る。文中の @ 全部に反応するとメールアドレスで開いてしまう
  • 候補の確定は click でなく mousedown で行う。click だと先に blur が起き、置き換える選択範囲が消える
  • 確定したチップは contenteditable=false の span にして、直後に NBSP を置いて caret を出す。文字が繋がらない
  • 候補が 0 件でも「該当なし」を出して閉じない。急に消えると打ち間違いに気づけない
実装メモ

本文は contenteditable の div で作り、選択範囲(Range)を操作して @クエリ文字列をメンションchip(contenteditable=false の span)に置き換えています。候補選びは blur で選択が消えないよう mousedown で確定します。実ページでは、送信時に chip の textContent や data 属性からユーザーIDを集めてサーバーへ渡してください。

コード(コピーして使えます)

<div class="mention-wrap" id="mWrap">
  <span class="m-label" id="mLabel">コメントを書く</span>
  <div class="editor-box">
    <div class="editor" id="editor" contenteditable="true" role="textbox" aria-multiline="true" aria-labelledby="mLabel" aria-haspopup="listbox" aria-expanded="false" aria-controls="mMenu" data-placeholder="@ でメンション…"></div>
    <ul class="m-menu" id="mMenu" role="listbox" aria-label="ユーザー候補" hidden></ul>
  </div>
  <p class="m-hint">「@」を入力するとメンション候補が開きます(↑↓ / Enter / Esc)</p>
</div>

タグ

同じカテゴリ「ソーシャル・コミュニケーション」のほかのパーツ

関連パーツ