Reka UI 标志Reka
backdrop
组件

选择

显示供用户选择的选项列表——由按钮触发。

特性

  • 可受控或非受控。
  • 提供两种定位模式。
  • 支持项、标签、项组。
  • 焦点完全受控。
  • 完整的键盘导航。
  • 支持自定义占位符。
  • 预输入支持。
  • 支持从右到左方向。

安装

从命令行安装此组件。

sh
$ npm add reka-ui

结构

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

vue
<script setup lang="ts">
import {
  SelectContent,
  SelectGroup,
  SelectIcon,
  SelectItem,
  SelectItemIndicator,
  SelectLabel,
  SelectPortal,
  SelectRoot,
  SelectScrollDownButton,
  SelectScrollUpButton,
  SelectSeparator,
  SelectTrigger,
  SelectValue,
  SelectViewport,
} from 'reka-ui'
</script>

<template>
  <SelectRoot>
    <SelectTrigger>
      <SelectValue />
      <SelectIcon />
    </SelectTrigger>

    <SelectPortal>
      <SelectContent>
        <SelectScrollUpButton />
        <SelectViewport>
          <SelectItem>
            <SelectItemText />
            <SelectItemIndicator />
          </SelectItem>
          <SelectGroup>
            <SelectLabel />
            <SelectItem>
              <SelectItemText />
              <SelectItemIndicator />
            </SelectItem>
          </SelectGroup>
          <SelectSeparator />
        </SelectViewport>
        <SelectScrollDownButton />
        <SelectArrow />
      </SelectContent>
    </SelectPortal>
  </SelectRoot>
</template>

API 参考

包含 Select 的所有部分

属性默认类型
autocomplete
string

原生 HTML input 的 `autocomplete` 属性。

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

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

defaultOpen
布尔值

Select 组件首次渲染时的打开状态。当您不需要控制其打开状态时使用。

defaultValue
AcceptableValue | AcceptableValue[]

Select 组件首次渲染时的值。当您不需要控制 Select 状态时使用。

dir
'ltr' | 'rtl'

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

disabled
布尔值

当为 `true` 时,阻止用户与 Select 交互。

modelValue
AcceptableValue | AcceptableValue[]

Select 的受控值。可绑定为 `v-model`。

multiple
布尔值

是否可以选择多个选项。

name
string

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

open
布尔值

Select 的受控打开状态。可绑定为 `v-model:open`。

required
布尔值

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

事件触发载荷
update:modelValue
[value: AcceptableValue]

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

update:open
[value: boolean]

当上下文菜单的打开状态改变时调用的事件处理程序。

插槽(默认)载荷
modelValue
AcceptableValue | AcceptableValue[] | undefined

当前输入值

open
布尔值

当前打开状态

触发器

切换 Select 的按钮。`SelectContent` 将通过与触发器对齐来定位自身。

属性默认类型
as
'button'
AsTag | Component

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

asChild
布尔值

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

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

disabled
布尔值
reference
ReferenceElement

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

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

数据属性
[data-state]"打开" | "关闭"
[data-disabled]禁用时存在
[data-placeholder]存在占位符时显示

反映选中值的部分。默认情况下,将渲染选中项的文本。如果您需要更多控制,可以改为控制 Select 并传入您自己的 `children`。它不应被样式化以确保正确的定位。当 Select 没有值时,还提供了一个可选的 `placeholder` 属性。

属性默认类型
as
'span'
AsTag | Component

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

asChild
布尔值

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

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

placeholder
''
string

当未设置 `value` 或 `defaultValue` 时,将在 `SelectValue` 内部渲染的内容。

插槽(默认)载荷
selectedLabel
string[]
modelValue
AcceptableValue | AcceptableValue[] | undefined

图标

一个小图标,通常显示在值旁边,作为可打开的视觉提示。默认渲染 ▼,但您可以通过 `asChild` 或使用 `children` 来使用您自己的图标。

属性默认类型
as
'div'
AsTag | Component

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

asChild
布尔值

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

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

disabled
布尔值

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

textValue
string

用于预输入目的的可选文本。

默认情况下,预输入行为将使用 `SelectItemText` 部分的 `.textContent`。

当内容复杂或包含非文本内容时使用此项。

值*
AcceptableValue

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

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

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

传送门

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

属性默认类型
defer
布尔值

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

reference

disabled
布尔值

禁用传送并内联渲染组件

reference

forceMount
布尔值

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

to
字符串 | HTMLElement

Vue 原生传送组件属性 :to

reference

内容

当 Select 打开时弹出的组件。

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

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

alignOffset
数字

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

arrowPadding
数字

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

as
'div'
AsTag | Component

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

asChild
布尔值

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

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

avoidCollisions
布尔值

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

bodyLock
布尔值

文档主体将被锁定,滚动将被禁用。

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

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

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

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

disableUpdateOnLayoutShift
布尔值

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

forceMount
布尔值

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

hideWhenDetached
布尔值

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

position
'popper' | 'item-aligned'

要使用的定位模式

`item-aligned (默认)` - 通过将内容相对于活动项定位,其行为类似于原生 macOS 菜单。
`popper` - 以与我们的其他基本组件(例如 `Popover` 或 `DropdownMenu`)相同的方式定位内容。

positionStrategy
'fixed' | 'absolute'

要使用的 CSS position 属性类型。

prioritizePosition
布尔值

强制内容在视口内定位。

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

reference
ReferenceElement

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

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

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

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

sideOffset
数字

与触发器的像素距离。

sticky
'部分' | '始终'

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

updatePositionStrategy
'始终' | '优化'

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

事件触发载荷
closeAutoFocus
[事件: Event]

关闭时自动聚焦调用的事件处理程序。可阻止其默认行为。

escapeKeyDown
[事件: KeyboardEvent]

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

pointerDownOutside
[事件: PointerDownOutsideEvent]

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

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

视口

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

属性默认类型
as
'div'
AsTag | Component

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

asChild
布尔值

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

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

nonce
string

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

包含选择项的组件。

属性默认类型
as
'div'
AsTag | Component

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

asChild
布尔值

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

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

disabled
布尔值

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

textValue
string

用于预输入目的的可选文本。

默认情况下,预输入行为将使用 `SelectItemText` 部分的 `.textContent`。

当内容复杂或包含非文本内容时使用此项。

值*
AcceptableValue

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

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

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

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

项文本

项的文本部分。它应只包含您希望在该项被选中时在触发器中看到的文本。不应为其设置样式以确保正确的定位。

属性默认类型
as
'span'
AsTag | Component

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

asChild
布尔值

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

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

项指示器

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

属性默认类型
as
'span'
AsTag | Component

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

asChild
布尔值

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

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

向上滚动按钮

一个可选按钮,用作显示视口溢出的提示,并可在功能上启用向上滚动。

属性默认类型
as
'div'
AsTag | Component

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

asChild
布尔值

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

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

向下滚动按钮

一个可选按钮,用作显示视口溢出的提示,并可在功能上启用向下滚动。

属性默认类型
as
'div'
AsTag | Component

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

asChild
布尔值

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

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

分组

用于将多个项分组。与 `SelectLabel` 结合使用,通过自动标记确保良好的可访问性。

属性默认类型
as
'div'
AsTag | Component

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

asChild
布尔值

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

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

标签

用于渲染组的标签。它无法通过箭头键聚焦。

属性默认类型
as
'div'
AsTag | Component

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

asChild
布尔值

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

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

for
string

分隔符

用于在 Select 中视觉上分隔各项。

属性默认类型
as
'div'
AsTag | Component

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

asChild
布尔值

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

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

箭头

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

属性默认类型
as
'svg'
AsTag | Component

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

asChild
布尔值

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

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

高度
5
数字

箭头的像素高度。

rounded
布尔值

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

宽度
10
数字

箭头的像素宽度。

示例

改变定位模式

默认情况下,`Select` 的行为类似于原生 macOS 菜单,它将 `SelectContent` 相对于活动项进行定位。如果您更喜欢类似于 `Popover` 或 `DropdownMenu` 的替代定位方法,则可以将 `position` 设置为 `popper` 并使用额外的对齐选项,例如 `side`、`sideOffset` 等。

vue
// index.vue
<script setup lang="ts">
import {
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectItemIndicator,
  SelectLabel,
  SelectPortal,
  SelectRoot,
  SelectSeparator,
  SelectTrigger,
} from 'reka-ui'
</script>

<template>
  <SelectRoot>
    <SelectTrigger>…</SelectTrigger>
    <SelectPortal>
      <SelectContent
        position="popper"
        :side-offset="5"
      >

      </SelectContent>
    </SelectPortal>
  </SelectRoot>
</template>

约束内容大小

在 `SelectContent` 上使用 `position="popper"` 时,您可能希望约束内容的宽度以使其与触发器宽度匹配。您还可能希望约束其高度,使其不超过视口。

我们公开了几个 CSS 自定义属性,例如 `--reka-select-trigger-width` 和 `--reka-select-content-available-height` 来支持此功能。使用它们来约束内容的尺寸。

vue
// index.vue
<script setup lang="ts">
import {
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectItemIndicator,
  SelectLabel,
  SelectPortal,
  SelectRoot,
  SelectSeparator,
  SelectTrigger,
} from 'reka-ui'
</script>

<template>
  <SelectRoot>
    <SelectTrigger>…</SelectTrigger>
    <SelectPortal>
      <SelectContent
        class="SelectContent"
        position="popper"
        :side-offset="5"
      >

      </SelectContent>
    </SelectPortal>
  </SelectRoot>
</template>
css
/* styles.css */
.SelectContent {
  width: var(--reka-select-trigger-width);
  max-height: var(--reka-select-content-available-height);
}

带有禁用项

您可以通过 data-disabled 属性为禁用项目添加特殊样式。

vue
// index.vue
<script setup lang="ts">
import {
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectItemIndicator,
  SelectLabel,
  SelectPortal,
  SelectRoot,
  SelectSeparator,
  SelectTrigger,
} from 'reka-ui'
</script>

<template>
  <SelectRoot>
    <SelectTrigger>…</SelectTrigger>
    <SelectPortal>
      <SelectContent>
        <SelectViewport>
          <SelectItem
            class="SelectItem"
            disabled
          >

          </SelectItem>
          <SelectItem>…</SelectItem>
          <SelectItem>…</SelectItem>
        </SelectViewport>
      </SelectContent>
    </SelectPortal>
  </SelectRoot>
</template>
css
/* styles.css */
.SelectItem[data-disabled] {
  color: "gainsboro";
}

带有占位符

当 Select 没有值时,您可以在 `Value` 上使用 `placeholder` 属性。`Trigger` 上还有一个 `data-placeholder` 属性,用于帮助样式设计。

vue
// index.vue
<script setup lang="ts">
import {
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectItemIndicator,
  SelectLabel,
  SelectPortal,
  SelectRoot,
  SelectSeparator,
  SelectTrigger,
} from 'reka-ui'
import './styles.css'
</script>

<template>
  <SelectRoot>
    <SelectTrigger class="SelectTrigger">
      <SelectValue placeholder="Pick an option" />
      <SelectIcon />
    </SelectTrigger>
    <SelectPortal>
      <SelectContent>…</SelectContent>
    </SelectPortal>
  </SelectRoot>
</template>
css
/* styles.css */
.SelectTrigger[data-placeholder] {
  color: "gainsboro";
}

带有分隔符

使用 Separator 部分在项目之间添加分隔符。

带有分组项

使用 `Group` 和 `Label` 部分将项分组。

带有复杂项

您可以在您的项中使用自定义内容。

vue
<script setup lang="ts">
import {
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectItemIndicator,
  SelectLabel,
  SelectPortal,
  SelectRoot,
  SelectSeparator,
  SelectTrigger,
} from 'reka-ui'
</script>

<template>
  <SelectRoot>
    <SelectTrigger>…</SelectTrigger>
    <SelectPortal>
      <SelectContent>
        <SelectViewport>
          <SelectItem>
            <SelectItemText>
              <img src="…">
              Adolfo Hess
            </SelectItemText>
            <SelectItemIndicator>…</SelectItemIndicator>
          </SelectItem>
          <SelectItem>…</SelectItem> <SelectItem>…</SelectItem>
        </SelectViewport>
      </SelectContent>
    </SelectPortal>
  </SelectRoot>
</template>

控制触发器中显示的值

默认情况下,触发器显示选中项的文本(不再像 v1 中那样自动渲染 `ItemText` 的内容)。

如果您需要渲染非纯文本内容,可以通过 `v-model` 属性(或访问 `SelectValue` 的 slotProps)来控制组件,并向 `SelectValue` 传递 `slot`。请记住确保您放入的内容是可访问的。

vue
<script setup>
const countries = { 'france': '🇫🇷', 'united-kingdom': '🇬🇧', 'spain': '🇪🇸' }

const value = ref('france')
</script>

<template>
  <SelectRoot v-model="value">
    <SelectTrigger>
      <SelectValue :aria-label="value">
        {{ countries[value] }}
      </SelectValue>
      <SelectIcon />
    </SelectTrigger>
    <SelectPortal>
      <SelectContent>
        <SelectViewport>
          <SelectItem value="france">
            <SelectItemText>France</SelectItemText>
            <SelectItemIndicator>…</SelectItemIndicator>
          </SelectItem>
          <SelectItem value="united-kingdom">
            <SelectItemText>United Kingdom</SelectItemText>
            <SelectItemIndicator>…</SelectItemIndicator>
          </SelectItem>
          <SelectItem value="spain">
            <SelectItemText>Spain</SelectItemText>
            <SelectItemIndicator>…</SelectItemIndicator>
          </SelectItem>
        </SelectViewport>
      </SelectContent>
    </SelectPortal>
  </SelectRoot>
</template>

带有自定义滚动条

默认情况下,原生滚动条是隐藏的,因为我们建议使用 `ScrollUpButton` 和 `ScrollDownButton` 部分以获得最佳用户体验。如果您不想使用这些部分,可以使用我们的 滚动区域 原语来组合您的 Select 组件。

vue
// index.vue
<script setup lang="ts">
import {
  ScrollAreaRoot,
  ScrollAreaScrollbar,
  ScrollAreaThumb,
  ScrollAreaViewport,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectItemIndicator,
  SelectLabel,
  SelectPortal,
  SelectRoot,
  SelectSeparator,
  SelectTrigger,
} from 'reka-ui'
</script>

<template>
  <SelectRoot>
    <SelectTrigger>…</SelectTrigger>
    <SelectPortal>
      <SelectContent>
        <ScrollAreaRoot
          class="ScrollAreaRoot"
          type="auto"
        >
          <SelectViewport as-child>
            <ScrollAreaViewport class="ScrollAreaViewport">
              <StyledItem>…</StyledItem> <StyledItem>…</StyledItem>
              <StyledItem>…</StyledItem>
            </ScrollAreaViewport>
          </SelectViewport>
          <ScrollAreaScrollbar
            class="ScrollAreaScrollbar"
            orientation="vertical"
          >
            <ScrollAreaThumb class="ScrollAreaThumb" />
          </ScrollAreaScrollbar>
        </ScrollAreaRoot>
      </SelectContent>
    </SelectPortal>
  </SelectRoot>
</template>
css
/* styles.css */
.ScrollAreaRoot {
  width: 100%;
  height: 100%;
}

.ScrollAreaViewport {
  width: 100%;
  height: 100%;
}

.ScrollAreaScrollbar {
  width: 4px;
  padding: 5px 2px;
}

.ScrollAreaThumb {
  background: rgba(0, 0, 0, 0.3);
  borderradius: 3px;
}

可访问性

遵循 ListBox WAI-ARIA 设计模式

有关更多信息,请参阅 W3C 仅选择组合框 示例。

键盘交互

描述
空格键
当焦点在 `SelectTrigger` 上时,打开 Select 并聚焦于选中项。
当焦点在某个项上时,选择该聚焦项。
回车键
当焦点在 `SelectTrigger` 上时,打开 Select 并聚焦于第一个项。
当焦点在某个项上时,选择该聚焦项。
向下箭头键
当焦点在 `SelectTrigger` 上时,打开 Select。
当焦点在项目上时,将焦点移到下一个项目。
向上箭头键
当焦点在 `SelectTrigger` 上时,打开 Select。
当焦点在项目上时,将焦点移到上一个项目。
Esc键
关闭 Select 并将焦点移至 `SelectTrigger`。

标记

使用我们的 Label 组件为 Select 提供可视化和可访问的标签。

vue
<script setup lang="ts">
import { Icon } from '@iconify/vue'
import {
  Label,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectItemIndicator,
  SelectLabel,
  SelectPortal,
  SelectRoot,
  SelectSeparator,
  SelectTrigger,
} from 'reka-ui'
import { ref } from 'vue'
</script>

<template>
  <Label>
    Country
    <SelectRoot>…</SelectRoot>
  </Label>

  <!-- or -->

  <Label for="country">Country</Label>
  <SelectRoot>
    <SelectTrigger id="country">

    </SelectTrigger>
    <SelectPortal>
      <SelectContent>…</SelectContent>
    </SelectPortal>
  </SelectRoot>
</template>

自定义 API

通过将原始部件抽象到您自己的组件中来创建您自己的 API。

抽象为 `Select` 和 `SelectItem`

此示例抽象了大部分组件。

用法

vue
<script setup lang="ts">
import { Select, SelectItem } from './your-select'
</script>

<template>
  <Select default-value="2">
    <SelectItem value="1">
      Item 1
    </SelectItem>
    <SelectItem value="2">
      Item 2
    </SelectItem>
    <SelectItem value="3">
      Item 3
    </SelectItem>
  </Select>
</template>

实现

ts
// your-select.ts
export { default as Select } from 'Select.vue'
export { default as SelectItem } from 'SelectItem.vue'
vue
<!-- Select.vue -->
<script setup lang="ts">
import type { SelectRootEmits, SelectRootProps } from 'reka-ui'
import { CheckIcon, ChevronDownIcon, ChevronUpIcon, } from '@radix-icons/vue'
import { SelectContent, SelectIcon, SelectPortal, SelectRoot, SelectScrollDownButton, SelectScrollUpButton, SelectTrigger, SelectValue, SelectViewport, useForwardPropsEmits } from 'reka-ui'

const props = defineProps<SelectRootProps>()
const emits = defineEmits<SelectRootEmits>()

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

<template>
  <SelectRoot v-bind="forward">
    <SelectTrigger>
      <SelectValue />
      <SelectIcon>
        <ChevronDownIcon />
      </SelectIcon>
    </SelectTrigger>

    <SelectPortal>
      <SelectContent>
        <SelectScrollUpButton>
          <ChevronUpIcon />
        </SelectScrollUpButton>
        <SelectViewport>
          <slot />
        </SelectViewport>
        <SelectScrollDownButton>
          <ChevronDownIcon />
        </SelectScrollDownButton>
      </SelectContent>
    </SelectPortal>
  </SelectRoot>
</template>
vue
<!-- SelectItem.vue -->
<script setup lang="ts">
import type { SelectItemProps } from 'reka-ui'
import { CheckIcon } from '@radix-icons/vue'
import { SelectItem, SelectItemIndicator, SelectItemText } from 'reka-ui'

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

<template>
  <SelectItem v-bind="props">
    <SelectItemText>
      <slot />
    </SelectItemText>
    <SelectItemIndicator>
      <CheckIcon />
    </SelectItemIndicator>
  </SelectItem>
</template>