コンテンツへスキップ

コンボボックス

キーボード操作を完全にサポートした、候補値のリストから選択します。
vue
<script setup lang="ts">
import { ref } from 'vue'
import { ComboboxAnchor, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxItemIndicator, ComboboxLabel, ComboboxRoot, ComboboxSeparator, ComboboxTrigger, ComboboxViewport } from 'radix-vue'
import { Icon } from '@iconify/vue'

const v = ref('')
const options = ['Apple', 'Banana', 'Blueberry', 'Grapes', 'Pineapple']
const vegetables = ['Aubergine', 'Broccoli', 'Carrot', 'Courgette', 'Leek']
</script>

<template>
  <ComboboxRoot
    v-model="v"
    class="relative"
  >
    <ComboboxAnchor class="min-w-[160px] inline-flex items-center justify-between rounded px-[15px] text-[13px] leading-none h-[35px] gap-[5px] bg-white text-grass11 shadow-[0_2px_10px] shadow-black/10 hover:bg-mauve3 focus:shadow-[0_0_0_2px] focus:shadow-black data-[placeholder]:text-grass9 outline-none">
      <ComboboxInput
        class="!bg-transparent outline-none text-grass11 h-full selection:bg-grass5 placeholder-mauve8"
        placeholder="Placeholder..."
      />
      <ComboboxTrigger>
        <Icon
          icon="radix-icons:chevron-down"
          class="h-4 w-4 text-grass11"
        />
      </ComboboxTrigger>
    </ComboboxAnchor>

    <ComboboxContent class="absolute z-10 w-full mt-2 min-w-[160px] bg-white overflow-hidden rounded shadow-[0px_10px_38px_-10px_rgba(22,_23,_24,_0.35),_0px_10px_20px_-15px_rgba(22,_23,_24,_0.2)] will-change-[opacity,transform] data-[side=top]:animate-slideDownAndFade data-[side=right]:animate-slideLeftAndFade data-[side=bottom]:animate-slideUpAndFade data-[side=left]:animate-slideRightAndFade">
      <ComboboxViewport class="p-[5px]">
        <ComboboxEmpty class="text-mauve8 text-xs font-medium text-center py-2" />

        <ComboboxGroup>
          <ComboboxLabel class="px-[25px] text-xs leading-[25px] text-mauve11">
            Fruits
          </ComboboxLabel>

          <ComboboxItem
            v-for="(option, index) in options"
            :key="index"
            class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] pr-[35px] pl-[25px] relative select-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:outline-none data-[highlighted]:bg-grass9 data-[highlighted]:text-grass1"
            :value="option"
          >
            <ComboboxItemIndicator
              class="absolute left-0 w-[25px] inline-flex items-center justify-center"
            >
              <Icon icon="radix-icons:check" />
            </ComboboxItemIndicator>
            <span>
              {{ option }}
            </span>
          </ComboboxItem>
          <ComboboxSeparator class="h-[1px] bg-grass6 m-[5px]" />
        </ComboboxGroup>

        <ComboboxGroup>
          <ComboboxLabel
            class="px-[25px] text-xs leading-[25px] text-mauve11"
          >
            Vegetables
          </ComboboxLabel>
          <ComboboxItem
            v-for="(option, index) in vegetables"
            :key="index"
            class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] pr-[35px] pl-[25px] relative select-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:outline-none data-[highlighted]:bg-grass9 data-[highlighted]:text-grass1"
            :value="option"
          >
            <ComboboxItemIndicator
              class="absolute left-0 w-[25px] inline-flex items-center justify-center"
            >
              <Icon icon="radix-icons:check" />
            </ComboboxItemIndicator>
            <span>
              {{ option }}
            </span>
          </ComboboxItem>
        </ComboboxGroup>
      </ComboboxViewport>
    </ComboboxContent>
  </ComboboxRoot>
</template>

機能

  • 制御または非制御にすることができます。
  • 2つの配置モードを提供します。
  • 項目、ラベル、項目のグループをサポートします。
  • フォーカスは完全に管理されます。
  • 完全なキーボードナビゲーション。
  • カスタムプレースホルダーをサポートします。
  • 右から左への方向をサポートします。

インストール

コマンドラインからコンポーネントをインストールします。

sh
$ npm add radix-vue

構成

すべての部品をインポートして組み合わせてください。

vue
<script setup lang="ts">
import {
  ComboboxAnchor,
  ComboboxArrow,
  ComboboxCancel,
  ComboboxContent,
  ComboboxEmpty,
  ComboboxGroup,
  ComboboxInput,
  ComboboxItem,
  ComboboxItemIndicator,
  ComboboxLabel,
  ComboboxPortal,
  ComboboxRoot,
  ComboboxSeparator,
  ComboboxTrigger,
  ComboboxViewport,
} from 'radix-vue'
</script>

<template>
  <ComboboxRoot>
    <ComboboxAnchor>
      <ComboboxInput />
      <ComboboxTrigger />
      <ComboboxCancel />
    </ComboboxAnchor>

    <ComboboxPortal>
      <ComboboxContent>
        <ComboboxViewport>
          <ComboboxEmpty />

          <ComboboxItem>
            <ComboboxItemIndicator />
          </ComboboxItem>

          <ComboboxGroup>
            <ComboboxLabel />
            <ComboboxItem>
              <ComboboxItemIndicator />
            </ComboboxItem>
          </ComboboxGroup>
          <ComboboxSeparator />
        </ComboboxViewport>

        <ComboboxArrow />
      </ComboboxContent>
    </ComboboxPortal>
  </ComboboxRoot>
</template>

APIリファレンス

ルート

コンボボックスのすべての部品を含みます

プロパティデフォルト
as
'div'
AsTag | コンポーネント

このコンポーネントがレンダリングされる要素またはコンポーネント。`asChild` で上書きできます。

asChild
boolean

子として渡された要素にデフォルトのレンダリング要素を変更し、それらのプロパティと動作をマージします。

詳細については、コンポジションガイドをご覧ください。

defaultOpen
boolean

最初にレンダリングされたときのコンボボックスの開状態。
開状態を制御する必要がない場合に使用します。

defaultValue
AcceptableValue | AcceptableValue[]

最初にレンダリングされたときのコンボボックスの値。コンボボックスの状態を制御する必要がない場合に使用します。

dir
'ltr' | 'rtl'

該当する場合のコンボボックスの読み取り方向。
省略した場合、グローバルに`ConfigProvider`から継承するか、LTR(左から右)の読み取りモードを想定します。

disabled
boolean

`true`の場合、ユーザーがコンボボックスと対話できなくなります。

displayValue
((val: AcceptableValue) => string)

選択された項目の入力の表示値。`multiple`では機能しません。

filterFunction
((val: string[] | number[] | false[] | true[] | Record<string, any>[], term: string) => string[] | number[] | false[] | true[] | Record<string, any>[])

`ComboboxItem`をフィルタリングするためのカスタムフィルタ関数。

modelValue
AcceptableValue | AcceptableValue[]

コンボボックスの制御された値。`v-model`でバインドできます。

multiple
boolean

複数のオプションを選択できるかどうか。

name
string

コンボボックスの名前。名前/値のペアの一部として、所有するフォームと共に送信されます。

open
boolean

コンボボックスの制御された開状態。`v-model:open`でバインドできます。

resetSearchTermOnBlur
true
boolean

コンボボックスの入力がぼやけたときにsearchTermをリセットするかどうか。

searchTerm
string

コンボボックスの制御された検索用語。`v-model:searchTerm`でバインドできます。

selectedValue
AcceptableValue

コンボボックスの現在強調表示されている値。`v-model:selectedValue`でバインドできます。

Emitペイロード
update:modelValue
[value: AcceptableValue]

値が変更されたときに呼び出されるイベントハンドラ。

update:open
[value: boolean]

コンボボックスの開状態が変更されたときに呼び出されるイベントハンドラ。

update:searchTerm
[value: string]

コンボボックスのsearchTermが変更されたときに呼び出されるイベントハンドラ。

update:selectedValue
[value: AcceptableValue]

コンボボックスの強調表示された値が変更されたときに呼び出されるイベントハンドラ。

スロット (デフォルト)ペイロード
open
boolean

現在の開状態

modelValue
AcceptableValue | AcceptableValue[]

現在の有効な値

アンカー

`ComboboxContent`の位置を`popper`に設定した場合、アンカーとして使用されます。

プロパティデフォルト
as
'div'
AsTag | コンポーネント

このコンポーネントがレンダリングされる要素またはコンポーネント。`asChild` で上書きできます。

asChild
boolean

子として渡された要素にデフォルトのレンダリング要素を変更し、それらのプロパティと動作をマージします。

詳細については、コンポジションガイドをご覧ください。

入力

コンボボックスの項目を検索するための入力コンポーネント。

プロパティデフォルト
as
'input'
AsTag | コンポーネント

このコンポーネントがレンダリングされる要素またはコンポーネント。`asChild` で上書きできます。

asChild
boolean

子として渡された要素にデフォルトのレンダリング要素を変更し、それらのプロパティと動作をマージします。

詳細については、コンポジションガイドをご覧ください。

autoFocus
boolean

マウント時に要素にフォーカスします。

disabled
boolean

`true`の場合、ユーザーが項目と対話できなくなります。

type
'text'
string

ネイティブ入力タイプ

トリガー

コンボボックスコンテンツを切り替えるボタン。

プロパティデフォルト
as
'button'
AsTag | コンポーネント

このコンポーネントがレンダリングされる要素またはコンポーネント。`asChild` で上書きできます。

asChild
boolean

子として渡された要素にデフォルトのレンダリング要素を変更し、それらのプロパティと動作をマージします。

詳細については、コンポジションガイドをご覧ください。

disabled
boolean

`true`の場合、ユーザーが項目と対話できなくなります。

データ属性
[data-state]"open" | "closed"
[data-disabled]無効な場合に表示されます。

キャンセル

検索用語をクリアするボタン。

プロパティデフォルト
as
'button'
AsTag | コンポーネント

このコンポーネントがレンダリングされる要素またはコンポーネント。`asChild` で上書きできます。

asChild
boolean

子として渡された要素にデフォルトのレンダリング要素を変更し、それらのプロパティと動作をマージします。

詳細については、コンポジションガイドをご覧ください。

項目がクエリに一致しない場合に表示されます。

プロパティデフォルト
as
'div'
AsTag | コンポーネント

このコンポーネントがレンダリングされる要素またはコンポーネント。`asChild` で上書きできます。

asChild
boolean

子として渡された要素にデフォルトのレンダリング要素を変更し、それらのプロパティと動作をマージします。

詳細については、コンポジションガイドをご覧ください。

ポータル

使用する場合、コンテンツ部分を`body`にポータルします。

`ComboboxContent`の位置を`popper`に設定して、`Popover`または`DropdownMenu`と同様に位置が自動的に計算されるようにする必要があります。

プロパティデフォルト
disabled
boolean

テレポートを無効にして、コンポーネントをインラインでレンダリングします。

参照

forceMount
boolean

より多くの制御が必要な場合にマウントを強制するために使用します。Vueアニメーションライブラリでアニメーションを制御する場合に役立ちます。

to
string | HTMLElement

Vueネイティブテレポートコンポーネントプロパティ`:to`

参照

コンテンツ

コンボボックスが開いているときに表示されるコンポーネント。

プロパティデフォルト
align
'start' | 'center' | 'end'

トリガーに対する優先される配置。衝突が発生したときに変更される可能性があります。

alignOffset
number

`start`または`end`の配置オプションからのピクセル単位のオフセット。

arrowPadding
number

矢印とコンテンツの端の間のパディング。コンテンツにborder-radiusがある場合、これにより角がオーバーフローするのを防ぎます。

as
'div'
AsTag | コンポーネント

このコンポーネントがレンダリングされる要素またはコンポーネント。`asChild` で上書きできます。

asChild
boolean

子として渡された要素にデフォルトのレンダリング要素を変更し、それらのプロパティと動作をマージします。

詳細については、コンポジションガイドをご覧ください。

avoidCollisions
boolean

`true`の場合、境界線の端との衝突を防ぐために、sideとalignの設定を上書きします。

bodyLock
boolean

document.bodyがロックされ、スクロールが無効になります。

collisionBoundary
Element | (Element | null)[] | null

衝突境界として使用される要素。デフォルトではビューポートですが、このチェックに含める追加の要素を提供できます。

collisionPadding
number | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>>

境界線の端から衝突検出が発生する距離(ピクセル単位)。数値(すべての辺で同じ)、または部分的なパディングオブジェクト(例:{ top: 20, left: 20 })を受け入れます。

disableOutsidePointerEvents
boolean

`true`の場合、`DismissableLayer`の外側の要素では、ホバー/フォーカス/クリック操作が無効になります。ユーザーは外側の要素と対話するために2回クリックする必要があります。1回目は`DismissableLayer`を閉じ、2回目は要素をトリガーします。

dismissable
boolean

コンポーネントをdismissableLayerにすることを許可します。

forceMount
boolean

より多くの制御が必要な場合にマウントを強制するために使用します。Vueアニメーションライブラリでアニメーションを制御する場合に役立ちます。

hideWhenDetached
boolean

トリガーが完全に隠れたときにコンテンツを隠すかどうか。

position
'inline' | 'popper'

使用する配置モード。
`inline`はデフォルトであり、CSSを使用して位置を制御できます。
`popper`は、他のプリミティブ(例:`Popover`または`DropdownMenu`)と同じ方法でコンテンツを配置します。

prioritizePosition
boolean

コンテンツをビューポート内に配置することを強制します。

参照要素と重なる可能性があり、望ましくない場合があります。

side
'top' | 'right' | 'bottom' | 'left'

開いているときにトリガーに対してレンダリングする優先側。衝突が発生し、avoidCollisionsが有効になっている場合、逆になります。

sideOffset
number

トリガーからの距離(ピクセル単位)。

sticky
'partial' | 'always'

整列軸のスティッキー動作。`partial`は、トリガーが境界内に少なくとも部分的にある限り、コンテンツを境界内に維持しますが、「always」は、境界内にあるかどうかに関係なく、コンテンツを境界内に維持します。

updatePositionStrategy
'always' | 'optimized'

すべてのアニメーションフレームでフローティング要素の位置を更新する戦略。

Emitペイロード
escapeKeyDown
[event: KeyboardEvent]

Escapeキーを押下した時に呼び出されるイベントハンドラです。キャンセル可能です。

focusOutside
[イベント: FocusOutsideEvent]

フォーカスがDismissableLayerの外に移動した時に呼び出されるイベントハンドラです。キャンセル可能です。

interactOutside
[イベント: PointerDownOutsideEvent | FocusOutsideEvent]

DismissableLayerの外でインタラクションが発生した時に呼び出されるイベントハンドラです。具体的には、pointerdownイベントが外で発生した場合、またはフォーカスが外に移動した場合です。キャンセル可能です。

pointerDownOutside
[イベント: PointerDownOutsideEvent]

pointerdownイベントがDismissableLayerの外で発生した時に呼び出されるイベントハンドラです。キャンセル可能です。

データ属性
[data-state]"open" | "closed"
[data-side]"left" | "right" | "bottom" | "top"
[data-align]"start" | "end" | "center"
CSS変数説明
--radix-combobox-content-transform-origin
コンテンツと矢印の位置/オフセットから計算されたtransform-originです。position="popper"の場合のみ存在します。
--radix-combobox-content-available-width
トリガーと境界線の端の間の残りの幅です。position="popper"の場合のみ存在します。
--radix-combobox-content-available-height
トリガーと境界線の端の間の残りの高さです。position="popper"の場合のみ存在します。
--radix-combobox-trigger-width
トリガーの幅です。position="popper"の場合のみ存在します。
--radix-combobox-trigger-height
トリガーの高さです。position="popper"の場合のみ存在します。

ビューポート

すべてのアイテムを含むスクロール可能なビューポートです。

プロパティデフォルト
as
'div'
AsTag | コンポーネント

このコンポーネントがレンダリングされる要素またはコンポーネント。`asChild` で上書きできます。

asChild
boolean

子として渡された要素にデフォルトのレンダリング要素を変更し、それらのプロパティと動作をマージします。

詳細については、コンポジションガイドをご覧ください。

nonce
string

スタイルタグにnonce属性を追加します。これはコンテンツセキュリティポリシーで使用できます。
省略した場合、グローバルにConfigProviderから継承されます。

アイテム

コンボボックスアイテムを含むコンポーネントです。

プロパティデフォルト
as
'div'
AsTag | コンポーネント

このコンポーネントがレンダリングされる要素またはコンポーネント。`asChild` で上書きできます。

asChild
boolean

子として渡された要素にデフォルトのレンダリング要素を変更し、それらのプロパティと動作をマージします。

詳細については、コンポジションガイドをご覧ください。

disabled
boolean

trueの場合、ユーザーがアイテムとインタラクトすることを防ぎます。

value*
AcceptableValue

nameと共に送信された際にデータとして与えられる値です。

Emitペイロード
select
[イベント: SelectEvent<AcceptableValue>]

アイテムを選択した時に呼び出されるイベントハンドラです。
event.preventDefaultを呼び出すことでキャンセルできます。

データ属性
[data-state]"checked" | "unchecked"
[data-highlighted]ハイライト表示されている場合に存在します。
[data-disabled]無効な場合に表示されます。

アイテムインジケーター

アイテムが選択された時にレンダリングされます。この要素を直接スタイル設定したり、アイコンを配置するためのラッパーとして使用したり、両方を使用したりできます。

プロパティデフォルト
as
'span'
AsTag | コンポーネント

このコンポーネントがレンダリングされる要素またはコンポーネント。`asChild` で上書きできます。

asChild
boolean

子として渡された要素にデフォルトのレンダリング要素を変更し、それらのプロパティと動作をマージします。

詳細については、コンポジションガイドをご覧ください。

グループ

複数のアイテムをグループ化するために使用します。アクセシビリティを確保するために、ComboboxLabelと組み合わせて使用し、自動ラベル付けを行います。

プロパティデフォルト
as
'div'
AsTag | コンポーネント

このコンポーネントがレンダリングされる要素またはコンポーネント。`asChild` で上書きできます。

asChild
boolean

子として渡された要素にデフォルトのレンダリング要素を変更し、それらのプロパティと動作をマージします。

詳細については、コンポジションガイドをご覧ください。

ラベル

グループのラベルをレンダリングするために使用します。矢印キーではフォーカスできません。

プロパティデフォルト
as
'div'
AsTag | コンポーネント

このコンポーネントがレンダリングされる要素またはコンポーネント。`asChild` で上書きできます。

asChild
boolean

子として渡された要素にデフォルトのレンダリング要素を変更し、それらのプロパティと動作をマージします。

詳細については、コンポジションガイドをご覧ください。

for
string

セパレーター

コンボボックス内のアイテムを視覚的に区切るために使用します。

プロパティデフォルト
as
'div'
AsTag | コンポーネント

このコンポーネントがレンダリングされる要素またはコンポーネント。`asChild` で上書きできます。

asChild
boolean

子として渡された要素にデフォルトのレンダリング要素を変更し、それらのプロパティと動作をマージします。

詳細については、コンポジションガイドをご覧ください。

矢印

コンテンツと共にレンダリングするためのオプションの矢印要素です。これを使用して、トリガーとComboboxContentを視覚的にリンクできます。ComboboxContent内でレンダリングする必要があります。positionpopperに設定されている場合のみ使用できます。

プロパティデフォルト
as
'svg'
AsTag | コンポーネント

このコンポーネントがレンダリングされる要素またはコンポーネント。`asChild` で上書きできます。

asChild
boolean

子として渡された要素にデフォルトのレンダリング要素を変更し、それらのプロパティと動作をマージします。

詳細については、コンポジションガイドをご覧ください。

height
5
number

矢印の高さをピクセル単位で指定します。

width
10
number

矢印の幅をピクセル単位で指定します。

オブジェクトを値としてバインドする

ネイティブのHTMLフォームコントロールは文字列のみを値として提供できますが、radix-vueは複雑なオブジェクトもバインドできます。

アイテムを選択した際に入力値を設定するには、displayValueプロップを設定してください。

vue
<script setup lang="ts">
import { ref } from 'vue'
import { ComboboxContent, ComboboxInput, ComboboxItem, ComboboxPortal, ComboboxRoot } from 'radix-vue'

const people = [
  { id: 1, name: 'Durward Reynolds' },
  { id: 2, name: 'Kenton Towne' },
  { id: 3, name: 'Therese Wunsch' },
  { id: 4, name: 'Benedict Kessler' },
  { id: 5, name: 'Katelyn Rohan' },
]
const selectedPeople = ref(people[0])
</script>

<template>
  <ComboboxRoot
    v-model="selectedPeople"
    :display-value="(v) => v.name"
  >
    <ComboboxInput />
    <ComboboxPortal>
      <ComboboxContent>
        <ComboboxItem
          v-for="person in people"
          :key="person.id"
          :value="person"
          :disabled="person.unavailable"
        >
          {{ person.name }}
        </ComboboxItem>
      </ComboboxContent>
    </ComboboxPortal>
  </ComboboxRoot>
</template>

複数の値を選択する

Comboboxコンポーネントでは、複数の値を選択できます。単一の値ではなく、値の配列を提供することで有効にできます。

vue
<script setup lang="ts">
import { ref } from 'vue'
import { ComboboxRoot } from 'radix-vue'

const people = [
  { id: 1, name: 'Durward Reynolds' },
  { id: 2, name: 'Kenton Towne' },
  { id: 3, name: 'Therese Wunsch' },
  { id: 4, name: 'Benedict Kessler' },
  { id: 5, name: 'Katelyn Rohan' },
]
const selectedPeople = ref([people[0], people[1]])
</script>

<template>
  <ComboboxRoot
    v-model="selectedPeople"
    multiple
  >
    ...
  </ComboboxRoot>
</template>

カスタムフィルタリング

内部的に、ComboboxRootは、関連するComboboxItemをフィルタリングするためのデフォルトのフィルタ関数を適用します(modelValueが文字列型の場合のみ適用されます)。

ただし、この動作は2つの異なる方法で置き換えることができます。

1. filter-functionプロップを提供する

vue
<script setup lang="ts">
import { ref } from 'vue'
import { ComboboxContent, ComboboxInput, ComboboxItem, ComboboxPortal, ComboboxRoot } from 'radix-vue'

const people = [
  { id: 1, name: 'Durward Reynolds' },
  { id: 2, name: 'Kenton Towne' },
  { id: 3, name: 'Therese Wunsch' },
  { id: 4, name: 'Benedict Kessler' },
  { id: 5, name: 'Katelyn Rohan' },
]
const selectedPeople = ref(people[0])

function filterFunction(list: typeof people[number], searchTerm: string) {
  return list.filter((person) => {
    return person.name.toLowerCase().includes(searchTerm.toLowerCase())
  })
}
</script>

<template>
  <ComboboxRoot
    v-model="selectedPeople"
    :filter-function="filterFunction"
  >
    <ComboboxInput />
    <ComboboxPortal>
      <ComboboxContent>
        <ComboboxItem
          v-for="person in people"
          :key="person.id"
          :value="person"
          :disabled="person.unavailable"
        >
          {{ person.name }}
        </ComboboxItem>
      </ComboboxContent>
    </ComboboxPortal>
  </ComboboxRoot>
</template>

2. フィルタリングされたv-forオプション

vue
<script setup lang="ts">
import { ref } from 'vue'
import { ComboboxContent, ComboboxInput, ComboboxItem, ComboboxPortal, ComboboxRoot } from 'radix-vue'

const people = [
  { id: 1, name: 'Durward Reynolds' },
  { id: 2, name: 'Kenton Towne' },
  { id: 3, name: 'Therese Wunsch' },
  { id: 4, name: 'Benedict Kessler' },
  { id: 5, name: 'Katelyn Rohan' },
]
const selectedPeople = ref(people[0])
const searchTerm = ref('')

const filteredPeople = computed(() =>
  searchTerm.value === ''
    ? people
    : people.filter((person) => {
      return person.name.toLowerCase().includes(searchTerm.value.toLowerCase())
    })
)
</script>

<template>
  <ComboboxRoot
    v-model="selectedPeople"
    v-model:searchTerm="searchTerm"
  >
    <ComboboxInput />
    <ComboboxPortal>
      <ComboboxContent>
        <ComboboxItem
          v-for="person in filteredPeople"
          :key="person.id"
          :value="person"
          :disabled="person.unavailable"
        >
          {{ person.name }}
        </ComboboxItem>
      </ComboboxContent>
    </ComboboxPortal>
  </ComboboxRoot>
</template>

カスタムラベル

デフォルトでは、Comboboxは入力内容をスクリーンリーダーのラベルとして使用します。補助技術にアナウンスされる内容をより細かく制御する場合は、Labelコンポーネントを使用してください。

vue
<script setup lang="ts">
import { ref } from 'vue'
import { ComboboxInput, ComboboxRoot, Label } from 'radix-vue'
</script>

<template>
  <ComboboxRoot v-model="selectedPeople">
    <Label for="person">Person: </Label>
    <ComboboxInput
      id="person"
      placeholder="Select a person"
    />
    ...
  </ComboboxRoot>
</template>

無効なアイテムを使用する場合

data-disabled属性を使用して、無効なアイテムに特別なスタイルを追加できます。

vue
<script setup lang="ts">
import { ref } from 'vue'
import {
  ComboboxContent,
  ComboboxInput,
  ComboboxItem,
  ComboboxPortal,
  ComboboxRoot,
} from 'radix-vue'
</script>

<template>
  <ComboboxRoot>
    <ComboboxInput />
    <ComboboxPortal>
      <ComboboxContent>
        <ComboboxItem
          class="ComboboxItem"
          disabled
        >
          ...
        </ComboboxItem>
      </ComboboxContent>
    </ComboboxPortal>
  </ComboboxRoot>
</template>
css
/* styles.css */
.ComboboxItem[data-disabled] {
  color: "gainsboro";
}

セパレーターを使用する場合

Separatorを使用して、アイテム間にセパレーターを追加します。

vue
<script setup lang="ts">
import { ref } from 'vue'
import {
  ComboboxContent,
  ComboboxInput,
  ComboboxItem,
  ComboboxPortal,
  ComboboxRoot,
  ComboboxSeparator
} from 'radix-vue'
</script>

<template>
  <ComboboxRoot>
    <ComboboxInput />
    <ComboboxPortal>
      <ComboboxContent>
        <ComboboxItem></ComboboxItem>
        <ComboboxItem></ComboboxItem>
        <ComboboxItem></ComboboxItem>
        <ComboboxSeparator />
        <ComboboxItem></ComboboxItem>
        <ComboboxItem></ComboboxItem>
        <ComboboxItem></ComboboxItem>
      </ComboboxContent>
    </ComboboxPortal>
  </ComboboxRoot>
</template>

グループ化されたアイテムを使用する場合

GroupLabelを使用して、アイテムをセクションにグループ化します。

vue
<script setup lang="ts">
import { ref } from 'vue'
import {
  ComboboxContent,
  ComboboxGroup,
  ComboboxInput,
  ComboboxItem,
  ComboboxLabel,
  ComboboxPortal,
  ComboboxRoot
} from 'radix-vue'
</script>

<template>
  <ComboboxRoot>
    <ComboboxInput />
    <ComboboxPortal>
      <ComboboxContent>
        <ComboboxGroup>
          <ComboboxLabel>Label</ComboboxLabel>
          <ComboboxItem></ComboboxItem>
          <ComboboxItem></ComboboxItem>
          <ComboboxItem></ComboboxItem>
        </ComboboxGroup>
      </ComboboxContent>
    </ComboboxPortal>
  </ComboboxRoot>
</template>

複雑なアイテムを使用する場合

アイテムにカスタムコンテンツを使用できます。

vue
<script setup lang="ts">
import { ref } from 'vue'
import {
  ComboboxContent,
  ComboboxGroup,
  ComboboxInput,
  ComboboxItem,
  ComboboxItemIndicator,
  ComboboxLabel,
  ComboboxPortal,
  ComboboxRoot
} from 'radix-vue'
</script>

<template>
  <ComboboxRoot>
    <ComboboxInput />
    <ComboboxPortal>
      <ComboboxContent>
        <ComboboxItem>
          <img src="">
          Adolfo Hess
          <ComboboxItemIndicator />
        </ComboboxItem>

      </ComboboxContent>
    </ComboboxPortal>
  </ComboboxRoot>
</template>

選択動作を防止する

デフォルトでは、ComboboxItemを選択するとコンテンツが閉じ、提供された値でmodelValueが更新されます。@select.preventでデフォルト動作をキャンセルできます。

vue
<script setup lang="ts">
import { ref } from 'vue'
import { ComboboxContent, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxItemIndicator, ComboboxLabel, ComboboxPortal, ComboboxRoot } from 'radix-vue'
</script>

<template>
  <ComboboxRoot>
    <ComboboxInput />
    <ComboboxPortal>
      <ComboboxContent>
        <ComboboxItem @select.prevent>
          Item A
        </ComboboxItem>

      </ComboboxContent>
    </ComboboxPortal>
  </ComboboxRoot>
</template>

アクセシビリティ

コンボボックスWAI-ARIAデザインパターンに準拠しています。

詳細については、W3Cのコンボボックス自動補完リストの例を参照してください。

キーボード操作

キー説明
Enter
ComboboxItemにフォーカスがある場合、フォーカスされているアイテムを選択します。
ArrowDown
ComboboxInputにフォーカスがある場合、コンボボックスコンテンツを開きます。
アイテムにフォーカスがある場合、フォーカスを次のアイテムに移動します。
ArrowUp
ComboboxInputにフォーカスがある場合、コンボボックスコンテンツを開きます。
アイテムにフォーカスがある場合、フォーカスを前のアイテムに移動します。
Esc
コンボボックスを閉じ、ComboboxInputフィールドに選択されたアイテムを復元します。

カスタムAPI

プリミティブな部分を独自のコンポーネントに抽象化することで、独自のAPIを作成できます。

コマンドメニュー

コンボボックスを使用して、独自のコマンドメニューを作成できます。

使用方法

vue
<script setup lang="ts">
import { Command, CommandItem } from './your-command'
</script>

<template>
  <Command>
    <CommandItem value="1">
      Item 1
    </CommandItem>
    <CommandItem value="2">
      Item 2
    </CommandItem>
    <CommandItem value="3">
      Item 3
    </CommandItem>
  </Command>
</template>

実装

ts
// your-command.ts
export { default as Command } from 'Command.vue'
export { default as CommandItem } from 'CommandItem.vue'
vue
<!-- Command.vue -->
<script setup lang="ts">
import { CheckIcon, ChevronDownIcon, ChevronUpIcon, } from '@radix-icons/vue'
import { ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxPortal, ComboboxRoot, useForwardPropsEmits } from 'radix-vue'
import type { ComboboxRootEmits, ComboboxRootProps } from 'radix-vue'

const props = defineProps<ComboboxRootProps>()
const emits = defineEmits<ComboboxRootEmits>()

const forward = useForwardPropsEmits(props, emits)
</script>

<template>
  <ComboboxRoot
    v-bind="forward"
    :open="true"
    model-value=""
  >
    <ComboboxInput placeholder="Type a command or search..." />

    <ComboboxPortal>
      <ComboboxContent>
        <ComboboxEmpty />
        <ComboboxViewport>
          <slot />
        </ComboboxViewport>
      </ComboboxContent>
    </ComboboxPortal>
  </ComboboxRoot>
</template>
vue
<!-- ComboboxItem.vue -->
<script setup lang="ts">
import { CheckIcon } from '@radix-icons/vue'
import { ComboboxItem, type ComboboxItemProps } from 'radix-vue'

const props = defineProps<ComboboxItemProps>()
</script>

<template>
  <ComboboxItem
    v-bind="props"
    @select.prevent
  >
    <slot />
  </ComboboxItem>
</template>