タグ入力
アルファ<script setup lang="ts">
import { ref } from 'vue'
import { TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText, TagsInputRoot } from 'radix-vue'
import { Icon } from '@iconify/vue'
const modelValue = ref(['Apple', 'Banana'])
</script>
<template>
<TagsInputRoot
v-model="modelValue"
class="flex gap-2 items-center border p-2 rounded-lg w-full max-w-[480px] flex-wrap border-blackA7 bg-white"
>
<TagsInputItem
v-for="item in modelValue"
:key="item"
:value="item"
class="text-white flex shadow-md items-center justify-center gap-2 bg-green8 aria-[current=true]:bg-green9 rounded p-1"
>
<TagsInputItemText class="text-sm pl-1" />
<TagsInputItemDelete class="p-0.5 rounded bg-transparent hover:bg-blackA4">
<Icon icon="lucide:x" />
</TagsInputItemDelete>
</TagsInputItem>
<TagsInputInput
placeholder="Fruits..."
class="text-sm focus:outline-none flex-1 rounded text-green9 bg-transparent placeholder:text-mauve9 px-1"
/>
</TagsInputRoot>
</template>
機能
- 制御することも、制御しないこともできます。
- 完全なキーボードナビゲーション。
- タグの数を制限します。
- クリップボードから値を受け入れます。
- すべてのタグ値をリセットするためのクリアボタン。
インストール
コマンドラインからコンポーネントをインストールします。
$ npm add radix-vue
構造
すべてのパーツをインポートして、それらをまとめます。
<script setup>
import { TagsInputClear, TagsInputDelete, TagsInputInput, TagsInputItem, TagsInputRoot, TagsInputText } from 'radix-vue'
</script>
<template>
<TagsInputRoot>
<TagsInputItem>
<TagsInputItemText />
<TagsInputItemDelete />
</TagsInputItem>
<TagsInputInput />
<TagsInputClear />
</TagsInputRoot>
</template>
APIリファレンス
ルート
すべてのタグ入力コンポーネントのパーツが含まれています。
プロパティ | デフォルト | 型 |
---|---|---|
addOnBlur | boolean
| |
addOnPaste | boolean
| |
addOnTab | boolean
| |
as | 'div' | AsTag | コンポーネント このコンポーネントがレンダリングする要素またはコンポーネント。 |
asChild | boolean 子として渡された要素に対して、デフォルトのレンダリング要素を変更し、そのプロパティと動作をマージします。 詳細については、コンポジションガイドをご覧ください。 | |
convertValue | ((value: string) => AcceptableInputValue) 入力値を希望の型に変換します。オブジェクトを値として使用し、 | |
defaultValue | [] | AcceptableInputValue[] 追加する必要のあるタグの値。タグ入力の状態を制御する必要がない場合に使用します |
delimiter | ',' | string 新しいタグの追加をトリガーする文字。また、 |
dir | 'ltr' | 'rtl' 該当する場合のコンボボックスの読み取り方向。 | |
disabled | boolean
| |
displayValue | value.toString() | ((value: AcceptableInputValue) => string) タグの値を表示します。接尾辞を追加したり、オブジェクトを値として使用する場合など、値に修正を適用する場合に便利です |
duplicate | boolean
| |
id | string | |
max | 0 | number タグの最大数。 |
modelValue | AcceptableInputValue[] タグ入力の制御された値。 | |
name | string 名前/値のペアの一部として、所有フォームとともに送信されるタグ入力の名前。 | |
required | boolean
|
Emit | ペイロード |
---|---|
invalid | [payload: AcceptableInputValue] 値が無効な場合に呼び出されるイベントハンドラー |
update:modelValue | [payload: AcceptableInputValue[]] 値が変更されたときに呼び出されるイベントハンドラー |
スロット(デフォルト) | ペイロード |
---|---|
modelValue | string | Record<string, any> 現在の入力値 |
データ属性 | 値 |
---|---|
[data-disabled] | 無効の場合に存在します |
[data-focused] | 入力にフォーカスがある場合に存在します |
[data-invalid] | 入力値が無効な場合に存在します |
アイテム
タグを保持するコンポーネント。
プロパティ | デフォルト | 型 |
---|---|---|
as | 'div' | AsTag | コンポーネント このコンポーネントがレンダリングする要素またはコンポーネント。 |
asChild | boolean 子として渡された要素に対して、デフォルトのレンダリング要素を変更し、そのプロパティと動作をマージします。 詳細については、コンポジションガイドをご覧ください。 | |
disabled | boolean
| |
value* | string | Record<string, any> タグに関連付けられた値 |
データ属性 | 値 |
---|---|
[data-state] | "active" | "inactive" |
[data-disabled] | 無効の場合に存在します |
ItemText
タグのテキスト部分。アクセシビリティにとって重要です。
プロパティ | デフォルト | 型 |
---|---|---|
as | 'span' | AsTag | コンポーネント このコンポーネントがレンダリングする要素またはコンポーネント。 |
asChild | boolean 子として渡された要素に対して、デフォルトのレンダリング要素を変更し、そのプロパティと動作をマージします。 詳細については、コンポジションガイドをご覧ください。 |
ItemDelete
関連付けられたタグを削除するボタン。
プロパティ | デフォルト | 型 |
---|---|---|
as | 'button' | AsTag | コンポーネント このコンポーネントがレンダリングする要素またはコンポーネント。 |
asChild | boolean 子として渡された要素に対して、デフォルトのレンダリング要素を変更し、そのプロパティと動作をマージします。 詳細については、コンポジションガイドをご覧ください。 |
データ属性 | 値 |
---|---|
[data-state] | "active" | "inactive" |
[data-disabled] | 無効の場合に存在します |
入力
タグ入力用の入力要素。
プロパティ | デフォルト | 型 |
---|---|---|
as | 'input' | AsTag | コンポーネント このコンポーネントがレンダリングする要素またはコンポーネント。 |
asChild | boolean 子として渡された要素に対して、デフォルトのレンダリング要素を変更し、そのプロパティと動作をマージします。 詳細については、コンポジションガイドをご覧ください。 | |
autoFocus | boolean マウント時に要素にフォーカスします。 | |
maxLength | number 許可される最大文字数。 | |
placeholder | string 空のタグ入力に使用するプレースホルダー文字。 |
データ属性 | 値 |
---|---|
[data-invalid] | 入力値が無効な場合に存在します |
クリア
すべてのタグを削除するボタン。
プロパティ | デフォルト | 型 |
---|---|---|
as | 'button' | AsTag | コンポーネント このコンポーネントがレンダリングする要素またはコンポーネント。 |
asChild | boolean 子として渡された要素に対して、デフォルトのレンダリング要素を変更し、そのプロパティと動作をマージします。 詳細については、コンポジションガイドをご覧ください。 |
データ属性 | 値 |
---|---|
[data-disabled] | 無効の場合に存在します |
例
コンボボックス付き
コンボボックスと組み合わせてタグ入力を構成できます。
<script setup lang="ts">
import { ref, watch } from 'vue'
import { ComboboxAnchor, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxItemIndicator, ComboboxLabel, ComboboxRoot, ComboboxTrigger, ComboboxViewport, TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText, TagsInputRoot } from 'radix-vue'
import { Icon } from '@iconify/vue'
const searchTerm = ref('')
const values = ref(['Apple'])
const options = ['Apple', 'Banana', 'Blueberry', 'Grapes', 'Pineapple']
watch(values, () => {
searchTerm.value = ''
}, { deep: true })
</script>
<template>
<ComboboxRoot
v-model="values"
v-model:search-term="searchTerm"
multiple
class="my-4 mx-auto relative"
>
<ComboboxAnchor class="w-[400px] inline-flex items-center justify-between rounded-lg p-2 text-[13px] leading-none 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">
<TagsInputRoot
v-slot="{ modelValue: tags }"
:model-value="values"
delimiter=""
class="flex gap-2 items-center rounded-lg flex-wrap"
>
<TagsInputItem
v-for="item in tags"
:key="item"
:value="item"
class="flex items-center justify-center gap-2 text-white bg-grass8 aria-[current=true]:bg-grass9 rounded px-2 py-1"
>
<TagsInputItemText class="text-sm" />
<TagsInputItemDelete>
<Icon icon="lucide:x" />
</TagsInputItemDelete>
</TagsInputItem>
<ComboboxInput as-child>
<TagsInputInput
placeholder="Fruits..."
class="focus:outline-none flex-1 rounded !bg-transparent placeholder:text-mauve10 px-1"
@keydown.enter.prevent
/>
</ComboboxInput>
</TagsInputRoot>
<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 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-gray-400 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-grass8 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>
貼り付けの動作
add-on-paste
プロパティを渡すことで、貼り付け時にタグを自動的に追加できます。
<script setup lang="ts">
import { TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText, TagsInputRoot } from 'radix-vue'
</script>
<template>
<TagsInputRoot
v-model="modelValue"
add-on-paste
>
…
</TagsInputRoot>
</template>
アクセシビリティ
キーボード操作
キー | 説明 |
---|---|
Delete | タグがアクティブな場合、それを削除し、右側のタグをアクティブに設定します。 |
Backspace | タグがアクティブな場合、それを削除し、左側のタグをアクティブに設定します。左側にタグがない場合は、次のタグにフォーカスするか、入力にフォーカスします。 |
ArrowRight | 次のタグをアクティブに設定します。 |
ArrowLeft | 前のタグをアクティブに設定します。 |
Home | 最初のタグをアクティブに設定します |
End | 最後のタグをアクティブに設定します |