メンション Mention

テキスト入力中に@でユーザーを候補表示し選択するUI。チームコミュニケーションの必須機能。

使用場面: コメントやチャットで@入力時にユーザー候補を表示してメンションする場面 採用例: Slack, Notion

ライブデモ

田中太郎
エンジニア
佐藤花子
デザイナー
鈴木一郎
PM
高橋美咲
マーケティング

ソースコード

<div class="demo-mention-wrapper">
  <label class="demo-mention-label">コメントを入力(@でメンション)</label>
  <div class="demo-mention-input-area">
    <div class="demo-mention-input" contenteditable="true" data-placeholder="@を入力してメンションを追加..."></div>
    <div class="demo-mention-dropdown">
      <div class="demo-mention-option" data-name="田中太郎">
        <div class="demo-mention-opt-avatar">田</div>
        <div><div class="demo-mention-opt-name">田中太郎</div><div class="demo-mention-opt-role">エンジニア</div></div>
      </div>
      <div class="demo-mention-option" data-name="佐藤花子">
        <div class="demo-mention-opt-avatar">佐</div>
        <div><div class="demo-mention-opt-name">佐藤花子</div><div class="demo-mention-opt-role">デザイナー</div></div>
      </div>
      <div class="demo-mention-option" data-name="鈴木一郎">
        <div class="demo-mention-opt-avatar">鈴</div>
        <div><div class="demo-mention-opt-name">鈴木一郎</div><div class="demo-mention-opt-role">PM</div></div>
      </div>
      <div class="demo-mention-option" data-name="高橋美咲">
        <div class="demo-mention-opt-avatar">高</div>
        <div><div class="demo-mention-opt-name">高橋美咲</div><div class="demo-mention-opt-role">マーケティング</div></div>
      </div>
    </div>
  </div>
</div>
.demo-mention-wrapper { padding: 12px; min-height: 280px; }
.demo-mention-label { display: block; font-size: 13px; color: #555; margin-bottom: 8px; font-weight: 600; }
.demo-mention-input-area { position: relative; }
.demo-mention-input {
  min-height: 80px; padding: 12px; border: 1px solid #e5e7eb;
  border-radius: 10px; font-size: 14px; color: #333; line-height: 1.6;
  outline: none; transition: border-color 0.2s;
}
.demo-mention-input:focus { border-color: var(--ui-primary); }
.demo-mention-input:empty::before {
  content: attr(data-placeholder); color: #bbb;
}
.demo-mention-input .demo-mention-tag {
  color: var(--ui-primary); font-weight: 600;
  background: color-mix(in srgb, var(--ui-primary) 10%, transparent);
  padding: 1px 4px; border-radius: 4px;
}
.demo-mention-dropdown {
  display: none; position: absolute; left: 0; right: 0;
  bottom: calc(100% + 4px); background: #fff;
  border: 1px solid #e5e7eb; border-radius: 10px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.1); padding: 4px;
  z-index: 10; max-height: 200px; overflow-y: auto;
}
.demo-mention-dropdown.open { display: block; }
.demo-mention-option {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  border-radius: 8px; cursor: pointer; transition: background 0.15s;
}
.demo-mention-option:hover, .demo-mention-option.selected {
  background: color-mix(in srgb, var(--ui-primary) 8%, transparent);
}
.demo-mention-opt-avatar {
  width: 32px; height: 32px; border-radius: 50%;
  background: color-mix(in srgb, var(--ui-primary) 15%, #fff);
  color: var(--ui-primary); display: flex; align-items: center;
  justify-content: center; font-weight: 700; font-size: 13px; flex-shrink: 0;
}
.demo-mention-opt-name { font-size: 13px; font-weight: 600; color: #111; }
.demo-mention-opt-role { font-size: 11px; color: #999; }
(function(){
  var input = document.querySelector('.demo-mention-input');
  var dropdown = document.querySelector('.demo-mention-dropdown');
  var options = document.querySelectorAll('.demo-mention-option');
  var mentioning = false;
  input.addEventListener('input', function(){
    var text = this.textContent;
    var atIdx = text.lastIndexOf('@');
    if(atIdx !== -1){
      var query = text.substring(atIdx + 1).toLowerCase();
      var hasMatch = false;
      options.forEach(function(opt){
        var name = opt.dataset.name.toLowerCase();
        if(name.indexOf(query) !== -1){ opt.style.display = 'flex'; hasMatch = true; }
        else { opt.style.display = 'none'; }
      });
      if(hasMatch){ dropdown.classList.add('open'); mentioning = true; }
      else { dropdown.classList.remove('open'); mentioning = false; }
    } else {
      dropdown.classList.remove('open');
      mentioning = false;
    }
  });
  options.forEach(function(opt){
    opt.addEventListener('click', function(){
      var name = this.dataset.name;
      var text = input.textContent;
      var atIdx = text.lastIndexOf('@');
      var before = text.substring(0, atIdx);
      input.innerHTML = before + '<span class="demo-mention-tag">@' + name + '</span>&nbsp;';
      dropdown.classList.remove('open');
      mentioning = false;
      var range = document.createRange();
      range.selectNodeContents(input);
      range.collapse(false);
      var sel = window.getSelection();
      sel.removeAllRanges();
      sel.addRange(range);
      input.focus();
    });
  });
})();

AIプロンプト

Basic
メンション機能をHTML/CSS/JSで作ってください。テキスト入力欄で@を入力するとユーザー候補リストが表示され、選択するとメンションタグが挿入されます。
Custom
以下の仕様でメンション機能を実装してください。
- contenteditable を使ったリッチテキスト入力
- @入力でユーザー候補のドロップダウン表示
- 候補はアバター、名前、役職を表示
- テキスト検索でフィルタリング
- 選択するとタグ化されたメンションを挿入
- プライマリカラー: #2563eb
Advanced
高機能なメンション機能を実装してください。
- 複数トリガー対応(@ユーザー、#チャンネル、:絵文字)
- キーボードナビゲーション(矢印キー + Enter で選択)
- 非同期ユーザー検索(debounce付き)
- 複数メンション対応
- メンションのクリックでプロフィールカード表示
- メンション削除時の一括削除(Backspaceでタグごと削除)
- IME入力(日本語変換)との互換性
- アクセシビリティ(aria-activedescendant, role="listbox")