代码演示
如何引入
<script setup lang="ts">
import { Dropdown } from '@fibrous/semi-ui-vue';
</script>
Dropdown.Menu、Dropdown.Item、Dropdown.Title、Dropdown.Divider 也可以按名导入:DropdownMenu、DropdownItem、DropdownTitle、DropdownDivider。
基本用法
- 默认插槽放 Dropdown 的 Trigger 触发器:默认为 hover 展示,可通过
trigger修改为click、custom、contextMenu等值指定不同触发方式 - 通过
#content插槽指定下拉框的具体内容:使用Dropdown.Menu作为父容器,组合使用Dropdown.Item、Dropdown.Divider、Dropdown.Title。
当然简单场景你也可以仅搭配Dropdown.Menu与Dropdown.Item,其他元素不是必须的。 Dropdown.Item通过设置disabled可以禁用某个选项,配置type,可以展示不同颜色的文本,用#icon插槽可以快速配置图标。更复杂的自定义结构,直接写在Dropdown.Item的默认插槽里。
代码
<script setup lang="ts">
import { IconAlertCircle, IconBox, IconForward, IconRefresh, IconSearch, IconSetting } from '@fibrous/semi-icons-vue';
import { IconToken } from '@fibrous/semi-icons-vue/lab';
import { Button, Dropdown, HotKeys } from '@fibrous/semi-ui-vue';
</script>
<template>
<Dropdown position="bottomLeft">
<Button theme="outline" type="tertiary">
<template #icon>
<IconToken />
</template>
Hover Me
</Button>
<template #content>
<Dropdown.Menu>
<Dropdown.Title>分组1</Dropdown.Title>
<Dropdown.Item>
<template #icon>
<IconBox />
</template>
Menu Item 1
<HotKeys :content="['Ctrl', 'B']" :hotKeys="[HotKeys.Keys.Control, HotKeys.Keys.B]" :style="{ marginLeft: '20px' }" />
</Dropdown.Item>
<Dropdown.Item>
<template #icon>
<IconSetting />
</template>
Menu Item 2
<HotKeys :content="['Ctrl', 'V']" :hotKeys="[HotKeys.Keys.Control, HotKeys.Keys.V]" :style="{ marginLeft: '20px' }" />
</Dropdown.Item>
<Dropdown.Item disabled>
<template #icon>
<IconForward />
</template>
Menu Item 3
<HotKeys :content="['Ctrl', 'F3']" :hotKeys="[HotKeys.Keys.Control, HotKeys.Keys.F3]" :style="{ marginLeft: '20px' }" />
</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Title>分组2</Dropdown.Title>
<Dropdown.Item type="tertiary">
<template #icon>
<IconRefresh />
</template>
tertiary
</Dropdown.Item>
<Dropdown.Item type="warning">
<template #icon>
<IconSearch />
</template>
warning
</Dropdown.Item>
<Dropdown.Item type="danger">
<template #icon>
<IconAlertCircle />
</template>
danger
</Dropdown.Item>
</Dropdown.Menu>
</template>
</Dropdown>
</template>嵌套使用
用户可以对 Dropdown 进行嵌套使用,此类情况适合具有多个子级选项的情况。键盘上 右箭头 打开子菜单、左箭头 回到父项,Enter 或 Space 触发任意层菜单项的 @click(详见 Accessibility)。嵌套的子菜单默认 spacing 为 2;showTick、selectionMode 与 trigger 不从外层继承,按子菜单 Dropdown 自身的设置生效。
代码
<script setup lang="ts">
import { IconToken } from '@fibrous/semi-icons-vue/lab';
import { Button, Dropdown, Toast } from '@fibrous/semi-ui-vue';
const submenus = [
{ label: 'Menu Item 1', position: 'rightTop' },
{ label: 'Menu Item 2', position: 'leftTop' },
] as const;
</script>
<template>
<div :style="{ margin: '100px' }">
<Dropdown>
<Button theme="outline" type="tertiary">
<template #icon>
<IconToken />
</template>
Hover Me
</Button>
<template #content>
<Dropdown.Menu>
<Dropdown v-for="submenu in submenus" :key="submenu.label" :position="submenu.position">
<Dropdown.Item>{{ submenu.label }}</Dropdown.Item>
<template #content>
<Dropdown.Menu>
<!-- Enter and Space trigger a submenu item's click too -->
<Dropdown.Item v-for="n in 3" :key="n" @click="Toast.info(`点击了 Nested Menu Item ${n}`)"> Nested Menu Item {{ n }} </Dropdown.Item>
</Dropdown.Menu>
</template>
</Dropdown>
<Dropdown.Item>Menu Item 3</Dropdown.Item>
</Dropdown.Menu>
</template>
</Dropdown>
</div>
</template>弹出位置
支持的位置同 Tooltip,常用的是:"bottom", "bottomLeft", "bottomRight" 这三种。
代码
<script setup lang="ts">
import { Dropdown, Tag } from '@fibrous/semi-ui-vue';
const positions = ['bottom', 'bottomLeft', 'bottomRight'] as const;
</script>
<template>
<div>
<template v-for="(position, index) in positions" :key="position">
<template v-if="index > 0">
<br />
<br />
</template>
<Dropdown :position="position">
<Tag>{{ position === 'bottom' ? 'Bottom' : position }}</Tag>
<template #content>
<Dropdown.Menu>
<Dropdown.Item>Menu Item 1</Dropdown.Item>
<Dropdown.Item>Menu Item 2</Dropdown.Item>
<Dropdown.Item>Menu Item 3</Dropdown.Item>
</Dropdown.Menu>
</template>
</Dropdown>
</template>
</div>
</template>触发方式
默认是移入触发,可通过获取焦点(focus),点击(click)或自定义事件触发菜单展开。
contextMenu 方式右键打开菜单后焦点会移到第一个可用项。
代码
<script setup lang="ts">
import { Button, Dropdown, Tag } from '@fibrous/semi-ui-vue';
</script>
<template>
<div>
<Dropdown position="bottomLeft" trigger="hover">
<Tag>Hover me</Tag>
<template #content>
<Dropdown.Menu>
<Dropdown.Item>Menu Item 1</Dropdown.Item>
<Dropdown.Item>Menu Item 2</Dropdown.Item>
<Dropdown.Item>Menu Item 3</Dropdown.Item>
</Dropdown.Menu>
</template>
</Dropdown>
<br />
<br />
<Dropdown position="bottomLeft" trigger="focus">
<div
:style="{
border: '1px solid var(--semi-color-border)',
borderRadius: '4px',
height: '36px',
width: '220px',
}"
>
Please use Tab to focus this div
</div>
<template #content>
<Dropdown.Menu :tabindex="-1">
<Dropdown.Item>Menu Item 1</Dropdown.Item>
<Dropdown.Item>Menu Item 2</Dropdown.Item>
<Dropdown.Item>Menu Item 3</Dropdown.Item>
</Dropdown.Menu>
</template>
</Dropdown>
<br />
<br />
<Dropdown position="bottomLeft" trigger="click">
<Button>Click me</Button>
<template #content>
<Dropdown.Menu>
<Dropdown.Item>Menu Item 1</Dropdown.Item>
<Dropdown.Item>Menu Item 2</Dropdown.Item>
<Dropdown.Item>Menu Item 3</Dropdown.Item>
</Dropdown.Menu>
</template>
</Dropdown>
<br />
<br />
<Dropdown position="bottomRight" trigger="contextMenu">
<Button :style="{ marginBottom: '20px' }" theme="solid" type="secondary"> Right click (ContextMenu) </Button>
<template #content>
<Dropdown.Menu>
<Dropdown.Item>Menu Item 1</Dropdown.Item>
<Dropdown.Item>Menu Item 2</Dropdown.Item>
<Dropdown.Item>Menu Item 3</Dropdown.Item>
</Dropdown.Menu>
</template>
</Dropdown>
</div>
</template>触发事件
点击菜单项后可触发不同鼠标事件,支持 @click,@mouseenter,@mouseleave 和 @contextmenu。顶层菜单的 @click 在点击时触发,子菜单的在鼠标左键按下时触发,键盘的 Enter 和 Space 同样触发。
代码
<script setup lang="ts">
import { IconToken } from '@fibrous/semi-icons-vue/lab';
import { Button, Dropdown, Toast } from '@fibrous/semi-ui-vue';
</script>
<template>
<Dropdown position="bottomLeft" trigger="click">
<Button theme="outline" type="tertiary">
<template #icon>
<IconToken />
</template>
Click Me
</Button>
<template #content>
<Dropdown.Menu>
<Dropdown.Item @click="Toast.info('You clicked me!')">1: click me!</Dropdown.Item>
<Dropdown.Item @mouseenter="Toast.info('Nice to meet you!')">2: mouse enter</Dropdown.Item>
<Dropdown.Item @mouseleave="Toast.info('See ya!')">3: mouse leave</Dropdown.Item>
<Dropdown.Item @contextmenu="Toast.info('Right clicked!')">4: right click</Dropdown.Item>
</Dropdown.Menu>
</template>
</Dropdown>
</template>Json 用法
可以通过 menu 属性,传入 JSON Array 快速配置出下拉框菜单。数据项里的监听使用 Vue 的键名,如 onClick、onMouseenter,会交给对应的 Dropdown.Item;需要为每一项自定义图标时使用 #menuIcon="{ item, index }" 插槽。提供 #content 插槽时以插槽为准。
代码
<script setup lang="ts">
import { IconToken } from '@fibrous/semi-icons-vue/lab';
import { Button, Dropdown, type DropDownMenuItem } from '@fibrous/semi-ui-vue';
const menu: DropDownMenuItem[] = [
{ node: 'title', name: '分组1' },
{ node: 'item', name: 'primary1', type: 'primary', onClick: () => console.log('click primary') },
{ node: 'item', name: 'secondary', type: 'secondary' },
{ node: 'divider' },
{ node: 'title', name: '分组2' },
{ node: 'item', name: 'tertiary', type: 'tertiary' },
{ node: 'item', name: 'warning', type: 'warning', active: true },
{ node: 'item', name: 'danger', type: 'danger' },
];
</script>
<template>
<Dropdown :menu="menu" position="bottomLeft" showTick trigger="click">
<Button theme="outline" type="tertiary">
<template #icon>
<IconToken />
</template>
Click Me
</Button>
</Dropdown>
</template>API 参考
Dropdown
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| contentClassName | 下拉菜单根元素的类名。 | string | unknown[] | semiGlobalDefault("Dropdown", "contentClassName") |
| menu | 通过数据快速配置菜单,数据项见下方 DropdownMenuItem;提供了 content 插槽时以插槽为准。 | DropDownMenuItem[] | semiGlobalDefault("Dropdown", "menu") |
| selectionMode | 本层菜单项的选择方式,已选项由 active 标记:single 时菜单项为带 aria-checked 的 menuitemradio,multiple 时为带 aria-checked 的 menuitemcheckbox;未设置时 showTick 开启则为带 aria-checked 的 menuitemcheckbox,否则为 menuitem。只影响角色与状态,勾的显示仍由 showTick 决定;嵌套的子菜单不继承。 | DropdownSelectionMode | semiGlobalDefault("Dropdown", "selectionMode") |
| showTick | 是否在 active 的 Dropdown.Item 左侧展示表示选中的勾;只作用于本 Dropdown 的菜单,嵌套的子菜单不继承。 | boolean | semiDefault("Dropdown", "showTick", false) |
| motion | 是否展示弹出层动画。 | boolean | semiDefault("Dropdown", "motion", true) |
| autoAdjustOverflow | 弹出层被遮挡时是否自动调整方向。 | boolean | semiGlobalDefault("Dropdown", "autoAdjustOverflow") |
| position | 弹出菜单相对触发元素的位置,常用 bottom、bottomLeft、bottomRight,更多见 Tooltip 的位置。 | Type"top" | "bottom" | "left" | "right" | "topLeft" | "topRight" | "leftTop" | "leftBottom" | "rightTop" | "rightBottom" | "bottomLeft" | "bottomRight" | "leftTopOver" | "rightTopOver" | "leftBottomOver" | "rightBottomOver" | semiDefault("Dropdown", "position", "bottom") |
| prefixCls | 弹出层类名前缀,设置后弹出层不再带 Dropdown 的样式。 | string | semiDefault("Dropdown", "prefixCls", cssClasses.PREFIX) |
| spacing | 弹出层与触发元素的距离,单位为像素;缺省时顶层菜单为 4,嵌套的子菜单为 2。 | number | { x: number; y: number; } | semiGlobalDefault("Dropdown", "spacing") |
| role | 包裹菜单的弹层容器的 ARIA role,默认 presentation,菜单本身的 role 为 menu。 | string | semiDefault("Dropdown", "role", "presentation") |
| ariaLabel | 弹出层 role 为 dialog 时的 aria-label。 | string | semiGlobalDefault("Dropdown", "ariaLabel") |
| ariaLabelledby | 弹出层 role 为 dialog 时的 aria-labelledby。 | string | semiGlobalDefault("Dropdown", "ariaLabelledby") |
| ariaDescribedby | 弹出层 role 为 dialog 时的 aria-describedby。 | string | semiGlobalDefault("Dropdown", "ariaDescribedby") |
| wrapWhenSpecial | 触发元素禁用或加载中时,是否在外层包裹 span 以保证触发行为。 | boolean | semiGlobalDefault("Dropdown", "wrapWhenSpecial") |
| stopPropagation | 是否阻止弹出层上的 click、mousedown 与焦点进出事件冒泡。 | boolean | semiGlobalDefault("Dropdown", "stopPropagation") |
| wrapperClassName | 触发元素被 span 包裹时,该 span 的类名。 | string | semiGlobalDefault("Dropdown", "wrapperClassName") |
| wrapperId | 弹出层节点的 id,触发元素的 aria 属性指向它;缺省时自动生成。 | string | undefined |
| keepDOM | 关闭时是否保留弹出层内容而不销毁。 | boolean | semiGlobalDefault("Dropdown", "keepDOM") |
| clickToHide | 在弹出层内点击时是否自动关闭弹出层。 | boolean | semiGlobalDefault("Dropdown", "clickToHide") |
| clickTriggerToHide | 点击触发元素时是否关闭已打开的弹出层。 | boolean | semiGlobalDefault("Dropdown", "clickTriggerToHide") |
| closeOnEsc | 在触发元素或弹出层按 Esc 是否关闭菜单;trigger 为 custom 时只触发 escKeyDown,由使用方决定是否关闭。 | boolean | semiDefault("Dropdown", "closeOnEsc", true) |
| condition | 是否允许触发显示;仅显式设为 false 时,hover、click、focus 等触发行为不生效,trigger 为 custom 时仍按 visible 显示。由 true 变为 false 时立即关闭已显示的弹出层;visible 受控时只发出 update:visible 与 visibleChange(false),使用方回写后才关闭。 | boolean | semiGlobalDefault("Dropdown", "condition") |
| disableFocusListener | trigger 为 hover 时,是否不响应键盘聚焦打开菜单。 | boolean | semiGlobalDefault("Dropdown", "disableFocusListener") |
| guardFocus | 焦点位于弹出层内时,Tab 是否在弹出层内循环。 | boolean | semiGlobalDefault("Dropdown", "guardFocus") |
| mouseEnterDelay | 指针移入触发元素后延迟显示的毫秒数,仅 trigger 为 hover 或 focus 时生效。 | number | semiGlobalDefault("Dropdown", "mouseEnterDelay") |
| mouseLeaveDelay | 指针移出弹出层后延迟隐藏的毫秒数,仅 trigger 为 hover 或 focus 时生效,不小于 mouseEnterDelay。 | number | TypesemiDefault("Dropdown", "mouseLeaveDelay", strings.DEFAULT_LEAVE_DELAY) |
| preventScroll | 聚焦时是否阻止浏览器滚动到被聚焦元素。 | boolean | semiGlobalDefault("Dropdown", "preventScroll") |
| returnFocusOnClose | 菜单关闭后焦点是否回到触发元素。 | boolean | semiDefault("Dropdown", "returnFocusOnClose", true) |
| trigger | 触发菜单显示的行为,可选 hover、focus、click、custom、contextMenu;custom 时显示与否完全由 visible 决定。 | "hover" | "focus" | "click" | "custom" | "contextMenu" | semiDefault("Dropdown", "trigger", "hover") |
| visible | 菜单是否显示,配合 trigger 为 custom 与 v-model:visible 使用;传入后由该值决定显示。 | boolean | semiGlobalDefault("Dropdown", "visible") |
Events
| 事件 | 说明 | 回调参数 |
|---|---|---|
| open | 菜单显示、进场动画开始时触发,每次打开一次,早于 afterOpen,受控与非受控相同;悬停打开后指针已离开而撤回的打开不触发。 | [] |
| update:visible | 菜单需要显示或隐藏时触发,供 v-model:visible 回写。 | [visible: boolean] |
| visibleChange | 菜单显示状态变化时触发;visible 受控时只报告用户交互发起的请求,父组件自己改变 visible 不触发。 | [visible: boolean] |
| clickOutSide | 菜单打开时在触发元素与弹出层以外的区域按下鼠标时触发,仅 trigger 为 click、contextMenu、custom 或开启 clickTriggerToHide 时有效。 | [event: MouseEvent] |
| escKeyDown | closeOnEsc 为 true 时,菜单打开期间按 Esc 触发。 | [event: KeyboardEvent] |
| afterOpen | 菜单打开且进场动画结束后触发;没有进场动画时打开后即触发,受控与非受控相同;进场结束前被关闭的打开不触发。 | [] |
| afterClose | 菜单关闭且离场动画结束后触发。 | [] |
Slots
| 插槽 | 说明 | 作用域参数 |
|---|---|---|
| default | 触发元素。单个元素或组件直接接收触发属性,文本或多个节点会被 span 包裹,同样响应键盘。 | any |
| content | 菜单内容,由 Dropdown.Menu 及 Dropdown.Item、Dropdown.Title、Dropdown.Divider 构成;提供后优先于 menu。 | any |
| menuIcon | menu 中每个 item 项的图标,作用域参数为该数据项与序号;渲染为空时该项无图标。 | DropdownMenuIconSlotProps |
Exposes
| 名称 | 说明 | 类型 |
|---|---|---|
| focusTrigger | 让触发元素获得焦点,仅在 returnFocusOnClose 为 true 且 trigger 不是 custom 时生效。 | Type() => void |
| rePosition | 按触发器当前位置立即重新计算弹出层位置。弹出层已随滚动、窗口尺寸变化、触发器移动以及触发器或弹出层的尺寸变化自动重新定位,一般无需调用;跟随触发器移动会晚一帧,需要同一帧内对齐时调用。 | Type() => void |
Dropdown 没有自己的根元素:class 落在弹层外层 .semi-dropdown-wrapper 上,style 落在 .semi-dropdown 上,其余未声明的属性被丢弃。
Dropdown.Menu
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| 无 |
Events
| 事件 | 说明 | 回调参数 |
|---|---|---|
| 无 |
Slots
| 插槽 | 说明 | 作用域参数 |
|---|---|---|
| default | 菜单的子元素,一般为 Dropdown.Item、Dropdown.Title 或 Dropdown.Divider。 | any |
Exposes
| 名称 | 说明 | 类型 |
|---|---|---|
| 无 |
class、style 与原生属性经 attrs 落在菜单的 ul 上;role 与 aria-orientation 可以被覆盖,绑定在菜单上的 @keydown 先于内置的键盘处理执行。
Dropdown.Item
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| active | 当前项是否处于激活态,激活态时字体加粗、颜色加深;Dropdown 的 showTick 为 true 时左侧还会展示 √。 | boolean | false |
| disabled | 是否禁用该项。 | boolean | false |
| showTick | 仅在 Dropdown 之外使用时生效;在 Dropdown 内以 Dropdown 的 showTick 为准。 | boolean | undefined |
| type | 文本颜色类型,可选 primary、secondary、tertiary、warning、danger。 | Type | undefined |
Events
| 事件 | 说明 | 回调参数 |
|---|---|---|
| 无 |
Slots
| 插槽 | 说明 | 作用域参数 |
|---|---|---|
| default | 菜单项的内容。 | any |
| icon | 菜单项的图标。 | any |
Exposes
| 名称 | 说明 | 类型 |
|---|---|---|
| 无 |
点击、鼠标移入移出与右键使用 @click、@mouseenter、@mouseleave、@contextmenu 监听;@click 的参数是原生 MouseEvent。class、style 与其他原生属性经 attrs 落在 li 上。禁用的 Item 不响应 @click、@mouseenter、@mouseleave、@contextmenu。
Dropdown.Title
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| 无 |
Events
| 事件 | 说明 | 回调参数 |
|---|---|---|
| 无 |
Slots
| 插槽 | 说明 | 作用域参数 |
|---|---|---|
| default | 分组标题的内容。 | any |
Exposes
| 名称 | 说明 | 类型 |
|---|---|---|
| 无 |
class、style 与原生属性经 attrs 落在 li 上。分隔线 Dropdown.Divider 没有属性与插槽,同样经 attrs 接收 class、style。
DropdownMenuItem
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| node | 数据项类型,可选:title,item,divider | 'title' | 'item' | 'divider' | - |
| name | 菜单文本,仅 title 与 item 有 | string | number | - |
| active、disabled、showTick、type | 与 Dropdown.Item 的同名属性对应,仅 item 有 | - | - |
class、style、data-*、aria-* | 经 attrs 交给对应的 Title、Item、Divider;style 为字符串或样式对象,不接受数组 | - | - |
| onClick、onMouseenter、onMouseleave、onContextmenu | Dropdown.Item 的监听,使用 Vue 键名,仅 item 有 | (event: MouseEvent) => void | - |
数据项不接受 children,标签只由 name 提供。
Methods
通过模板 ref 调用 focusTrigger() 与 rePosition(),见上方 Dropdown 的 Exposes。
Accessibility
Dropdown 按 WAI-ARIA APG 的 Menu Button 与 Menu and Menubar 模式实现。
ARIA
- 触发元素带
aria-haspopup="menu"与aria-expanded,菜单显示时aria-expanded为true,否则为false - Dropdown.Menu 的
role为menu,aria-orientation为vertical - Dropdown.Item 的
role为menuitem;Dropdown 的selectionMode为single时为menuitemradio,为multiple或开启showTick时为menuitemcheckbox,这三种情况都以aria-checked暴露active;√ 图标不计入菜单项名称;禁用项带aria-disabled="true" - 作为嵌套 Dropdown 触发元素的 Dropdown.Item(父项)同样带
aria-haspopup="menu"与aria-expanded - Dropdown.Divider 渲染为
role="separator"的li,Dropdown.Title 渲染为role="presentation"的li - 包裹菜单的弹层容器
role为presentation,不是tooltip
键盘和焦点
焦点在触发元素上时:
| 按键 | 行为 |
|---|---|
Enter、Space | trigger 为 click 时打开菜单,焦点移到第一个可用项 |
下箭头 | 菜单已打开时,焦点移到第一个可用项;触发元素是按钮(button、带 href 的链接、Semi Button 等)且菜单关闭时,打开菜单并聚焦第一个可用项 |
上箭头 | 菜单已打开时,焦点移到最后一个可用项;触发元素是按钮且菜单关闭时,打开菜单并聚焦最后一个可用项 |
Tab | 菜单已打开时关闭菜单,焦点按浏览器默认顺序移动 |
render(Vue 中为 #content 插槽)中没有菜单项时,弹层打开后按 下箭头、上箭头 分别聚焦弹层中第一个、最后一个可聚焦元素。
触发元素是文本或多个节点时,Dropdown 用一个 span 包裹它们,上表按键对这个 span 同样生效。
trigger 为 hover 或 focus 时,键盘聚焦触发元素即打开菜单(disableFocusListener 可关闭),失焦后关闭。
trigger 为 contextMenu 时,右键打开菜单后焦点移到第一个可用项。
焦点在菜单项上时:
| 按键 | 行为 |
|---|---|
下箭头、上箭头 | 移到当前层的下一项、上一项,跳过禁用项,到首尾后循环 |
Home、End | 移到当前层的第一项、最后一项 |
Enter、Space | 父项:打开子菜单并把焦点移到子菜单第一项;其他项:触发 onClick(Vue 中为 @click),开启 clickToHide 时随后关闭菜单 |
右箭头 | 父项:打开子菜单并把焦点移到子菜单第一项;其他项无效果 |
左箭头 | 在子菜单中:关闭子菜单,焦点回到父项,与 closeOnEsc 无关 |
Tab | 关闭全部菜单(含子菜单),焦点按浏览器默认顺序移动,不回到触发元素 |
Esc | 关闭焦点所在的那一层菜单,焦点回到打开它的元素(父项或触发元素);焦点在父项且其子菜单已打开时先关闭子菜单;closeOnEsc 为 false 时不关闭 |
| 字母键 | 移到当前层下一个以该字符开头的项 |
- RTL(ConfigProvider
direction="rtl")下左箭头与右箭头的行为互换。 - 菜单项的
onKeyDown(Vue 中为@keydown)中调用e.preventDefault()可以阻止Enter、Space触发onClick(Vue 中为@click)。 - 嵌套 Dropdown 的子菜单项由键盘激活时
onClick(Vue 中为@click)收到的是click事件;鼠标操作时仍在左键按下时触发。
文案规范
- 下拉框内选项内容需要表述准确且包含信息,使用户在浏览时更加容易在选项中选择
- 使用语句式的大小写,并且简洁明了地书写选项
- 如果是动作选项,使用动词或者动词短语来描述用户选择该选项后会发生的动作。举个例子,"Move", "Log time", or "Hide labels"
- 不使用介词
| ✅ 推荐用法 | ❌ 不推荐用法 |
|---|---|
设计变量
| Sass 变量 | 值 | 用法 |
|---|---|---|
| $transition_duration-dropdown_item-bg | var(--semi-transition_duration-none) | 下拉菜单项-背景颜色-动画持续时间 |
| $transition_function-dropdown_item-bg | var(--semi-transition_function-easeOut) | 下拉菜单项-背景颜色-过渡曲线 |
| $transition_delay-dropdown_item-bg | 0ms | 下拉菜单项-背景颜色-延迟时间 |
| $radius-dropdown | var(--semi-border-radius-medium) | 下拉菜单圆角大小 |
| $radius-dropdown_item | 0px | 下拉菜单项圆角大小 |
| $color-dropdown-bg-default | var(--semi-color-bg-3) | 下拉菜单背景颜色 |
| $color-dropdown_title-text-default | var(--semi-color-text-2) | 下拉菜单分组标题文字颜色 |
| $spacing-dropdown_menu-paddingY | $spacing-extra-tight | 下拉菜单垂直内边距 |
| $spacing-dropdown_menu-paddingX | 0 | 下拉菜单水平内边距 |
| $spacing-dropdown_title-paddingTop | $spacing-tight | 下拉菜单分组标题顶部内边距 |
| $spacing-dropdown_title-paddingBottom | $spacing-extra-tight | 下拉菜单分组标题底部内边距 |
| $spacing-dropdown_title-paddingLeft | $spacing-base | 下拉菜单分组标题左侧内边距 |
| $spacing-dropdown_title-paddingRight | $spacing-base | 下拉菜单分组标题右侧内边距 |
| $spacing-dropdown_title_withTick-paddingLeft | 31px | 可选中的下拉菜单,分组标题左侧内边距 |
| $spacing-dropdown_item_withTick-paddingLeft | $spacing-base-tight | 可选中弄的下拉菜单项,对勾 icon 左侧内边距 |
| $spacing-dropdown_item-paddingY | $spacing-tight | 下拉菜单项垂直内边距 |
| $spacing-dropdown_item-paddingX | $spacing-base | 下拉菜单项水平内边距 |
| $color-dropdown_item-text-default | var(--semi-color-text-0) | 下拉菜单项文字颜色 |
| $color-dropdown_item-bg-hover | var(--semi-color-fill-0) | 下拉菜单项背景颜色 - 悬浮 |
| $color-dropdown_item-bg-active | var(--semi-color-fill-1) | 下拉菜单项背景颜色 - 按下 |
| $color-dropdown_item_danger-text-default | var(--semi-color-danger) | 下拉菜单项背景颜色 - 悬浮 |
| $color-dropdown_item_secondary-text-default | var(--semi-color-secondary) | 二级菜单项文字颜色 |
| $color-dropdown_item_warning-text-default | var(--semi-color-warning) | 警告菜单项文字颜色 |
| $color-dropdown_item_tertiary-text-default | var(--semi-color-tertiary) | 第三菜单项文字颜色 |
| $color-dropdown_item_primary-text-default | var(--semi-color-primary) | 主要菜单项文字颜色 |
| $color-dropdown_item_disabled-text-default | var(--semi-color-disabled-text) | 禁用菜单项文字颜色 |
| $color-dropdown_item_disabled-bg-default | transparent | 禁用菜单项背景颜色 |
| $color-dropdown_seperator-bg-default | var(--semi-color-border) | 菜单项分隔线颜色 |
| $spacing-dropdown_icon-marginRight | 9px | 菜单项分隔线颜色 |
| $spacing-dropdown_seperator-marginY | $spacing-extra-tight | 菜单项分隔线垂直内边距 |
| $spacing-dropdown_seperator-marginX | 0 | 菜单项分隔线水平内边距 |
| $width-dropdown | 280px | 菜单最大宽度 |
| $size-dropdown-icon-width | 12px | 菜单项图标宽度 |
| $height-dropdown_seperator | 1px | 菜单项分隔线宽度 |
| $font-dropdown_item_active-fontWeight | 600 | 选中菜单项字重 |
| $filter-dropdown-bg | none |
FAQ
- 为什么 Dropdown 浮层在靠近屏幕边界宽度不够时,丢失宽度意外换行?
在 chromium 104 后 对于屏幕边界文本宽度不够时的换行渲染策略发生变化,详细原因可查看 issue #1022,semi 侧已经在 v2.17.0 版本修复了这个问题。