组合框
特性
- 可受控或不受控。
- 提供 2 种定位模式。
- 支持项目、标签、项目组。
- 焦点管理完善。
- 完整的键盘导航。
- 支持自定义占位符。
- 支持从右到左方向。
安装
从命令行安装此组件。
$ npm add reka-ui
结构
导入所有部分并将其组合。
<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 | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
by | string | ((a: AcceptableValue, b: AcceptableValue) => boolean) 使用此属性按特定字段比较对象,或传入您自己的比较函数以完全控制对象的比较方式。 | |
defaultOpen | 布尔值 组合框初始渲染时的打开状态。 | |
defaultValue | AcceptableValue | AcceptableValue[] 列表框初始渲染时的值。当您不需要控制列表框状态时使用 | |
dir | 'ltr' | 'rtl' 适用时列表框的阅读方向。 | |
disabled | 布尔值 当为 | |
highlightOnHover | 布尔值 当为 | |
ignoreFilter | 布尔值 当为 | |
modelValue | AcceptableValue | AcceptableValue[] 列表框的受控值。可与 | |
multiple | 布尔值 是否可以选择多个选项。 | |
name | string 字段的名称。随其所属的表单一起作为名称/值对提交。 | |
open | 布尔值 组合框的受控打开状态。可与 | |
required | 布尔值 当为 | |
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 | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
reference | ReferenceElement 用于定位的参考(或锚点)元素。 如果未提供,将使用当前组件作为锚点。 |
输入
用于搜索组合框项目的输入组件。
属性 | 默认 | 类型 |
---|---|---|
as | 'input' | AsTag | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
autoFocus | 布尔值 挂载时聚焦到元素。 | |
disabled | 布尔值 当为 | |
displayValue | ((val: any) => string) 所选项目的输入显示值。不适用于 | |
modelValue | string 过滤器的受控值。可与 v-model 绑定。 |
事件触发 | 载荷 |
---|---|
update:modelValue | [string] 值改变时调用的事件处理程序。 |
触发器
切换组合框内容的按钮。
属性 | 默认 | 类型 |
---|---|---|
as | 'button' | AsTag | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
disabled | 布尔值 当为 |
数据属性 | 值 |
---|---|
[data-state] | "打开" | "关闭" |
[data-disabled] | 禁用时存在 |
取消
清除搜索词的按钮。
属性 | 默认 | 类型 |
---|---|---|
as | 'button' | AsTag | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 |
空
当没有项目匹配查询时显示。
属性 | 默认 | 类型 |
---|---|---|
as | 'div' | AsTag | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 |
传送门
使用时,将内容部分传送到 body
中。
您需要为 ComboboxContent
设置 position="popper"
,以确保位置像 Popover
或 DropdownMenu
一样自动计算。
属性 | 默认 | 类型 |
---|---|---|
defer | 布尔值 延迟解析 Teleport 目标,直到应用程序的其他部分挂载(需要 Vue 3.5.0+) | |
disabled | 布尔值 禁用传送并内联渲染组件 | |
forceMount | 布尔值 当需要更多控制时,用于强制挂载。在与 Vue 动画库控制动画时很有用。 | |
to | 字符串 | HTMLElement Vue 原生传送组件属性 |
内容
组合框打开时弹出的组件。
属性 | 默认 | 类型 |
---|---|---|
align | 'start' | 'center' | 'end' 相对于触发器的首选对齐方式。当发生碰撞时可能会改变。 | |
alignOffset | 数字 与 | |
arrowPadding | 数字 箭头与内容边缘之间的内边距。如果您的内容有 border-radius,这将防止它溢出角落。 | |
as | 'div' | AsTag | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
avoidCollisions | 布尔值 当为 | |
bodyLock | 布尔值 document.body 将被锁定,滚动将被禁用。 | |
collisionBoundary | Element | (Element | null)[] | null 用作碰撞边界的元素。默认情况下是视口,但您可以提供其他元素以包含在此检查中。 | |
collisionPadding | 数字 | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>> 碰撞检测应发生的距边界边缘的像素距离。接受一个数字(所有边相同),或一个部分填充对象,例如:{ top: 20, left: 20 }。 | |
disableOutsidePointerEvents | 布尔值 当为 | |
disableUpdateOnLayoutShift | 布尔值 当布局发生偏移时,是否禁用更新内容位置。 | |
forceMount | 布尔值 当需要更多控制时,用于强制挂载。在与 Vue 动画库控制动画时很有用。 | |
hideWhenDetached | 布尔值 当触发器完全被遮挡时,是否隐藏内容。 | |
position | 'inline' | 'popper' 要使用的定位模式, | |
positionStrategy | 'fixed' | 'absolute' 要使用的 CSS position 属性类型。 | |
prioritizePosition | 布尔值 强制内容在视口内定位。 可能与参考元素重叠,这可能不是期望的结果。 | |
reference | ReferenceElement 将设置为浮动元素定位参考的自定义元素或虚拟元素。 如果提供,它将替换默认的锚点元素。 | |
side | 'top' | 'right' | 'bottom' | 'left' 打开时,相对于触发器渲染的首选侧边。当发生碰撞且启用 avoidCollisions 时,将反转。 | |
sideOffset | 数字 与触发器的像素距离。 | |
sticky | '部分' | '始终' 对齐轴上的粘性行为。 | |
updatePositionStrategy | '始终' | '优化' 在每个动画帧更新浮动元素位置的策略。 |
事件触发 | 载荷 |
---|---|
escapeKeyDown | [事件: KeyboardEvent] 按下 Esc 键时调用的事件处理程序。可阻止其默认行为。 |
focusOutside | [事件: FocusOutsideEvent] 当焦点移出 |
interactOutside | [事件: PointerDownOutsideEvent | FocusOutsideEvent] 当 |
pointerDownOutside | [事件: PointerDownOutsideEvent] 当 |
数据属性 | 值 |
---|---|
[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 | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
nonce | string 将向样式标签添加 |
项目
包含组合框项目的组件。
属性 | 默认 | 类型 |
---|---|---|
as | 'div' | AsTag | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
disabled | 布尔值 当为 | |
textValue | string 项目内容的字符串表示形式。 如果子元素不是纯文本,则 | |
值* | AcceptableValue 与 `name` 一起提交时作为数据给出的值。 |
事件触发 | 载荷 |
---|---|
select | [event: SelectEvent<AcceptableValue>] 选择项目时调用的事件处理程序。 |
数据属性 | 值 |
---|---|
[data-state] | "选中" | "未选中" |
[data-highlighted] | 高亮时存在 |
[data-disabled] | 禁用时存在 |
项目指示器
当项目被选中时渲染。您可以直接样式化此元素,也可以将其用作放置图标的包装器,或者两者兼可。
属性 | 默认 | 类型 |
---|---|---|
as | 'span' | AsTag | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 |
分组
用于对多个项目进行分组。与 ComboboxLabel
结合使用可确保通过自动标签实现良好的可访问性。
属性 | 默认 | 类型 |
---|---|---|
as | 'div' | AsTag | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 |
标签
用于渲染组的标签。它不能通过方向键获得焦点。
属性 | 默认 | 类型 |
---|---|---|
as | 'div' | AsTag | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
for | string |
分隔符
用于在组合框中视觉上分隔项目
属性 | 默认 | 类型 |
---|---|---|
as | 'div' | AsTag | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 |
箭头
一个可选的箭头元素,与内容一起渲染。这可用于帮助将触发器与 ComboboxContent
视觉链接起来。必须在 ComboboxContent
内部渲染。仅当 position
设置为 popper
时可用。
属性 | 默认 | 类型 |
---|---|---|
as | 'svg' | AsTag | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
高度 | 5 | 数字 箭头的像素高度。 |
rounded | 布尔值 当为 | |
宽度 | 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
属性,以便在项目选择时设置输入值。
<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
组件允许您选择多个值。您可以通过提供值数组而不是单个值来启用此功能。
<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"
。
<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 组件。
<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
属性为禁用项目添加特殊样式。
<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>
/* styles.css */
.ComboboxItem[data-disabled] {
color: "gainsboro";
}
带有分隔符
使用 Separator
部分在项目之间添加分隔符。
<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>
带有分组项目
使用 Group
和 Label
部分将项目分组在一个部分中。
<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>
带有复杂项目
您可以在项目中自定义内容。
<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
来阻止此行为。
<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>
带有工作过滤功能的虚拟化组合框
组合框项目在传递给虚拟化器之前**必须**手动过滤。
有关虚拟化的更多通用信息,请参阅虚拟化指南。
<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>
可访问性
有关更多信息,请参阅 W3C 组合框自动完成列表示例。
键盘交互
键 | 描述 |
---|---|
回车键 | 当焦点在 ComboboxItem 上时,选择聚焦的项目。 |
向下箭头键 | 当焦点在 ComboboxInput 上时,打开组合框内容。当焦点在项目上时,将焦点移到下一个项目。 |
向上箭头键 | 当焦点在 ComboboxInput 上时,打开组合框内容。当焦点在项目上时,将焦点移到上一个项目。 |
Esc键 | 关闭组合框并恢复 ComboboxInput 字段中选定的项目。 |
自定义 API
通过将原始部件抽象到您自己的组件中来创建您自己的 API。
命令菜单
组合框可用于构建您自己的命令菜单。
用法
<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>
实现
// your-command.ts
export { default as Command } from 'Command.vue'
export { default as CommandItem } from 'CommandItem.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>
<!-- 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>