Admin 元件

Select

參考API
下拉選擇器。單選/多選、選項搜尋、tag 顯示、自訂選項渲染。

安裝

Terminal
pnpm dlx shadcn-vue add @admin/select
import {  AdminSelect,  AdminSelectAnchor,  AdminSelectCancel,  AdminSelectCounter,  AdminSelectEmpty,  AdminSelectGroup,  AdminSelectIcon,  AdminSelectInput,  AdminSelectItem,  AdminSelectItemIndicator,  AdminSelectList,  AdminSelectSeparator,  AdminSelectTags,  AdminSelectTrigger,  AdminSelectValue,  AdminSelectViewport,} from '@/components/admin/select'

用法

<script setup lang="ts">import { ref } from 'vue'import {  AdminSelect,  AdminSelectAnchor,  AdminSelectIcon,  AdminSelectItem,  AdminSelectList,  AdminSelectTrigger,  AdminSelectValue,  AdminSelectViewport} from '@/components/admin/select'​const options = [  { label: 'Apple', value: 'apple' },  { label: 'Banana', value: 'banana' },  { label: 'Cherry', value: 'cherry' }] as const​type Fruit = (typeof options)[number]​const value = ref<Fruit>()</script>​<template>  <admin-select v-model="value" by="value" :display-value="(v) => v.label">    <admin-select-anchor class="w-60">      <admin-select-trigger>        <admin-select-value placeholder="選擇水果" />        <admin-select-icon />      </admin-select-trigger>    </admin-select-anchor>    <admin-select-list>      <admin-select-viewport>        <admin-select-item v-for="option in options" :key="option.value" :value="option">          {{ option.label }}        </admin-select-item>      </admin-select-viewport>    </admin-select-list>  </admin-select></template>

場景

多選

<script setup lang="ts">import { ref } from 'vue'import {  AdminSelect,  AdminSelectAnchor,  AdminSelectCounter,  AdminSelectIcon,  AdminSelectItem,  AdminSelectList,  AdminSelectTags,  AdminSelectTrigger,  AdminSelectValue,  AdminSelectViewport} from '@/components/admin/select'​interface Tech {  label: string  value: string}​const options: Tech[] = [  { label: 'Vue', value: 'vue' },  { label: 'Nuxt', value: 'nuxt' },  { label: 'Pinia', value: 'pinia' },  { label: 'VueUse', value: 'vueuse' },  { label: 'Vite', value: 'vite' }]​const selected = ref<Tech[]>([options[0]!, options[1]!])​function displayTech(value: Tech) {  return value.label}​function onSelectedUpdate(value: Tech | Tech[]) {  selected.value = Array.isArray(value) ? value : [value]}</script>​<template>  <admin-select    by="value"    multiple    :display-value="displayTech"    :model-value="selected"    @update:model-value="onSelectedUpdate"  >    <admin-select-anchor class="w-80">      <admin-select-trigger class="h-auto">        <admin-select-tags />        <admin-select-value placeholder="選擇技術" />        <admin-select-counter />        <admin-select-icon />      </admin-select-trigger>    </admin-select-anchor>    <admin-select-list>      <admin-select-viewport>        <admin-select-item v-for="option in options" :key="option.value" :value="option">          {{ option.label }}        </admin-select-item>      </admin-select-viewport>    </admin-select-list>  </admin-select></template>

可搜尋

<script setup lang="ts">import { ref } from 'vue'import {  AdminSelect,  AdminSelectAnchor,  AdminSelectEmpty,  AdminSelectIcon,  AdminSelectInput,  AdminSelectItem,  AdminSelectList,  AdminSelectTrigger,  AdminSelectValue,  AdminSelectViewport} from '@/components/admin/select'​const options = [  { label: 'Taipei 台北', value: 'tpe' },  { label: 'Taichung 台中', value: 'txg' },  { label: 'Tainan 台南', value: 'tnn' },  { label: 'Kaohsiung 高雄', value: 'khh' },  { label: 'Hsinchu 新竹', value: 'hsz' },  { label: 'Taoyuan 桃園', value: 'tyn' },  { label: 'Hualien 花蓮', value: 'hun' }] as const​type City = (typeof options)[number]​const value = ref<City>()</script>​<template>  <admin-select v-model="value" by="value" :display-value="(v) => v.label">    <admin-select-anchor class="w-72">      <admin-select-trigger>        <admin-select-value placeholder="選擇城市" />        <admin-select-icon />      </admin-select-trigger>    </admin-select-anchor>    <admin-select-list>      <admin-select-input placeholder="搜尋城市..." />      <admin-select-viewport>        <admin-select-empty>找不到符合的城市</admin-select-empty>        <admin-select-item v-for="option in options" :key="option.value" :value="option">          {{ option.label }}        </admin-select-item>      </admin-select-viewport>    </admin-select-list>  </admin-select></template>

錯誤狀態

<script setup lang="ts">import { ref } from 'vue'import {  AdminSelect,  AdminSelectAnchor,  AdminSelectIcon,  AdminSelectItem,  AdminSelectList,  AdminSelectTrigger,  AdminSelectValue,  AdminSelectViewport} from '@/components/admin/select'​const options = [  { label: 'Apple', value: 'apple' },  { label: 'Banana', value: 'banana' },  { label: 'Cherry', value: 'cherry' }] as const​type Fruit = (typeof options)[number]​const value = ref<Fruit>()</script>​<template>  <admin-select v-model="value" by="value" is-error :display-value="(v) => v.label">    <admin-select-anchor class="w-60">      <admin-select-trigger>        <admin-select-value placeholder="選擇水果" />        <admin-select-icon />      </admin-select-trigger>    </admin-select-anchor>    <admin-select-list>      <admin-select-viewport>        <admin-select-item v-for="option in options" :key="option.value" :value="option">          {{ option.label }}        </admin-select-item>      </admin-select-viewport>    </admin-select-list>  </admin-select></template>

完整組合

子元件:anchor、trigger(tags/value/counter/icon)、list、input(含 cancel)、viewport、empty、group(heading)、separator、item(含 item-indicator)。

<script setup lang="ts">import { ref } from 'vue'import {  AdminSelect,  AdminSelectAnchor,  AdminSelectCancel,  AdminSelectCounter,  AdminSelectEmpty,  AdminSelectGroup,  AdminSelectIcon,  AdminSelectInput,  AdminSelectItem,  AdminSelectItemIndicator,  AdminSelectList,  AdminSelectSeparator,  AdminSelectTags,  AdminSelectTrigger,  AdminSelectValue,  AdminSelectViewport} from '@/components/admin/select'​interface Tech {  label: string  value: string}​const quickPicks: Tech[] = [  { label: 'Vue', value: 'vue' },  { label: 'Nuxt', value: 'nuxt' }]​const groups: { heading: string; items: Tech[] }[] = [  {    heading: '前端',    items: [      { label: 'Vite', value: 'vite' },      { label: 'VueUse', value: 'vueuse' }    ]  },  {    heading: '後端',    items: [      { label: 'Node', value: 'node' },      { label: 'Nitro', value: 'nitro' },      { label: 'Prisma', value: 'prisma' }    ]  }]​const selected = ref<Tech[]>([quickPicks[0]!, groups[1]!.items[1]!])​function displayTech(value: Tech) {  return value.label}​function onSelectedUpdate(value: Tech | Tech[]) {  selected.value = Array.isArray(value) ? value : [value]}</script>​<template>  <admin-select    by="value"    multiple    :display-value="displayTech"    :model-value="selected"    @update:model-value="onSelectedUpdate"  >    <admin-select-anchor class="w-80">      <admin-select-trigger class="h-auto">        <admin-select-tags />        <admin-select-value placeholder="選擇技術棧" />        <admin-select-counter />        <admin-select-icon />      </admin-select-trigger>    </admin-select-anchor>    <admin-select-list>      <admin-select-input placeholder="搜尋...">        <admin-select-cancel />      </admin-select-input>      <admin-select-viewport>        <admin-select-empty>找不到符合的項目</admin-select-empty>        <admin-select-group>          <admin-select-item v-for="option in quickPicks" :key="option.value" :value="option">            {{ option.label }}            <template #indicator>              <admin-select-item-indicator />            </template>          </admin-select-item>        </admin-select-group>        <admin-select-separator />        <admin-select-group v-for="group in groups" :key="group.heading" :heading="group.heading">          <admin-select-item v-for="option in group.items" :key="option.value" :value="option">            {{ option.label }}            <template #indicator>              <admin-select-item-indicator />            </template>          </admin-select-item>        </admin-select-group>      </admin-select-viewport>    </admin-select-list>  </admin-select></template>

Type-safe 封裝

AdminSelect 已是 generic(T extends AcceptableValue),可直接以較嚴的 v-model 受益。若要讓 v-model 與選項清單的 literal union 對齊,可自行封裝:傳入 options(建議加 as const),由封裝元件以物件為 value 渲染 item,並以 displayValue 顯示 label。

封裝再以 multiple 為條件式泛型的 discriminant:multiple 時 v-model 型別收斂為選項陣列、未開時為單一選項,兩種模式共用同一個封裝元件。

範例:

TypedAdminSelect.vue
<script  setup  lang="ts"  generic="    TOptions extends ReadonlyArray<{      label: string      value: string | number | null    }>,    TMultiple extends boolean = false  ">import type { HTMLAttributes } from 'vue'import type { AdminSelectEmits, AdminSelectProps } from '@/components/admin/select'import { reactiveOmit } from '@vueuse/core'import { useForwardPropsEmits } from 'reka-ui'import { computed } from 'vue'import {  AdminSelect,  AdminSelectAnchor,  AdminSelectIcon,  AdminSelectItem,  AdminSelectList,  AdminSelectTrigger,  AdminSelectValue,  AdminSelectViewport} from '@/components/admin/select'​type TOption = TOptions[number]// modelValue 型別跟著 multiple 走:multiple 時為選項陣列(空選為 []),單選時為單一選項或 null(清除)type TModelValue = TMultiple extends true ? TOption[] : TOption | null​defineOptions({  name: 'typed-admin-select'})​const props = defineProps<  Omit<AdminSelectProps<TOption>, 'modelValue' | 'defaultValue' | 'displayValue' | 'multiple'> & {    options: TOptions    multiple?: TMultiple    modelValue?: TModelValue    defaultValue?: TModelValue    placeholder?: string    displayValue?: (value: TOption) => string    class?: HTMLAttributes['class']  }>()​const emits = defineEmits<  Omit<AdminSelectEmits<TOption>, 'update:modelValue'> & {    'update:modelValue': [value: TModelValue]  }>()​const delegatedProps = reactiveOmit(  props,  'modelValue',  'options',  'placeholder',  'displayValue',  'class')const forwardedAll = useForwardPropsEmits(delegatedProps, emits)​const forwarded = computed(() => {  const { 'onUpdate:modelValue': _, ...rest } = forwardedAll.value  return rest})​// 未提供 displayValue 時預設取 option.label(options 型別已約束含 label)const resolveDisplayValue = computed(() => {  return props.displayValue ?? ((value: TOption) => value.label)})​// 內部綁定不含 null(reka modelValue 不接受 null);null(清除)在此收成 undefined,// 對外 emit 仍依 multiple 吐 [] / null。模型持有的是 option 物件,`?? undefined` 不會誤傷合法值const innerValue = computed<TOption | TOption[] | undefined>({  get() {    return props.modelValue ?? undefined  },  set(value) {    if (props.multiple) {      emits('update:modelValue', (value ?? []) as TModelValue)      return    }    emits('update:modelValue', (value ?? null) as TModelValue)  }})</script>​<template>  <admin-select    v-bind="forwarded"    v-model="innerValue"    by="value"    :display-value="resolveDisplayValue"  >    <admin-select-anchor :class="props.class">      <admin-select-trigger>        <admin-select-value :placeholder="props.placeholder" />        <admin-select-icon />      </admin-select-trigger>    </admin-select-anchor>    <admin-select-list>      <admin-select-viewport>        <admin-select-item          v-for="(option, index) in props.options"          :key="`${option.value}-${index}`"          :value="option"        >          {{ option.label }}        </admin-select-item>      </admin-select-viewport>    </admin-select-list>  </admin-select></template>
需開啟 strictVModel

型別檢查需開啟 strictVModel(若已開啟 strictTemplates 則已包含)。設定見 Type-safe。下列同時含合法綁定與刻意錯誤綁定;錯誤處以 @vue-expect-error 標示。

<script setup lang="ts">import { ref } from 'vue'import TypedAdminSelect from './typed-admin-select-demo.vue'​const options = [  { label: 'Draft', value: 'draft' },  { label: 'Published', value: 'published' }] as const​const status = ref<(typeof options)[number] | null>(options[0])const wrong = ref({ label: 'Unknown', value: 'unknown' })​const selected = ref<(typeof options)[number][]>([options[0]])</script>​<template>  <div class="flex w-full max-w-md flex-col gap-6">    <typed-admin-select v-model="status" class="w-full" placeholder="選擇狀態" :options="options" />​    <!-- @vue-expect-error value 不在 options 的 value union 內 -->    <typed-admin-select v-model="wrong" class="w-full" placeholder="選擇狀態" :options="options" />​    <!-- multiple:modelValue 型別跟著收斂為選項陣列 -->    <typed-admin-select      v-model="selected"      class="w-full"      placeholder="選擇狀態"      multiple      :options="options"    />​    <!-- @vue-expect-error multiple 需要陣列,給單一選項報錯 -->    <typed-admin-select v-model="status" class="w-full" multiple :options="options" />​    <!-- @vue-expect-error 未開 multiple 需要單一選項,給陣列報錯 -->    <typed-admin-select v-model="selected" class="w-full" :options="options" />  </div></template>

API 參考

組成

<template>  <admin-select    v-model="value"    by="value"    multiple    :display-value="(v) => v.label"    :is-error="isError"  >    <admin-select-anchor>      <admin-select-trigger>        <admin-select-tags />        <admin-select-value placeholder="..." />        <admin-select-counter />        <admin-select-icon />      </admin-select-trigger>    </admin-select-anchor>    <admin-select-list>      <admin-select-input placeholder="...">        <admin-select-cancel />      </admin-select-input>      <admin-select-viewport>        <admin-select-empty>無結果</admin-select-empty>        <admin-select-group heading="群組標題">          <admin-select-item v-for="o in options" :key="o.value" :value="o">            {{ o.label }}          </admin-select-item>        </admin-select-group>        <admin-select-separator />      </admin-select-viewport>    </admin-select-list>  </admin-select></template>

admin-select

Props

名稱型別預設值說明
classunknown——
openboolean | undefined—The controlled open state of the Combobox. Can be binded with `v-model:open`.
defaultOpenboolean | undefined—The open state of the combobox when it is initially rendered. Use when you do not need to control its open state.
resetSearchTermOnBlurboolean | undefined`true`Whether to reset the searchTerm when the Combobox input blurred
resetSearchTermOnSelectboolean | undefined`true`Whether to reset the searchTerm when the Combobox value is selected
openOnFocusboolean | undefined`false`Whether to open the combobox when the input is focused
openOnClickboolean | undefined`false`Whether to open the combobox when the input is clicked
ignoreFilterboolean | undefined—When `true`, disable the default filters
resetModelValueOnClearboolean | undefined—When `true` the `modelValue` will be reset to `null` (or `[]` if `multiple`)
modelValueTModelValue | TModelValue[] | undefined—The controlled value of the listbox. Can be binded with `v-model`.
asglobalThis.Component | AsTag | undefined"div"The element or component this component should render as. Can be overwritten by `asChild`.
asChildboolean | undefined—Change the default rendered element for the one passed as a child, merging their props and behavior. Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details.
requiredboolean | undefined—When `true`, indicates that the user must set the value before the owning form can be submitted.
disabledboolean | undefined—When `true`, prevents the user from interacting with listbox
dirDirection | undefined—The reading direction of the listbox when applicable. If omitted, inherits globally from `ConfigProvider` or assumes LTR (left-to-right) reading mode.
defaultValueTModelValue | TModelValue[] | undefined—The value of the listbox when initially rendered. Use when you do not need to control the state of the Listbox
namestring | undefined—The name of the field. Submitted with its owning form as part of a name/value pair.
multipleboolean | undefined—Whether multiple options can be selected or not.
highlightOnHoverboolean | undefined—When `true`, hover over item will trigger highlight
bystring | ((a: TModelValue, b: TModelValue) => boolean) | undefined—Use this to compare objects by a particular field, or pass your own comparison function for complete control over how objects are compared.
deselectableboolean | undefinedtrue已選中之選項是否可再次點擊取消選取
isErrorboolean | undefinedfalse設為 `true` 時為 trigger 套用錯誤狀態邊框
displayValue((value: TModelValue) => string) | undefined—將已選 value 轉成 trigger/tags 顯示文案;未提供時 fallback 為 `String(value)`

Events

名稱Payload說明
update:modelValueTModelValue—
update:openboolean—
highlight{ ref: HTMLElement; value: TModelValue; } | undefined—

Slots

名稱Bindings說明
default{ open: boolean; modelValue: TModelValue | TModelValue[]; }—

admin-select-anchor

Props

名稱型別預設值說明
referenceReferenceElement | undefined—The reference (or anchor) element that is being referred to for positioning. If not provided will use the current component as anchor.
asChildboolean | undefined—Change the default rendered element for the one passed as a child, merging their props and behavior. Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details.
asglobalThis.Component | AsTag | undefined"div"The element or component this component should render as. Can be overwritten by `asChild`.
classClassValue—根元素之自訂 class

Slots

名稱Bindings說明
default{}—

admin-select-trigger

Props

名稱型別預設值說明
disabledboolean | undefined—When `true`, prevents the user from interacting with item
asChildboolean | undefined—Change the default rendered element for the one passed as a child, merging their props and behavior. Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details.
asglobalThis.Component | AsTag | undefined"div"The element or component this component should render as. Can be overwritten by `asChild`.
classClassValue—根元素之自訂 class

Slots

名稱Bindings說明
default{}—

admin-select-value

Props

名稱型別預設值說明
placeholderstring | undefined—未選取選項時顯示之提示文字
classClassValue—根元素之自訂 class

admin-select-icon

Props

名稱型別預設值說明
classClassValue—根元素之自訂 class

admin-select-list

Props

名稱型別預設值說明
forceMountboolean | undefined—Used to force mounting when more control is needed. Useful when controlling animation with Vue animation libraries.
position"inline" | "popper" | undefined"popper"The positioning mode to use, `inline` is the default and you can control the position using CSS. `popper` positions content in the same way as our other primitives, for example `Popover` or `DropdownMenu`.
bodyLockboolean | undefined—The document.body will be lock, and scrolling will be disabled.
hideWhenEmptyboolean | undefinedfalseWhen `true`, hides the content when there are no items matching the filter.
memoDependenciesunknown[] | undefined—Reactive dependencies that should invalidate the memoized content subtree.
side"top" | "right" | "bottom" | "left" | undefined"bottom"The preferred side of the trigger to render against when open. Will be reversed when collisions occur and avoidCollisions is enabled.
sideOffsetnumber | undefined4The distance in pixels from the trigger.
sideFlipboolean | undefinedtrueFlip to the opposite side when colliding with boundary.
align"start" | "end" | "center" | undefined"start"The preferred alignment against the trigger. May change when collisions occur.
alignOffsetnumber | undefined0An offset in pixels from the `start` or `end` alignment options.
alignFlipboolean | undefinedtrueFlip alignment when colliding with boundary. May only occur when `prioritizePosition` is true.
avoidCollisionsboolean | undefinedtrueWhen `true`, overrides the side and align preferences to prevent collisions with boundary edges.
collisionBoundaryElement | (Element | null)[] | null | undefined[]The element used as the collision boundary. By default this is the viewport, though you can provide additional element(s) to be included in this check.
collisionPaddingnumber | Partial<Record<"top" | "right" | "bottom" | "left", number>> | undefined0The distance in pixels from the boundary edges where collision detection should occur. Accepts a number (same for all sides), or a partial padding object, for example: { top: 20, left: 20 }.
arrowPaddingnumber | undefined0The padding between the arrow and the edges of the content. If your content has border-radius, this will prevent it from overflowing the corners.
hideShiftedArrowboolean | undefinedtrueWhen `true`, hides the arrow when it cannot be centered to the reference element.
sticky"partial" | "always" | undefined"partial"The sticky behavior on the align axis. `partial` will keep the content in the boundary as long as the trigger is at least partially in the boundary whilst "always" will keep the content in the boundary regardless.
hideWhenDetachedboolean | undefinedfalseWhether to hide the content when the trigger becomes fully occluded.
positionStrategy"fixed" | "absolute" | undefined—The type of CSS position property to use.
updatePositionStrategy"always" | "optimized" | undefined'optimized'Strategy to update the position of the floating element on every animation frame.
disableUpdateOnLayoutShiftboolean | undefinedfalseWhether to disable the update position for the content when the layout shifted.
prioritizePositionboolean | undefinedfalseForce content to be position within the viewport. Might overlap the reference element, which may not be desired.
referenceReferenceElement | undefined—The custom element or virtual element that will be set as the reference to position the floating element. If provided, it will replace the default anchor element.
dirDirection | undefined—The reading direction of the popper content when applicable. If omitted, inherits globally from `ConfigProvider` or assumes LTR (left-to-right) reading mode.
asChildboolean | undefined—Change the default rendered element for the one passed as a child, merging their props and behavior. Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details.
asglobalThis.Component | AsTag | undefined"div"The element or component this component should render as. Can be overwritten by `asChild`.
disableOutsidePointerEventsboolean | undefined—When `true`, hover/focus/click interactions will be disabled on elements outside the `DismissableLayer`. Users will need to click twice on outside elements to interact with them: once to close the `DismissableLayer`, and again to trigger the element.
classClassValue—根元素之自訂 class
tostring | HTMLElement | undefined—指定 ComboboxPortal 之掛載目標

Slots

名稱Bindings說明
default{}—

admin-select-viewport

Props

名稱型別預設值說明
noncestring | undefined—Will add `nonce` attribute to the style tag which can be used by Content Security Policy. If omitted, inherits globally from `ConfigProvider`.
asChildboolean | undefined—Change the default rendered element for the one passed as a child, merging their props and behavior. Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details.
asglobalThis.Component | AsTag | undefined"div"The element or component this component should render as. Can be overwritten by `asChild`.
classClassValue—根元素之自訂 class

Slots

名稱Bindings說明
default{}—

admin-select-input

Props

名稱型別預設值說明
displayValue((val: any) => string) | undefined—The display value of input for selected item. Does not work with `multiple`.
modelValuestring | undefined—The controlled value of the filter. Can be binded with v-model.
autoFocusboolean | undefined—Focus on element when mounted.
disabledboolean | undefined—When `true`, prevents the user from interacting with item
asChildboolean | undefined—Change the default rendered element for the one passed as a child, merging their props and behavior. Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details.
asglobalThis.Component | AsTag | undefined"div"The element or component this component should render as. Can be overwritten by `asChild`.
classClassValue—根元素之自訂 class
placeholderstring | undefined—搜尋輸入框之提示文字

Slots

名稱Bindings說明
icon{}—
default{}—

admin-select-cancel

Props

名稱型別預設值說明
asChildboolean | undefined—Change the default rendered element for the one passed as a child, merging their props and behavior. Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details.
asglobalThis.Component | AsTag | undefined"div"The element or component this component should render as. Can be overwritten by `asChild`.
classClassValue—根元素之自訂 class

Slots

名稱Bindings說明
default{}—

admin-select-empty

Props

名稱型別預設值說明
asChildboolean | undefined—Change the default rendered element for the one passed as a child, merging their props and behavior. Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details.
asglobalThis.Component | AsTag | undefined"div"The element or component this component should render as. Can be overwritten by `asChild`.
classClassValue—根元素之自訂 class

Slots

名稱Bindings說明
default{}—

admin-select-group

Props

名稱型別預設值說明
asChildboolean | undefined—Change the default rendered element for the one passed as a child, merging their props and behavior. Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details.
asglobalThis.Component | AsTag | undefined"div"The element or component this component should render as. Can be overwritten by `asChild`.
classClassValue—根元素之自訂 class
headingstring | undefined—群組標題;提供時於群組頂部渲染 ComboboxLabel

Slots

名稱Bindings說明
default{}—

admin-select-item

Props

名稱型別預設值說明
textValuestring | undefined—A string representation of the item contents. If the children are not plain text, then the `textValue` prop must also be set to a plain text representation, which will be used for autocomplete in the ComboBox.
value*AcceptableValue—The value given as data when submitted with a `name`.
disabledboolean | undefined—When `true`, prevents the user from interacting with the item.
asChildboolean | undefined—Change the default rendered element for the one passed as a child, merging their props and behavior. Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details.
asglobalThis.Component | AsTag | undefined"div"The element or component this component should render as. Can be overwritten by `asChild`.
classClassValue—根元素之自訂 class

* 代表必填

Events

名稱Payload說明
selectSelectEvent$3<AcceptableValue>—

Slots

名稱Bindings說明
default{}—
indicator{}—

admin-select-item-indicator

Props

名稱型別預設值說明
asChildboolean | undefined—Change the default rendered element for the one passed as a child, merging their props and behavior. Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details.
asglobalThis.Component | AsTag | undefined"div"The element or component this component should render as. Can be overwritten by `asChild`.
classClassValue—根元素之自訂 class

Slots

名稱Bindings說明
default{}—

admin-select-separator

Props

名稱型別預設值說明
asChildboolean | undefined—Change the default rendered element for the one passed as a child, merging their props and behavior. Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details.
asglobalThis.Component | AsTag | undefined"div"The element or component this component should render as. Can be overwritten by `asChild`.
classClassValue—根元素之自訂 class

admin-select-tags

Props

名稱型別預設值說明
classClassValue—根元素之自訂 class
tagClassClassValue—單一 tag 之自訂 class

Slots

名稱Bindings說明
default{ option: AcceptableValue; remove: () => void; }—

admin-select-counter

Props

名稱型別預設值說明
maxnumber | undefined99顯示計數之上限數字
classClassValue—根元素之自訂 class

注意事項

  • trigger 需以 <admin-select-anchor> 包覆:anchor 為 popper 定位錨點,list 的展開位置與寬度以 anchor 為參考;欲設定下拉寬度請把寬度 class 下在 <admin-select-anchor> 上。
  • 搜尋輸入固定於 list 頂部:<admin-select-input> 放在 <admin-select-list> 內、<admin-select-viewport> 之外時會固定不隨清單捲動;item 清單放入 <admin-select-viewport> 提供捲動。
  • 物件 value 請設 by:v-model 綁 option 物件時,建議 by="value"(或自訂比較函式),並以 :display-value 決定 trigger/tags 文案。
  • 單選的 deselectable:預設 true,再次點擊已選項目會清空選擇並關閉下拉;不需此行為時於 root 設 deselectable=false。
  • 搜尋過濾的 label 來源:過濾依據是每顆 <admin-select-item> 的 textContent;若 item 內嵌入 icon / 圖片等非文字節點,建議透過 text-value prop 顯式指定可被過濾的字串。

更新紀錄

  • BREAKING feat!: 收斂為 compound + type-safe,displayValue 取代 options12d3b34
  • BREAKING refactor!: 對齊 shadcn-vue combobox 分件結構並收斂選取狀態a2fc6b7
  • fix: 修正 error 邊框被 focus/open/checked 蓋過dfbeab5
  • BREAKING refactor!: admin-select 的 isError 改由 root 傳入2242110