Reka UI 徽标Reka
backdrop
组件

组合框

从建议值列表中选择,并提供完整的键盘支持。

特性

  • 可受控或不受控。
  • 提供 2 种定位模式。
  • 支持项目、标签、项目组。
  • 焦点管理完善。
  • 完整的键盘导航。
  • 支持自定义占位符。
  • 支持从右到左方向。

安装

从命令行安装此组件。

sh
$ npm add reka-ui

结构

导入所有部分并将其组合。

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

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

    <ComboboxPortal>
      <ComboboxContent>
        <ComboboxViewport>
          <ComboboxItem>
            <ComboboxItemIndicator />
          </ComboboxItem>

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

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

API 参考

包含组合框的所有部分

属性默认类型
as
'div'
AsTag | 组件

此组件应渲染为的元素或组件。可通过 asChild 覆盖。

asChild
布尔值

更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。

阅读我们的 组合指南了解更多详情。

by
string | ((a: AcceptableValue, b: AcceptableValue) => boolean)

使用此属性按特定字段比较对象,或传入您自己的比较函数以完全控制对象的比较方式。

defaultOpen
布尔值

组合框初始渲染时的打开状态。
当您不需要控制其打开状态时使用。

defaultValue
AcceptableValue | AcceptableValue[]

列表框初始渲染时的值。当您不需要控制列表框状态时使用

dir
'ltr' | 'rtl'

适用时列表框的阅读方向。
如果省略,则全局继承自 ConfigProvider 或假定为 LTR(从左到右)阅读模式。

disabled
布尔值

当为 true 时,防止用户与列表框交互

highlightOnHover
布尔值

当为 true 时,鼠标悬停在项目上会触发高亮显示

ignoreFilter
布尔值

当为 true 时,禁用默认过滤器

modelValue
AcceptableValue | AcceptableValue[]

列表框的受控值。可与 v-model 绑定。

multiple
布尔值

是否可以选择多个选项。

name
string

字段的名称。随其所属的表单一起作为名称/值对提交。

open
布尔值

组合框的受控打开状态。可与 v-model:open 绑定。

required
布尔值

当为 true 时,表示用户必须在所属表单提交前设置值。

resetSearchTermOnBlur
true
布尔值

当组合框输入失去焦点时是否重置搜索词

resetSearchTermOnSelect
true
布尔值

当组合框值被选中时是否重置搜索词

openOnFocus
false
布尔值

当输入框获得焦点时是否打开组合框

openOnClick
false
布尔值

当输入框被点击时是否打开组合框

事件触发载荷
highlight
[payload: { ref: HTMLElement; value: AcceptableValue; }]

当高亮元素改变时的事件处理程序。

update:modelValue
[value: AcceptableValue]

值改变时调用的事件处理程序。

update:open
[value: boolean]

当组合框打开状态改变时调用的事件处理程序。

插槽(默认)载荷
open
布尔值

当前打开状态

modelValue
AcceptableValue | AcceptableValue[]

当前活动值

锚点

如果您将 ComboboxContent 的位置设置为 popper,则用作锚点。

属性默认类型
as
'div'
AsTag | 组件

此组件应渲染为的元素或组件。可通过 asChild 覆盖。

asChild
布尔值

更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。

阅读我们的 组合指南了解更多详情。

reference
ReferenceElement

用于定位的参考(或锚点)元素。

如果未提供,将使用当前组件作为锚点。

输入

用于搜索组合框项目的输入组件。

属性默认类型
as
'input'
AsTag | 组件

此组件应渲染为的元素或组件。可通过 asChild 覆盖。

asChild
布尔值

更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。

阅读我们的 组合指南了解更多详情。

autoFocus
布尔值

挂载时聚焦到元素。

disabled
布尔值

当为 true 时,阻止用户与项目交互

displayValue
((val: any) => string)

所选项目的输入显示值。不适用于 multiple

modelValue
string

过滤器的受控值。可与 v-model 绑定。

事件触发载荷
update:modelValue
[string]

值改变时调用的事件处理程序。

触发器

切换组合框内容的按钮。

属性默认类型
as
'button'
AsTag | 组件

此组件应渲染为的元素或组件。可通过 asChild 覆盖。

asChild
布尔值

更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。

阅读我们的 组合指南了解更多详情。

disabled
布尔值

当为 true 时,阻止用户与项目交互

数据属性
[data-state]"打开" | "关闭"
[data-disabled]禁用时存在

取消

清除搜索词的按钮。

属性默认类型
as
'button'
AsTag | 组件

此组件应渲染为的元素或组件。可通过 asChild 覆盖。

asChild
布尔值

更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。

阅读我们的 组合指南了解更多详情。

当没有项目匹配查询时显示。

属性默认类型
as
'div'
AsTag | 组件

此组件应渲染为的元素或组件。可通过 asChild 覆盖。

asChild
布尔值

更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。

阅读我们的 组合指南了解更多详情。

传送门

使用时,将内容部分传送到 body 中。

您需要为 ComboboxContent 设置 position="popper",以确保位置像 PopoverDropdownMenu 一样自动计算。

属性默认类型
defer
布尔值

延迟解析 Teleport 目标,直到应用程序的其他部分挂载(需要 Vue 3.5.0+)

reference

disabled
布尔值

禁用传送并内联渲染组件

reference

forceMount
布尔值

当需要更多控制时,用于强制挂载。在与 Vue 动画库控制动画时很有用。

to
字符串 | HTMLElement

Vue 原生传送组件属性 :to

reference

内容

组合框打开时弹出的组件。

提示
使用 Presence 组件构建 - 支持任何 动画技术,同时保持对 Presence 发出事件的访问。
属性默认类型
align
'start' | 'center' | 'end'

相对于触发器的首选对齐方式。当发生碰撞时可能会改变。

alignOffset
数字

startend 对齐选项的像素偏移量。

arrowPadding
数字

箭头与内容边缘之间的内边距。如果您的内容有 border-radius,这将防止它溢出角落。

as
'div'
AsTag | 组件

此组件应渲染为的元素或组件。可通过 asChild 覆盖。

asChild
布尔值

更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。

阅读我们的 组合指南了解更多详情。

avoidCollisions
布尔值

当为 true 时,覆盖侧边和对齐偏好,以防止与边界边缘发生碰撞。

bodyLock
布尔值

document.body 将被锁定,滚动将被禁用。

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

用作碰撞边界的元素。默认情况下是视口,但您可以提供其他元素以包含在此检查中。

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

碰撞检测应发生的距边界边缘的像素距离。接受一个数字(所有边相同),或一个部分填充对象,例如:{ top: 20, left: 20 }。

disableOutsidePointerEvents
布尔值

当为 true 时,DismissableLayer 外部元素的悬停/聚焦/点击交互将被禁用。用户需要点击外部元素两次才能与它们交互:第一次关闭 DismissableLayer,第二次触发元素。

disableUpdateOnLayoutShift
布尔值

当布局发生偏移时,是否禁用更新内容位置。

forceMount
布尔值

当需要更多控制时,用于强制挂载。在与 Vue 动画库控制动画时很有用。

hideWhenDetached
布尔值

当触发器完全被遮挡时,是否隐藏内容。

position
'inline' | 'popper'

要使用的定位模式,
inline 是默认值,您可以使用 CSS 控制位置。
popper 以与我们其他原语(例如 PopoverDropdownMenu)相同的方式定位内容。

positionStrategy
'fixed' | 'absolute'

要使用的 CSS position 属性类型。

prioritizePosition
布尔值

强制内容在视口内定位。

可能与参考元素重叠,这可能不是期望的结果。

reference
ReferenceElement

将设置为浮动元素定位参考的自定义元素或虚拟元素。

如果提供,它将替换默认的锚点元素。

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

打开时,相对于触发器渲染的首选侧边。当发生碰撞且启用 avoidCollisions 时,将反转。

sideOffset
数字

与触发器的像素距离。

sticky
'部分' | '始终'

对齐轴上的粘性行为。partial 将使内容保持在边界内,只要触发器至少部分在边界内;而 "always" 则无论如何都会将内容保持在边界内。

updatePositionStrategy
'始终' | '优化'

在每个动画帧更新浮动元素位置的策略。

事件触发载荷
escapeKeyDown
[事件: KeyboardEvent]

按下 Esc 键时调用的事件处理程序。可阻止其默认行为。

focusOutside
[事件: FocusOutsideEvent]

当焦点移出 DismissableLayer 时调用的事件处理程序。可阻止其默认行为。

interactOutside
[事件: PointerDownOutsideEvent | FocusOutsideEvent]

DismissableLayer 外部发生交互时调用的事件处理程序。具体来说,当 pointerdown 事件在外部发生或焦点移出时。可阻止其默认行为。

pointerDownOutside
[事件: PointerDownOutsideEvent]

pointerdown 事件在 DismissableLayer 外部发生时调用的事件处理程序。可阻止其默认行为。

数据属性
[data-state]"打开" | "关闭"
[data-side]"左" | "右" | "下" | "上"
[data-align]"开始" | "结束" | "居中"
CSS 变量描述
--reka-combobox-content-transform-origin
根据内容和箭头位置/偏移量计算的 transform-origin。仅当 position="popper" 时存在。
--reka-combobox-content-available-width
触发器与边界边缘之间的剩余宽度。仅当 position="popper" 时存在。
--reka-combobox-content-available-height
触发器与边界边缘之间的剩余高度。仅当 position="popper" 时存在。
--reka-combobox-trigger-width
触发器的宽度。仅当 position="popper" 时存在。
--reka-combobox-trigger-height
触发器的高度。仅当 position="popper" 时存在。

视口

包含所有项目的滚动视口。

属性默认类型
as
'div'
AsTag | 组件

此组件应渲染为的元素或组件。可通过 asChild 覆盖。

asChild
布尔值

更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。

阅读我们的 组合指南了解更多详情。

nonce
string

将向样式标签添加 nonce 属性,此属性可用于内容安全策略 (Content Security Policy)。
如果省略,则全局继承自 ConfigProvider

项目

包含组合框项目的组件。

属性默认类型
as
'div'
AsTag | 组件

此组件应渲染为的元素或组件。可通过 asChild 覆盖。

asChild
布尔值

更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。

阅读我们的 组合指南了解更多详情。

disabled
布尔值

当为 true 时,阻止用户与项目交互。

textValue
string

项目内容的字符串表示形式。

如果子元素不是纯文本,则 textValue 属性也必须设置为纯文本表示形式,此表示形式将用于组合框中的自动完成功能。

值*
AcceptableValue

与 `name` 一起提交时作为数据给出的值。

事件触发载荷
select
[event: SelectEvent<AcceptableValue>]

选择项目时调用的事件处理程序。
可以通过调用 event.preventDefault 来阻止它。

数据属性
[data-state]"选中" | "未选中"
[data-highlighted]高亮时存在
[data-disabled]禁用时存在

项目指示器

当项目被选中时渲染。您可以直接样式化此元素,也可以将其用作放置图标的包装器,或者两者兼可。

属性默认类型
as
'span'
AsTag | 组件

此组件应渲染为的元素或组件。可通过 asChild 覆盖。

asChild
布尔值

更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。

阅读我们的 组合指南了解更多详情。

分组

用于对多个项目进行分组。与 ComboboxLabel 结合使用可确保通过自动标签实现良好的可访问性。

属性默认类型
as
'div'
AsTag | 组件

此组件应渲染为的元素或组件。可通过 asChild 覆盖。

asChild
布尔值

更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。

阅读我们的 组合指南了解更多详情。

标签

用于渲染组的标签。它不能通过方向键获得焦点。

属性默认类型
as
'div'
AsTag | 组件

此组件应渲染为的元素或组件。可通过 asChild 覆盖。

asChild
布尔值

更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。

阅读我们的 组合指南了解更多详情。

for
string

分隔符

用于在组合框中视觉上分隔项目

属性默认类型
as
'div'
AsTag | 组件

此组件应渲染为的元素或组件。可通过 asChild 覆盖。

asChild
布尔值

更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。

阅读我们的 组合指南了解更多详情。

箭头

一个可选的箭头元素,与内容一起渲染。这可用于帮助将触发器与 ComboboxContent 视觉链接起来。必须在 ComboboxContent 内部渲染。仅当 position 设置为 popper 时可用。

属性默认类型
as
'svg'
AsTag | 组件

此组件应渲染为的元素或组件。可通过 asChild 覆盖。

asChild
布尔值

更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。

阅读我们的 组合指南了解更多详情。

高度
5
数字

箭头的像素高度。

rounded
布尔值

当为 true 时,渲染圆角版本的箭头。不适用于 as/asChild

宽度
10
数字

箭头的像素宽度。

虚拟化器

用于实现列表虚拟化的虚拟容器。

警告

组合框项目在传递给虚拟化器之前**必须**手动过滤。请参阅下方示例

有关虚拟化的更多通用信息,请参阅虚拟化指南

属性默认类型
estimateSize
数字

每个项目的估计大小(像素)

options*
AcceptableValue[]

项目列表

overscan
数字

在可见区域之外渲染的项目数量

textContent
((option: AcceptableValue) => string)

每个项目的文本内容,用于实现预输入功能

插槽(默认)载荷
option
null | string | number | bigint | Record<string, any>
virtualizer
Virtualizer<HTMLElement, Element>
virtualItem
VirtualItem

示例

将对象绑定为值

与只允许您提供字符串作为值的原生 HTML 表单控件不同,reka-ui 也支持绑定复杂对象。

请确保设置 displayValue 属性,以便在项目选择时设置输入值。

vue
<script setup lang="ts">
import { ComboboxContent, ComboboxInput, ComboboxItem, ComboboxPortal, ComboboxRoot } from 'reka-ui'
import { ref } from '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">
    <ComboboxInput :display-value="(v) => v.name" />
    <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 { ComboboxRoot } from 'reka-ui'
import { ref } from '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 将根据渲染的文本过滤项目。

但是,您也可以提供自己的自定义过滤逻辑,并同时设置 ignoreFilter="true"

vue
<script setup lang="ts">
import { ComboboxContent, ComboboxInput, ComboboxItem, ComboboxPortal, ComboboxRoot, useFilter } from 'reka-ui'
import { ref } from '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 { startsWith } = useFilter({ sensitivity: 'base' })
const filteredPeople = computed(() => people.filter(p => startsWith(p.name, searchTerm.value)))
</script>

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

自定义标签

默认情况下,Combobox 将使用输入内容作为屏幕阅读器的标签。如果您想更精细地控制辅助技术宣布的内容,请使用 Label 组件。

vue
<script setup lang="ts">
import { ComboboxInput, ComboboxRoot, Label } from 'reka-ui'
import { ref } from '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 {
  ComboboxContent,
  ComboboxInput,
  ComboboxItem,
  ComboboxPortal,
  ComboboxRoot,
} from 'reka-ui'
import { ref } from '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 {
  ComboboxContent,
  ComboboxInput,
  ComboboxItem,
  ComboboxPortal,
  ComboboxRoot,
  ComboboxSeparator
} from 'reka-ui'
import { ref } from '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 {
  ComboboxContent,
  ComboboxGroup,
  ComboboxInput,
  ComboboxItem,
  ComboboxLabel,
  ComboboxPortal,
  ComboboxRoot
} from 'reka-ui'
import { ref } from '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 {
  ComboboxContent,
  ComboboxGroup,
  ComboboxInput,
  ComboboxItem,
  ComboboxItemIndicator,
  ComboboxLabel,
  ComboboxPortal,
  ComboboxRoot
} from 'reka-ui'
import { ref } from '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 { ComboboxContent, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxItemIndicator, ComboboxLabel, ComboboxPortal, ComboboxRoot } from 'reka-ui'
import { ref } from 'vue'
</script>

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

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

带有工作过滤功能的虚拟化组合框

组合框项目在传递给虚拟化器之前**必须**手动过滤。

有关虚拟化的更多通用信息,请参阅虚拟化指南

vue
<script setup lang="ts">
import { ComboboxContent, ComboboxInput, ComboboxItem, ComboboxPortal, ComboboxRoot, ComboboxViewport, ComboboxVirtualizer, useFilter } from 'reka-ui'
import { computed, ref } from 'vue'

const people = Array.from({ length: 100000 }).map((_, id) => ({ id, name: `Person #${id}` }))
const selectedPeople = ref(people[0])
const searchTerm = ref('')

const { contains } = useFilter({ sensitivity: 'base' })
const filteredPeople = computed(() => people.filter(p => contains(p.name, searchTerm.value)))
</script>

<template>
  <ComboboxRoot v-model="selectedPeople">
    <ComboboxInput v-model="searchTerm" />
    <ComboboxPortal>
      <ComboboxContent class="max-h-[40vh] overflow-hidden">
        <ComboboxViewport>
          <ComboboxVirtualizer
            v-slot="{ option }"
            :options="filteredPeople"
            :text-content="(x) => x.name"
            :estimate-size="24"
          >
            <ComboboxItem :value="option">
              {{ option.name }}
            </ComboboxItem>
          </ComboboxVirtualizer>
        </ComboboxViewport>
      </ComboboxContent>
    </ComboboxPortal>
  </ComboboxRoot>
</template>

可访问性

遵循 组合框 WAI-ARIA 设计模式

有关更多信息,请参阅 W3C 组合框自动完成列表示例。

键盘交互

描述
回车键
当焦点在 ComboboxItem 上时,选择聚焦的项目。
向下箭头键
当焦点在 ComboboxInput 上时,打开组合框内容。
当焦点在项目上时,将焦点移到下一个项目。
向上箭头键
当焦点在 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 type { ComboboxRootEmits, ComboboxRootProps } from 'reka-ui'
import { CheckIcon, ChevronDownIcon, ChevronUpIcon, } from '@radix-icons/vue'
import { ComboboxContent, ComboboxInput, ComboboxPortal, ComboboxRoot, useForwardPropsEmits } from 'reka-ui'

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
        @escape-key-down.prevent
        @focus-outside.prevent
        @interact-outside.prevent
        @pointer-down-outside.prevent
      >
        <ComboboxViewport>
          <slot />
        </ComboboxViewport>
      </ComboboxContent>
    </ComboboxPortal>
  </ComboboxRoot>
</template>
vue
<!-- ComboboxItem.vue -->
<script setup lang="ts">
import type { ComboboxItemProps } from 'reka-ui'
import { CheckIcon } from '@radix-icons/vue'
import { ComboboxItem } from 'reka-ui'

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

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