← 動的パーツギャラリーへ戻る

パーツ番号 03-02-02 ・ JavaScript使用

コマンドパレット風検索

入力欄に文字を打つと候補が絞り込まれ、↑↓キーでハイライト移動・Enterで選択できる検索UI。WordPress管理画面のクイック操作やサイト内検索の入口に。

jsinput

プレビュー

ソースコード

HTML

<div class="d03-02-02-palette">
          <div class="d03-02-02-bar">
            <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="#6b7280" stroke-width="2"><circle cx="11" cy="11" r="7"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
            <input type="text" class="d03-02-02-input" placeholder="コマンドを入力..." aria-label="コマンド検索">
          </div>
          <ul class="d03-02-02-list"></ul>
          <p class="d03-02-02-empty">該当する項目がありません</p>
        </div>

CSS

.prev.d03-02-02{align-items:flex-start}
        .d03-02-02-palette{width:100%;max-width:340px;margin:0 auto;background:#fff;border:1px solid #e5e7eb;border-radius:14px;box-shadow:0 14px 34px rgba(30,41,59,.12);overflow:hidden}
        .d03-02-02-bar{display:flex;align-items:center;gap:10px;padding:12px 14px;border-bottom:1px solid #eef2f7}
        .d03-02-02-input{flex:1;border:0;outline:none;font-size:14px;color:#1f2937;background:transparent}
        .d03-02-02-list{list-style:none;margin:0;padding:6px;max-height:180px;overflow-y:auto}
        .d03-02-02-list li{padding:9px 12px;border-radius:8px;font-size:13.5px;color:#374151;cursor:pointer;transition:background .15s}
        .d03-02-02-list li .k{color:#9ca3af;font-size:11px;float:right}
        .d03-02-02-list li:hover,.d03-02-02-list li.is-active{background:#eef2ff;color:#4338ca}
        .d03-02-02-empty{display:none;padding:16px;text-align:center;color:#9ca3af;font-size:13px;margin:0}
        .d03-02-02-empty.show{display:block}

JavaScript

(function(){
        var root=document.getElementById('item-03-02-02');
        var input=root.querySelector('.d03-02-02-input');
        var list=root.querySelector('.d03-02-02-list');
        var empty=root.querySelector('.d03-02-02-empty');
        var items=[['新規投稿を作成','C'],['メディアを追加','M'],['固定ページ一覧','P'],['プラグイン管理','L'],['テーマを変更','T'],['ユーザー設定','U'],['サイトを表示','V'],['キャッシュ削除','X']];
        var active=-1,view=[];
        function render(){
          var q=input.value.trim().toLowerCase();
          view=items.filter(function(i){return i[0].toLowerCase().indexOf(q)>-1;});
          list.innerHTML=view.map(function(i,idx){return '<li data-i="'+idx+'">'+i[0]+'<span class="k">'+i[1]+'</span></li>';}).join('');
          empty.classList.toggle('show',view.length===0);
          active=view.length?0:-1;highlight();
        }
        function highlight(){
          [].forEach.call(list.children,function(li,idx){li.classList.toggle('is-active',idx===active);});
        }
        function scrollActiveIntoView(){
          if(active>-1&&list.children[active])list.children[active].scrollIntoView({block:'nearest'});
        }
        input.addEventListener('input',render);
        input.addEventListener('keydown',function(e){
          if(e.key==='ArrowDown'){e.preventDefault();if(view.length){active=(active+1)%view.length;highlight();scrollActiveIntoView();}}
          else if(e.key==='ArrowUp'){e.preventDefault();if(view.length){active=(active-1+view.length)%view.length;highlight();scrollActiveIntoView();}}
          else if(e.key==='Enter'){e.preventDefault();if(active>-1)input.value=view[active][0];render();}
        });
        list.addEventListener('click',function(e){var li=e.target.closest('li');if(li){input.value=view[+li.dataset.i][0];render();}});
        render();
      })();

クラス名 .d03-02-02 は本ライブラリ内での識別用です。複数のパーツを同じページで使う場合は、重複しないよう名前を変更してください。