菜单栏
特性
- 可受控或不受控。
- 支持可配置阅读方向的子菜单。
- 支持项目、标签和项目组。
- 支持可勾选项目(单选或多选)。
- 自定义侧边、对齐、偏移、碰撞处理。
- 可选渲染一个指向箭头。
- 焦点完全受控。
- 完整的键盘导航。
- 支持预输入搜索。
安装
从命令行安装此组件。
$ npm add reka-ui
解构
导入所有部分并将其组合。
<script setup lang="ts">
import {
MenubarArrow,
MenubarCheckboxItem,
MenubarContent,
MenubarItem,
MenubarItemIndicator,
MenubarLabel,
MenubarMenu,
MenubarPortal,
MenubarRadioGroup,
MenubarRadioItem,
MenubarRoot,
MenubarSeparator,
MenubarSub,
MenubarSubContent,
MenubarSubTrigger,
MenubarTrigger,
} from './'
</script>
<template>
<MenubarRoot>
<MenubarMenu>
<MenubarTrigger />
<MenubarPortal>
<MenubarContent>
<MenubarLabel />
<MenubarItem />
<MenubarGroup>
<MenubarItem />
</MenubarGroup>
<MenubarCheckboxItem>
<MenubarItemIndicator />
</MenubarCheckboxItem>
<MenubarRadioGroup>
<MenubarRadioItem>
<MenubarItemIndicator />
</MenubarRadioItem>
</MenubarRadioGroup>
<MenubarSub>
<MenubarSubTrigger />
<MenubarPortal>
<MenubarSubContent />
</MenubarPortal>
</MenubarSub>
<MenubarSeparator />
<MenubarArrow />
</MenubarContent>
</MenubarPortal>
</MenubarMenu>
</MenubarRoot>
</template>
API 参考
根组件
包含菜单栏的所有部分
属性 | 默认 | 类型 |
---|---|---|
defaultValue | 字符串 菜单在初次渲染时应打开的值。当您不需要控制值状态时使用。 | |
dir | '从左到右' | '从右到左' 适用时,组合框的阅读方向。 如果省略,则全局继承自 | |
loop | false | 布尔值 当为 |
modelValue | 字符串 要打开的菜单的受控值。可用作 |
事件触发 | 载荷 |
---|---|
update:modelValue | [值: 布尔值] 值改变时调用的事件处理程序。 |
插槽(默认) | 载荷 |
---|---|
modelValue | 字符串 当前输入值 |
菜单
一个顶级菜单项,包含一个触发器和内容组合。
属性 | 默认 | 类型 |
---|---|---|
value | 字符串 当导航菜单受控时,将项目与活动值关联的唯一值。 当不受控时,此 prop 会自动管理。 |
触发器
用于切换内容的按钮。默认情况下,MenubarContent
会根据触发器定位。
属性 | 默认 | 类型 |
---|---|---|
as | '按钮' | 作为标签 | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
disabled | 布尔值 当为 |
数据属性 | 值 |
---|---|
[data-state] | "打开" | "关闭" |
[data-highlighted] | 高亮时存在 |
[data-disabled] | 禁用时存在 |
传送门
使用时,将内容部分传送到 body
中。
属性 | 默认 | 类型 |
---|---|---|
defer | 布尔值 延迟解析 Teleport 目标,直到应用程序的其他部分挂载(需要 Vue 3.5.0+) | |
disabled | 布尔值 禁用传送并内联渲染组件 | |
forceMount | 布尔值 当需要更多控制时,用于强制挂载。在与 Vue 动画库控制动画时很有用。 | |
to | 字符串 | HTMLElement Vue 原生传送组件属性 |
内容
菜单打开时弹出的组件。
属性 | 默认 | 类型 |
---|---|---|
align | '开始' | '开始' | '居中' | '结束' 相对于触发器的首选对齐方式。当发生碰撞时可能会改变。 |
alignOffset | 数字 与 | |
arrowPadding | 数字 箭头与内容边缘之间的内边距。如果您的内容有 border-radius,这将防止它溢出角落。 | |
as | 'div' | 作为标签 | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
avoidCollisions | 布尔值 当为 | |
collisionBoundary | 元素 | (元素 | null)[] | null 用作碰撞边界的元素。默认情况下是视口,但您可以提供其他元素以包含在此检查中。 | |
collisionPadding | 数字 | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>> 碰撞检测应发生的距边界边缘的像素距离。接受一个数字(所有边相同),或一个部分填充对象,例如:{ top: 20, left: 20 }。 | |
disableUpdateOnLayoutShift | 布尔值 当布局发生偏移时,是否禁用更新内容位置。 | |
forceMount | 布尔值 当需要更多控制时,用于强制挂载。在与 Vue 动画库控制动画时很有用。 | |
hideWhenDetached | 布尔值 当触发器完全被遮挡时,是否隐藏内容。 | |
loop | 布尔值 当为 | |
positionStrategy | '固定' | '绝对' 要使用的 CSS position 属性类型。 | |
prioritizePosition | 布尔值 强制内容在视口内定位。 可能与参考元素重叠,这可能不是期望的结果。 | |
reference | ReferenceElement 将设置为浮动元素定位参考的自定义元素或虚拟元素。 如果提供,它将替换默认的锚点元素。 | |
side | '上' | '右' | '下' | '左' 打开时,相对于触发器渲染的首选侧边。当发生碰撞且启用 avoidCollisions 时,将反转。 | |
sideOffset | 数字 与触发器的像素距离。 | |
sticky | '部分' | '始终' 对齐轴上的粘性行为。 | |
updatePositionStrategy | '始终' | '优化' 在每个动画帧更新浮动元素位置的策略。 |
事件触发 | 载荷 |
---|---|
closeAutoFocus | [事件: Event] 关闭时自动聚焦调用的事件处理程序。可阻止其默认行为。 |
escapeKeyDown | [事件: KeyboardEvent] 按下 Esc 键时调用的事件处理程序。可阻止其默认行为。 |
focusOutside | [事件: FocusOutsideEvent] 当焦点移出 |
interactOutside | [事件: PointerDownOutsideEvent | FocusOutsideEvent] 当 |
pointerDownOutside | [事件: PointerDownOutsideEvent] 当 |
数据属性 | 值 |
---|---|
[data-state] | "打开" | "关闭" |
[data-side] | "左" | "右" | "下" | "上" |
[data-align] | "开始" | "结束" | "居中" |
CSS 变量 | 描述 |
---|---|
--reka-menubar-content-transform-origin | 从内容和箭头位置/偏移量计算的 transform-origin |
--reka-menubar-content-available-width | 触发器与边界边缘之间的剩余宽度 |
--reka-menubar-content-available-height | 触发器与边界边缘之间的剩余高度 |
--reka-menubar-trigger-width | 触发器的宽度 |
--reka-menubar-trigger-height | 触发器的高度 |
箭头
一个可选的箭头元素,用于与菜单栏菜单一起渲染。这可以帮助在视觉上将触发器与 MenubarContent
连接起来。必须在 MenubarContent
内部渲染。
属性 | 默认 | 类型 |
---|---|---|
as | 'svg' | 作为标签 | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
高度 | 5 | 数字 箭头的像素高度。 |
rounded | 布尔值 当为 | |
宽度 | 10 | 数字 箭头的像素宽度。 |
项目
包含菜单栏项目的组件。
属性 | 默认 | 类型 |
---|---|---|
as | 'div' | 作为标签 | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
disabled | 布尔值 当为 | |
textValue | 字符串 用于即时搜索的可选文本。默认情况下,即时搜索行为将使用项目的 |
事件触发 | 载荷 |
---|---|
select | [事件: Event] 当用户选择项目(通过鼠标或键盘)时调用的事件处理程序。 |
数据属性 | 值 |
---|---|
[data-highlighted] | 高亮时存在 |
[data-disabled] | 禁用时存在 |
组
用于将多个 MenubarItem
分组。
属性 | 默认 | 类型 |
---|---|---|
as | 'div' | 作为标签 | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 |
标签
用于渲染标签。它不能通过箭头键聚焦。
属性 | 默认 | 类型 |
---|---|---|
as | 'div' | 作为标签 | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 |
复选框项目
一个可受控并像复选框一样渲染的项目。
属性 | 默认 | 类型 |
---|---|---|
as | 'div' | 作为标签 | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
disabled | 布尔值 当为 | |
modelValue | 假 | 真 | '不确定' 项目的受控选中状态。可用作 | |
textValue | 字符串 用于即时搜索的可选文本。默认情况下,即时搜索行为将使用项目的 |
事件触发 | 载荷 |
---|---|
select | [事件: Event] 当用户选择项目(通过鼠标或键盘)时调用的事件处理程序。 |
update:modelValue | [载荷: 布尔值] 值改变时调用的事件处理程序。 |
数据属性 | 值 |
---|---|
[data-state] | "选中" | "未选中" |
[data-highlighted] | 高亮时存在 |
[data-disabled] | 禁用时存在 |
单选组
用于将多个 MenubarRadioItem
分组。
属性 | 默认 | 类型 |
---|---|---|
as | 'div' | 作为标签 | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
modelValue | 字符串 组中选中项目的值。 |
事件触发 | 载荷 |
---|---|
update:modelValue | [载荷: 字符串] 值改变时调用的事件处理程序。 |
单选项目
一个可受控并像单选按钮一样渲染的项目。
属性 | 默认 | 类型 |
---|---|---|
as | 'div' | 作为标签 | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
disabled | 布尔值 当为 | |
textValue | 字符串 用于即时搜索的可选文本。默认情况下,即时搜索行为将使用项目的 | |
值* | 字符串 项目的唯一值。 |
事件触发 | 载荷 |
---|---|
select | [事件: Event] 当用户选择项目(通过鼠标或键盘)时调用的事件处理程序。 |
数据属性 | 值 |
---|---|
[data-state] | "选中" | "未选中" |
[data-highlighted] | 高亮时存在 |
[data-disabled] | 禁用时存在 |
项目指示器
当父级 MenubarCheckboxItem
或 MenubarRadioItem
被选中时渲染。您可以直接设置此元素的样式,也可以将其用作放置图标的包装器,或者两者兼可。
属性 | 默认 | 类型 |
---|---|---|
as | 'div' | 作为标签 | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
forceMount | 布尔值 当需要更多控制时,用于强制挂载。在与 Vue 动画库控制动画时很有用。 |
数据属性 | 值 |
---|---|
[data-state] | "选中" | "未选中" |
分隔符
用于在菜单栏菜单中在视觉上分隔项目。
属性 | 默认 | 类型 |
---|---|---|
as | 'div' | 作为标签 | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 |
子菜单
包含子菜单的所有部分。
属性 | 默认 | 类型 |
---|---|---|
defaultOpen | 布尔值 子菜单在初次渲染时的打开状态。当您不需要控制其打开状态时使用。 | |
open | 布尔值 菜单的受控打开状态。可用作 |
事件触发 | 载荷 |
---|---|
update:open | [载荷: 布尔值] 子菜单打开状态改变时调用的事件处理程序。 |
插槽(默认) | 载荷 |
---|---|
open | 布尔值 当前打开状态 |
子菜单触发器
一个用于打开子菜单的项目。必须在 MenubarSub
内部渲染。
属性 | 默认 | 类型 |
---|---|---|
as | 'div' | 作为标签 | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
disabled | 布尔值 当为 | |
textValue | 字符串 用于即时搜索的可选文本。默认情况下,即时搜索行为将使用项目的 |
数据属性 | 值 |
---|---|
[data-state] | "打开" | "关闭" |
[data-highlighted] | 高亮时存在 |
[data-disabled] | 禁用时存在 |
子菜单内容
子菜单打开时弹出的组件。必须在 MenubarSub
内部渲染。
属性 | 默认 | 类型 |
---|---|---|
alignOffset | 数字 与 | |
arrowPadding | 数字 箭头与内容边缘之间的内边距。如果您的内容有 border-radius,这将防止它溢出角落。 | |
as | 'div' | 作为标签 | 组件 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
avoidCollisions | 布尔值 当为 | |
collisionBoundary | 元素 | (元素 | null)[] | null 用作碰撞边界的元素。默认情况下是视口,但您可以提供其他元素以包含在此检查中。 | |
collisionPadding | 数字 | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>> 碰撞检测应发生的距边界边缘的像素距离。接受一个数字(所有边相同),或一个部分填充对象,例如:{ top: 20, left: 20 }。 | |
disableUpdateOnLayoutShift | 布尔值 当布局发生偏移时,是否禁用更新内容位置。 | |
forceMount | 布尔值 当需要更多控制时,用于强制挂载。在与 Vue 动画库控制动画时很有用。 | |
hideWhenDetached | 布尔值 当触发器完全被遮挡时,是否隐藏内容。 | |
loop | 布尔值 当为 | |
positionStrategy | '固定' | '绝对' 要使用的 CSS position 属性类型。 | |
prioritizePosition | 布尔值 强制内容在视口内定位。 可能与参考元素重叠,这可能不是期望的结果。 | |
reference | ReferenceElement 将设置为浮动元素定位参考的自定义元素或虚拟元素。 如果提供,它将替换默认的锚点元素。 | |
sideOffset | 数字 与触发器的像素距离。 | |
sticky | '部分' | '始终' 对齐轴上的粘性行为。 | |
updatePositionStrategy | '始终' | '优化' 在每个动画帧更新浮动元素位置的策略。 |
事件触发 | 载荷 |
---|---|
closeAutoFocus | [事件: Event] 关闭时自动聚焦调用的事件处理程序。可阻止其默认行为。 |
entryFocus | [事件: Event] 容器获得焦点时调用的事件处理程序。可阻止其默认行为。 |
escapeKeyDown | [事件: KeyboardEvent] 按下 Esc 键时调用的事件处理程序。可阻止其默认行为。 |
focusOutside | [事件: FocusOutsideEvent] 当焦点移出 |
interactOutside | [事件: PointerDownOutsideEvent | FocusOutsideEvent] 当 |
openAutoFocus | [事件: Event] 打开时自动聚焦调用的事件处理程序。可阻止其默认行为。 |
pointerDownOutside | [事件: PointerDownOutsideEvent] 当 |
数据属性 | 值 |
---|---|
[data-state] | "打开" | "关闭" |
[data-side] | "左" | "右" | "下" | "上" |
[data-align] | "开始" | "结束" | "居中" |
[data-orientation] | "垂直" | "水平" |
CSS 变量 | 描述 |
---|---|
--reka-menubar-content-transform-origin | 从内容和箭头位置/偏移量计算的 transform-origin |
--reka-menubar-content-available-width | 触发器与边界边缘之间的剩余宽度 |
--reka-menubar-content-available-height | 触发器与边界边缘之间的剩余高度 |
--reka-menubar-trigger-width | 触发器的宽度 |
--reka-menubar-trigger-height | 触发器的高度 |
示例
带子菜单
您可以使用 MenubarSub
及其部分组合来创建子菜单。
<script setup lang="ts">
import {
MenubarContent,
MenubarItem,
MenubarMenu,
MenubarPortal,
MenubarRoot,
MenubarSeparator,
MenubarSub,
MenubarSubContent,
MenubarSubTrigger,
MenubarTrigger,
} from 'reka-ui'
</script>
<template>
<MenubarRoot>
<MenubarMenu>
<MenubarTrigger>…</MenubarTrigger>
<MenubarPortal>
<MenubarContent>
<MenubarItem>…</MenubarItem>
<MenubarItem>…</MenubarItem>
<MenubarSeparator />
<MenubarSub>
<MenubarSubTrigger>Sub menu →</MenubarSubTrigger>
<MenubarPortal>
<MenubarSubContent>
<MenubarItem>Sub menu item</MenubarItem>
<MenubarItem>Sub menu item</MenubarItem>
<MenubarArrow />
</MenubarSubContent>
</MenubarPortal>
</MenubarSub>
<MenubarSeparator />
<MenubarItem>…</MenubarItem>
</MenubarContent>
</MenubarPortal>
</MenubarMenu>
</MenubarRoot>
</template>
带禁用项目
您可以通过 data-disabled
属性为禁用项目添加特殊样式。
<script setup lang="ts">
import { MenubarContent, MenubarItem, MenubarMenu, MenubarPortal, MenubarRoot, MenubarTrigger } from 'reka-ui'
</script>
<template>
<MenubarRoot>
<MenubarMenu>
<MenubarTrigger>…</MenubarTrigger>
<MenubarPortal>
<MenubarContent>
<MenubarItem
class="MenubarItem"
disabled
>
…
</MenubarItem>
<MenubarItem class="MenubarItem">
…
</MenubarItem>
</MenubarContent>
</MenubarPortal>
</MenubarMenu>
</MenubarRoot>
</template>
/* styles.css */
.MenubarItem[data-disabled] {
color: gainsboro;
}
带分隔符
使用 Separator
部分在项目之间添加分隔符。
<script setup lang="ts">
import {
MenubarContent,
MenubarItem,
MenubarMenu,
MenubarPortal,
MenubarRoot,
MenubarSeparator,
MenubarTrigger,
} from 'reka-ui'
</script>
<template>
<MenubarRoot>
<MenubarMenu>
<MenubarTrigger>…</MenubarTrigger>
<MenubarPortal>
<MenubarContent>
<MenubarItem>…</MenubarItem>
<MenubarSeparator />
<MenubarItem>…</MenubarItem>
<MenubarSeparator />
<MenubarItem>…</MenubarItem>
</MenubarContent>
</MenubarPortal>
</MenubarMenu>
</MenubarRoot>
</template>
带标签
使用 Label
部分帮助标记一个区域。
<script setup lang="ts">
import {
MenubarContent,
MenubarItem,
MenubarLabel,
MenubarMenu,
MenubarPortal,
MenubarRoot,
MenubarTrigger,
} from 'reka-ui'
</script>
<template>
<MenubarRoot>
<MenubarMenu>
<MenubarTrigger>…</MenubarTrigger>
<MenubarPortal>
<MenubarContent>
<MenubarLabel>Label</MenubarLabel>
<MenubarItem>…</MenubarItem>
<MenubarItem>…</MenubarItem>
<MenubarItem>…</MenubarItem>
</MenubarContent>
</MenubarPortal>
</MenubarMenu>
</MenubarRoot>
</template>
带复选框项目
使用 CheckboxItem
部分添加一个可勾选的项目。
<script setup lang="ts">
import { Icon } from '@iconify/vue'
import {
MenubarCheckboxItem,
MenubarContent,
MenubarItem,
MenubarItemIndicator,
MenubarMenu,
MenubarPortal,
MenubarRoot,
MenubarSeparator,
MenubarTrigger,
} from 'reka-ui'
const checked = ref(true)
</script>
<template>
<MenubarRoot>
<MenubarMenu>
<MenubarTrigger>…</MenubarTrigger>
<MenubarPortal>
<MenubarContent>
<MenubarItem>…</MenubarItem>
<MenubarItem>…</MenubarItem>
<MenubarSeparator />
<MenubarCheckboxItem v-model="checked">
<MenubarItemIndicator>
<Icon icon="radix-icons:check" />
</MenubarItemIndicator>
Checkbox item
</MenubarCheckboxItem>
</MenubarContent>
</MenubarPortal>
</MenubarMenu>
</MenubarRoot>
</template>
带单选项目
使用 RadioGroup
和 RadioItem
部分添加一个可在其他项目中选中的项目。
<script setup lang="ts">
import { Icon } from '@iconify/vue'
import {
MenubarCheckboxItem,
MenubarContent,
MenubarItem,
MenubarItemIndicator,
MenubarMenu,
MenubarPortal,
MenubarRadioGroup,
MenubarRadioItem,
MenubarRoot,
MenubarSeparator,
MenubarTrigger,
} from 'reka-ui'
const color = ref('blue')
</script>
<template>
<MenubarRoot>
<MenubarMenu>
<MenubarTrigger>…</MenubarTrigger>
<MenubarPortal>
<MenubarContent>
<MenubarRadioGroup v-model="color">
<MenubarRadioItem value="red">
<MenubarItemIndicator>
<Icon icon="radix-icons:check" />
</MenubarItemIndicator>
Red
</MenubarRadioItem>
<MenubarRadioItem value="blue">
<MenubarItemIndicator>
<Icon icon="radix-icons:check" />
</MenubarItemIndicator>
Blue
</MenubarRadioItem>
</MenubarRadioGroup>
</MenubarContent>
</MenubarPortal>
</MenubarMenu>
</MenubarRoot>
</template>
带复杂项目
您可以在 Item
部分添加额外的装饰元素,例如图片。
<script setup lang="ts">
import { MenubarContent, MenubarItem, MenubarMenu, MenubarPortal, MenubarRoot, MenubarTrigger } from 'reka-ui'
</script>
<template>
<MenubarRoot>
<MenubarMenu>
<MenubarTrigger>…</MenubarTrigger>
<MenubarPortal>
<MenubarContent>
<MenubarItem>
<img src="…">
Adolfo Hess
</MenubarItem>
<MenubarItem>
<img src="…">
Miyah Myles
</MenubarItem>
</MenubarContent>
</MenubarPortal>
</MenubarMenu>
</MenubarRoot>
</template>
限制内容/子内容大小
您可能希望限制内容(或子内容)的宽度,使其与触发器(或子触发器)的宽度匹配。您可能还希望限制其高度不超过视口。
我们公开了几个 CSS 自定义属性,例如 --reka-menubar-trigger-width
和 --reka-menubar-content-available-height
来支持此功能。使用它们来限制内容尺寸。
<script setup lang="ts">
import { MenubarContent, MenubarItem, MenubarMenu, MenubarPortal, MenubarRoot, MenubarTrigger } from 'reka-ui'
</script>
<template>
<MenubarRoot>
<MenubarMenu>
<MenubarTrigger> Trigger </MenubarTrigger>
<MenubarPortal>
<MenubarContent
class="MenubarContent"
:side-offset="5"
:align-offset="-3"
>
<MenubarItem> New Tab </MenubarItem>
</MenubarContent>
</MenubarPortal>
</MenubarMenu>
</MenubarRoot>
</template>
/* styles.css */
.MenubarContent {
width: var(--reka-menubar-trigger-width);
max-height: var(--reka-menubar-content-available-height);
}
原点感知动画
我们公开了一个 CSS 自定义属性 --reka-menubar-content-transform-origin
。使用它来根据 side
、sideOffset
、align
、alignOffset
和任何碰撞从其计算出的原点来动画化内容。
<script setup lang="ts">
import { MenubarContent, MenubarMenu, MenubarPortal, MenubarRoot, MenubarTrigger } from 'reka-ui'
</script>
<template>
<MenubarRoot>
<MenubarMenu>
<MenubarTrigger>…</MenubarTrigger>
<MenubarPortal>
<MenubarContent class="MenubarContent">
…
</MenubarContent>
</MenubarPortal>
</MenubarMenu>
</MenubarRoot>
</template>
/* styles.css */
.MenubarContent {
transform-origin: var(--reka-menubar-content-transform-origin);
animation: scaleIn 0.5s ease-out;
}
@keyframes scaleIn {
from {
opacity: 0;
transform: scale(0);
}
to {
opacity: 1;
transform: scale(1);
}
}
碰撞感知动画
我们公开了 data-side
和 data-align
属性。它们的值将在运行时改变以反映碰撞。使用它们来创建碰撞和方向感知的动画。
<script setup lang="ts">
import { MenubarContent, MenubarMenu, MenubarPortal, MenubarRoot, MenubarTrigger } from 'reka-ui'
</script>
<template>
<MenubarRoot>
<MenubarMenu>
<MenubarTrigger>…</MenubarTrigger>
<MenubarPortal>
<MenubarContent class="MenubarContent">
…
</MenubarContent>
</MenubarPortal>
</MenubarMenu>
</MenubarRoot>
</template>
/* styles.css */
.MenubarContent {
animation-duration: 0.6s;
animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}
.MenubarContent[data-side="top"] {
animation-name: slideUp;
}
.MenubarContent[data-side="bottom"] {
animation-name: slideDown;
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
可访问性
遵循 菜单按钮 WAI-ARIA 设计模式,并使用 roving tabindex 管理菜单项之间的焦点移动。
键盘交互
键 | 描述 |
---|---|
空格键 | 当焦点位于 MenubarTrigger 上时,打开菜单栏并聚焦第一个项目。当焦点位于某个项目上时,激活该项目。 |
回车键 | 当焦点位于 MenubarTrigger 上时,打开关联菜单。当焦点位于某个项目上时,激活该项目。 |
向下箭头键 | 当焦点位于 MenubarTrigger 上时,打开关联菜单。当焦点在项目上时,将焦点移到下一个项目。 |
向上箭头键 | 当焦点在项目上时,将焦点移到上一个项目。 |
向右箭头键向左箭头键 | 当焦点位于 MenubarTrigger 上时,将焦点移动到下一个或上一个项目。当焦点位于 MenubarSubTrigger 上时,根据阅读方向打开或关闭子菜单。当焦点位于 MenubarContent 内部时,打开菜单栏中的下一个菜单。 |
Esc键 | 关闭当前打开的菜单,并将焦点移动到其 MenubarTrigger 。 |