- 前端
- UI组件
- 设计系统
【免费下载链接】semi-design
🚀A modern, comprehensive, flexible design system and React UI library, AI-friendly built-in.🎨Provide 3000+ Design Tokens, easy to build your design system. Make Semi Design to Any Design.🧑🏻💻 Design to Code in one click
Dropdown(下拉菜单)是 Semi Design 中基于 Tooltip 能力封装的展示类组件:它把任意触发元素(children)与一个"向下弹出"的菜单面板组合起来,默认鼠标移入即展开,也支持点击、聚焦、右键或完全自定义的触发方式。本文以 content/show/dropdown/index-en-US.md 为主线,结合packages/semi-ui/dropdown与packages/semi-foundation/dropdown的源码实现,带你掌握组件组合式 API、五种触发模式、JSON 菜单配置、键盘无障碍交互等完整实战能力,读完即可在业务中直接落地使用。
快速上手:引入与基本用法
Semi Design 的所有组件都从@douyinfe/semi-ui统一导出,Dropdown 也不例外:
import { Dropdown } from '@douyinfe/semi-ui';Dropdown 的核心使用模型可以概括为两句话:
- 触发元素:放在 Dropdown 的
children中,默认以 hover(鼠标移入)触发展开,可通过props.trigger修改为click、custom、contextMenu等值指定不同触发方式; - 面板内容:通过
render指定下拉框的具体内容——用Dropdown.Menu作为父容器,组合使用Dropdown.Item、Dropdown.Divider、Dropdown.Title。简单场景下只搭配Dropdown.Menu与Dropdown.Item即可,其他元素不是必须的。
其中Dropdown.Item通过disabled可以禁用某个选项,配置type可以展示不同颜色的文本,设置icon可以快速配置图标;更复杂的自定义结构,则可以通过children传入ReactNode自定义渲染。
下面是一个完整的综合示例,展示了分组标题、带图标菜单项、快捷键提示、分隔线以及五种文字类型(tertiary / warning / danger):
import React from 'react'; import { Dropdown, Button, HotKeys } from '@douyinfe/semi-ui'; import { IconBox, IconSetting, IconForward, IconRefresh, IconSearch, IconAlertCircle } from "@douyinfe/semi-icons"; import { IconToken } from "@douyinfe/semi-icons-lab"; function Demo() { return ( <Dropdown position="bottomLeft" render={ <Dropdown.Menu> <Dropdown.Title>Group 1</Dropdown.Title> <Dropdown.Item icon={<IconBox />}> Menu Item 1 <HotKeys style={{ marginLeft: 20 }} hotKeys={[HotKeys.Keys.Control, HotKeys.Keys.B]} content={['Ctrl', 'B']} ></HotKeys> </Dropdown.Item> <Dropdown.Item icon={<IconSetting />}> Menu Item 2 <HotKeys style={{ marginLeft: 20 }} hotKeys={[HotKeys.Keys.Control, HotKeys.Keys.V]} content={['Ctrl', 'V']} ></HotKeys> </Dropdown.Item> <Dropdown.Item disabled icon={<IconForward />}> Menu Item 3 <HotKeys style={{ marginLeft: 20 }} hotKeys={[HotKeys.Keys.Control, HotKeys.Keys.F3]} content={['Ctrl', 'F3']} ></HotKeys> </Dropdown.Item> <Dropdown.Divider /> <Dropdown.Title>Group 2</Dropdown.Title> <Dropdown.Item type="tertiary" icon={<IconRefresh />}>Tertiary text</Dropdown.Item> <Dropdown.Item type="warning" icon={<IconSearch />}> Warning Text </Dropdown.Item> <Dropdown.Item type="danger" icon={<IconAlertCircle />}>Danger text</Dropdown.Item> </Dropdown.Menu> } > <Button theme="outline" type="tertiary" icon={<IconToken />}> Hover Me </Button> </Dropdown> ); }从源码实现看(packages/semi-ui/dropdown/index.tsx),Dropdown是一个典型的组合型组件:它在类上静态挂载了四个子组件——static Menu = DropdownMenu、static Item = DropdownItem、static Divider = DropdownDivider、static Title = DropdownTitle,这也是你能直接写Dropdown.Menu、Dropdown.Item的原因;同时它通过DropdownContext(packages/semi-ui/dropdown/context.ts)向下传递level(嵌套层级)、showTick与trigger三个上下文值,供子组件消费。
嵌套使用:多级菜单
用户可以对Dropdown进行嵌套使用,此类情况适合具有多个子级选项的场景。嵌套时只需在某个Dropdown.Item外层再套一层Dropdown,并通过position控制子菜单展开方向(如rightTop、leftTop):
import React, { useMemo } from 'react'; import { Dropdown, Tag } from '@douyinfe/semi-ui'; function Demo() { const subDropdown = useMemo( () => ( <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> ), [] ); return ( <div style={{ margin: 100 }}> <Dropdown render={ <Dropdown.Menu> <Dropdown position={'rightTop'} render={subDropdown}> <Dropdown.Item>Menu Item 1</Dropdown.Item> </Dropdown> <Dropdown position={'leftTop'} render={subDropdown}> <Dropdown.Item>Menu Item 2</Dropdown.Item> </Dropdown> <Dropdown.Item>Menu Item 3</Dropdown.Item> </Dropdown.Menu> } > <Tag>Hover Me</Tag> </Dropdown> </div> ); }嵌套场景下的两个源码细节值得注意:
- 间距自适应:在 index.tsx 的
render()中,组件会读取context.level判断当前是否处于嵌套层级。当level > 0时,spacing若未显式传入数值,会被替换为numbers.NESTED_SPACING(2px);只有顶层才使用默认的numbers.SPACING(4px)。这一常量定义在 packages/semi-foundation/dropdown/constants.ts 中,保证子菜单与父菜单之间保持紧凑贴合。 - 嵌套点击事件差异:在 dropdownItem.tsx 中,当
context.level !== 1(即处于嵌套 Dropdown 内部)时,onClick会被改写为onMouseDown,并只在e.button === 0(鼠标左键)时触发——这是为了避免嵌套菜单在展开/收起交互中产生意外冒泡。
弹出位置控制
Dropdown 支持的位置与 Tooltip 完全一致(可参见 Tooltip 位置说明),常用的是"bottom"、"bottomLeft"、"bottomRight"这三种。位置集合POSITION_SET在 constants.ts 中直接从 Tooltip 的strings.POSITION_SET复用而来,组件默认位置为bottom。
import React from 'react'; import { Dropdown, Tag } from '@douyinfe/semi-ui'; function Demo() { return ( <div> <Dropdown position={'bottom'} render={ <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> } > <Tag>Bottom</Tag> </Dropdown> <br /> <br /> <Dropdown position={'bottomLeft'} render={ <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> } > <Tag>bottomLeft</Tag> </Dropdown> <br /> <br /> <Dropdown position={'bottomRight'} render={ <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> } > <Tag>bottomRight</Tag> </Dropdown> </div> ); }与位置相关的两个实用属性:
autoAdjustOverflow(默认true):弹出层被遮挡时是否自动调整方向;spacing(默认4):弹出层与 Trigger 元素(即 Dropdown children)的距离,单位 px,嵌套时默认收紧为 2px(见上文)。
此外,margin(v2.25.0 起支持,作用同 Tooltip margin)用于为弹出层计算溢出时增加冗余值,适合被 fixed 元素遮挡的场景,详见 issue #549。
触发方式:hover / focus / click / custom / contextMenu
Dropdown 默认是移入触发(hover),也可以通过获取焦点(focus)、点击(click)、自定义事件(custom)甚至鼠标右键(contextMenu,v2.42 起提供)触发菜单展开。五种触发值在 constants.ts 中定义为TRIGGER_SET: ['hover', 'focus', 'click', 'custom', 'contextMenu'],组件默认值为hover。
import React from 'react'; import { Dropdown, Tag, Input, Button } from '@douyinfe/semi-ui'; function Demo() { return ( <div> <Dropdown trigger={'hover'} position={'bottomLeft'} render={ <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> } > <Tag>Hover me</Tag> </Dropdown> <br /> <br /> <Dropdown trigger={'focus'} position={'bottomLeft'} render={ <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> } > <div style={{ border: '1px solid var(--semi-color-border)', borderRadius: 4, height: 36, width: 220 }}> Please use Tab to focus this div </div> </Dropdown> <br /> <br /> <Dropdown trigger={'click'} position={'bottomLeft'} render={ <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> } > <Button>Click me</Button> </Dropdown> </div> ); }focus触发时,建议给Dropdown.Menu设置tabindex={-1},让菜单容器自身可被聚焦,从而避免焦点在菜单内循环时丢失;custom触发则需要配合visible受控属性使用,由你完全掌控展开时机。右键菜单(contextMenu)的典型写法如下(来自同文档的中文版演示):
<Dropdown trigger={'contextMenu'} position={'bottomRight'} render={ <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> } > <Button theme="solid" type="secondary" style={{ marginBottom: 20 }}> Right click (ContextMenu) </Button> </Dropdown>从 foundation.ts 可以看出触发逻辑的底层实现:handleVisibleChange(visible)会先调用setPopVisible更新状态,再通过notifyVisibleChange回调onVisibleChange;当visible为真且trigger === 'click'时,会自动把焦点移到菜单的第一个菜单项(setFocusToFirstMenuItem)。而handleKeyDown则在 Trigger 上拦截键盘事件——Enter/Space直接event.target.click()激活,ArrowDown/ArrowUp分别把焦点移到第一个/最后一个菜单项。
另外两个与 hover 体验相关的延迟属性:
mouseEnterDelay(默认50):鼠标移入 Trigger 后延迟显示的时间(毫秒,仅 trigger 为 hover/focus 时生效);mouseLeaveDelay:鼠标移出弹出层后延迟消失的时间(毫秒,仅 trigger 为 hover/focus 时生效)。文档表格标注默认值为50,而当前仓库实现中 defaultProps 实际取的是 constants.ts 里的DEFAULT_LEAVE_DELAY(100ms),使用时建议按需显式设置。
disableFocusListener(v2.17.0 起)用于在trigger为hover时,不响应键盘聚焦弹出浮层事件(详见 issue #977)。
触发事件:菜单项上的鼠标事件
点击菜单项后可触发不同鼠标事件,支持onClick、onMouseEnter、onMouseLeave和onContextMenu四种:
import React from 'react'; import { Dropdown, Button, Toast } from '@douyinfe/semi-ui'; import { IconToken } from "@douyinfe/semi-icons-lab"; () => { return ( <Dropdown trigger={'click'} position={'bottomLeft'} render={ <Dropdown.Menu> <Dropdown.Item onClick={() => Toast.info({ content: 'You clicked me!' })}> 1: click me! </Dropdown.Item> <Dropdown.Item onMouseEnter={() => Toast.info({ content: 'Nice to meet you!' })}> 2: mouse enter </Dropdown.Item> <Dropdown.Item onMouseLeave={() => Toast.info({ content: 'See ya!' })}> 3: mouse leave </Dropdown.Item> <Dropdown.Item onContextMenu={() => Toast.info({ content: 'Right clicked!' })}> 4: right click </Dropdown.Item> </Dropdown.Menu> } > <Button theme="outline" type="tertiary" icon={<IconToken />}> Click Me </Button> </Dropdown> ); };这些事件在 dropdownItem.tsx 中统一处理:当Dropdown.Item未禁用(!disabled)时,onClick、onMouseEnter、onMouseLeave、onContextMenu四个事件才会被绑定到<li>元素上;禁用状态下所有鼠标事件都不会响应。此外,禁用项会渲染aria-disabled={disabled},菜单项本身使用role="menuitem"和tabIndex={-1}(详见下文无障碍章节)。
JSON 配置用法:通过 menu 属性快速构建菜单
除了 JSX 组合写法,还可以通过menu属性传入 JSON Array 快速配置下拉框菜单内容。每项通过node字段声明类型(title/item/divider),并支持透传对应子组件的全部属性(如type、active、onClick):
import React from 'react'; import { Dropdown, Button } from '@douyinfe/semi-ui'; import { IconToken } from "@douyinfe/semi-icons-lab"; function DropdownEvents() { const menu = [ { node: 'title', name: 'Group1' }, { node: 'item', name: 'primary1', type: 'primary', onClick: () => console.log('click primary') }, { node: 'item', name: 'secondary', type: 'secondary' }, { node: 'divider' }, { node: 'title', name: 'Group2' }, { node: 'item', name: 'tertiary', type: 'tertiary' }, { node: 'item', name: 'warning', type: 'warning', active: true }, { node: 'item', name: 'danger', type: 'danger' }, ]; return ( <Dropdown trigger={'click'} showTick position={'bottomLeft'} menu={menu}> <Button theme="outline" type="tertiary" icon={<IconToken />}> Click Me </Button> </Dropdown> ); }其底层实现在 index.tsx 的renderMenu()中:组件遍历menu数组,根据m.node的取值(title/item/divider)分别渲染为Dropdown.Title、Dropdown.Item与Dropdown.Divider,并自动剥离node、name字段、把其余属性透传给对应子组件,最终统一包裹进Dropdown.Menu。也就是说,JSON 写法与 JSX 组合写法最终渲染出的 DOM 结构完全一致,menu只是提供了一种更利于动态配置(例如由后端下发的菜单数据)的声明式入口。
API 参考
Dropdown
| 属性 | 说明 | 类型 | 默认值 | 版本 |
|---|---|---|---|---|
| autoAdjustOverflow | 弹出层被遮挡时是否自动调整方向 | boolean | true | |
| className | 下拉弹层外层样式类名 | string | ||
| closeOnEsc | 在 trigger 或弹出层按 Esc 键是否关闭面板,受控(visible 受控)时不生效 | boolean | true | 2.13.0 |
| children | 触发弹出层的 Trigger 元素 | ReactNode | ||
| clickToHide | 在弹出层内点击时是否自动关闭弹出层 | boolean | - | |
| contentClassName | 下拉菜单根元素类名 | string | ||
| disableFocusListener | trigger 为hover时,不响应键盘聚焦弹出浮层事件(详见 issue #977) | boolean | true | 2.17.0 |
| keepDOM | 关闭时是否保留内部组件 DOM 不销毁 | boolean | false | 2.31.0 |
| getPopupContainer | 指定父级 DOM,弹层将渲染至该 DOM 中,自定义时需设置position: relative。这会改变浮层 DOM 树位置,但不会改变视图渲染位置 | function():HTMLElement | () => document.body | |
| margin | 弹出层计算溢出时的冗余值,用于被 fixed 元素遮挡的场景(详见 issue #549),作用同 Tooltip margin | object|number | 2.25.0 | |
| mouseEnterDelay | 鼠标移入 Trigger 后延迟显示的时间(毫秒,仅 trigger 为 hover/focus 时生效) | number | 50 | |
| mouseLeaveDelay | 鼠标移出弹出层后延迟消失的时间(毫秒,仅 trigger 为 hover/focus 时生效) | number | 50 | |
| menu | 通过传入 JSON Array 快速配置 Dropdown 内容 | Array<DropdownMenuItem> | [] | - |
| position | 弹出菜单的位置,常用:bottom、bottomLeft、bottomRight,更多详见 Tooltip 位置 | string | 'bottom' | |
| render | 弹出层的内容,由Dropdown.Menu及Dropdown.Item、Dropdown.Title构成 | ReactNode | ||
| rePosKey | 更新该项的值可手动触发弹出层的重新定位 | string | number | ||
| spacing | 弹出层与 Trigger 元素(即 Dropdown children)的距离,单位 px | number | 4 | |
| style | 弹出层内联样式 | object | ||
| showTick | 是否自动在 active 的 Dropdown.Item 项左侧展示表示选中的勾 | boolean | false | - |
| stopPropagation | 是否阻止弹出层上的点击事件冒泡 | boolean | false | - |
| trigger | 触发下拉的行为,可选hover、focus、click、custom、contextMenu(v2.42 起提供) | string | 'hover' | |
| visible | 是否显示菜单,需配合 trigger custom 使用 | boolean | ||
| zIndex | 弹出层 z-index 值 | number | 1050 | |
| onClickOutSide | 当弹出层处于展示状态,点击非 Children、非弹出层内部区域时的回调(仅 trigger 为 custom、click 时有效) | function(e:event) | 2.1.0 | |
| onEscKeyDown | 在 trigger 或弹出层按 Esc 键时调用 | function(e:event) | 2.13.0 | |
| onVisibleChange | 弹出层显示状态改变时的回调 | function(visible: boolean) |
补充说明:Dropdown的defaultProps在 index.tsx 中定义,除上表外还包括zIndex取 Tooltip 的DEFAULT_Z_INDEX(即表中标注的 1050)、closeOnEsc: true、onVisibleChange与onEscKeyDown默认为空函数(noop)、motion: true等。
Dropdown.Menu
| 属性 | 说明 | 类型 | 默认值 | 版本 |
|---|---|---|---|---|
| style | 下拉弹层菜单样式 | object | - | |
| className | 下拉弹层菜单样式类名 | string | - | |
| children | 下拉弹层菜单包裹的子元素,一般为Dropdown.Item或Dropdown.Title | ReactNode |
Dropdown.Item
| 属性 | 说明 | 类型 | 默认值 | 版本 |
|---|---|---|---|---|
| active | 当前项是否处于激活态,激活态时左侧有 √,字体加粗、颜色加深。当 Dropdown 的 showTick 为 false 时,即使 Item 的 active 为 true,√ 也不会展示 | boolean | false | |
| className | 样式类名 | string | ||
| disabled | 是否禁用菜单 | boolean | false | |
| icon | 图标,展示在左侧 | ReactNode | - | |
| style | 内联样式 | object | ||
| type | 类型,可选值:primary、secondary、tertiary、warning、danger | string | "tertiary" | |
| onClick | 单击触发的回调事件 | function | ||
| onContextMenu | 鼠标右键触发的回调事件 | function | - | |
| onMouseEnter | MouseEnter 触发的回调事件 | function | ||
| onMouseLeave | MouseLeave 触发的回调事件 | function |
type的可选值与默认值同样定义在 constants.ts 的ITEM_TYPE: ['primary', 'secondary', 'tertiary', 'warning', 'danger']中。showTick的实现细节在 dropdownItem.tsx 中:当showTick && active时渲染实心IconTick;当showTick && !active时渲染一个color: 'transparent'的透明IconTick占位,保证菜单项文字在有无选中态之间不产生位移抖动。
Dropdown.Title
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| className | 样式类名 | string | "" |
| style | 内联样式 | object | {} |
DropdownMenuItem
| 属性 | 说明 | 类型 |
|---|---|---|
| node | 菜单类型:title、item、divider | string |
| name | 菜单内容(标题或 Item 的文本) | string |
| 其他属性与 Title、Item、Divider 的属性对应 |
无障碍(Accessibility)
ARIA
Dropdown.Menu的role被设置为menu,aria-orientation被设置为vertical;Dropdown.Item的role被设置为menuitem。
这两条规则直接体现在渲染层:dropdownMenu.tsx 中<ul role="menu" aria-orientation="vertical">,dropdownItem.tsx 中<li role="menuitem" tabIndex={-1} aria-disabled={disabled}>。
键盘与焦点
- Dropdown 的触发器可被聚焦,目前支持 3 种触发方式:
- 触发方式设置为 hover 或 focus 时:鼠标悬浮或聚焦时打开 Dropdown,打开后用户可以使用
下箭头将焦点移动到 Dropdown 内(对应 foundation.ts 中handleKeyDown对ArrowDown的处理); - 触发方式设置为 click 时:点击触发器或聚焦时使用
Enter或Space键打开 Dropdown,此时焦点自动聚焦到 Dropdown 中的第一个非禁用项上(handleVisibleChange中的setFocusToFirstMenuItem);
- 触发方式设置为 hover 或 focus 时:鼠标悬浮或聚焦时打开 Dropdown,打开后用户可以使用
- 当焦点位于 Dropdown 内的菜单项上时(对应 menuFoundation.ts 的
onMenuKeydown):- 键盘用户可以使用
上箭头或下箭头切换可交互元素; - 使用
Enter键或Space键可以激活聚焦的菜单项,若菜单项绑定了onClick,事件会被触发; - 按下可打印字符(字母/数字等)时,会按字符首字母快速定位菜单项(
setFocusByFirstCharacter结合findIndexByCharacter实现);
- 键盘用户可以使用
- 键盘用户可以通过按
Esc关闭 Dropdown,关闭后焦点返回到触发器上(closeOnEsc默认开启,且关闭时returnFocusOnClose={true}会把焦点还给 Trigger);custom触发模式下Esc还会通过getMenuButton找回触发按钮并聚焦; - 键盘交互暂未完整支持嵌套场景。
提示:菜单项内部的键盘事件统一由
Dropdown.Menu的onKeyDown分发(onMenuKeydown),而 Trigger 上的Enter/Space/方向键则由 Dropdown 根组件的onKeyDown(foundation.handleKeyDown)处理,两层分工明确,且都刻意保留了事件冒泡,避免影响 Trigger 上自带的输入框按键逻辑。
文案规范
- 下拉框内选项内容需要表述准确且包含信息,使用户在浏览时更容易在选项间做出选择;
- 使用语句式的大小写,并且简洁明了地书写选项;
- 如果是动作选项,使用动词或动词短语来描述用户选择该选项后会发生的动作。例如 "Move"、"Log time"、"Hide labels";
- 不使用介词。
| ✅ 推荐用法 | ❌ 不推荐用法 |
|---|---|
| Add text / Add link / Add image / Add video | Add a text / Add a link / Add a image / Add a video |
设计令牌与主题定制
下拉菜单的视觉样式完全由 Semi Design 的设计令牌(Design Tokens)驱动。<DesignToken/>会在文档站点上自动渲染当前组件全部可用的设计令牌,包括颜色(如--semi-color-primary、--semi-color-danger)、圆角(--semi-radius-*)、阴影、字体大小与间距等。想要深度定制时,可以直接在 semi-theme-default 中查找对应的 SCSS 变量,并结合 主题定制指南 将其映射为品牌化主题;菜单项的样式类结构(如semi-dropdown-item、semi-dropdown-item-disabled、semi-dropdown-item-selected)定义在 packages/semi-foundation/dropdown/dropdown.scss 中,可作为自定义 CSS 的锚点。
常见问题 FAQ
为什么 Dropdown 浮层在靠近屏幕边界宽度不够时,会丢失宽度意外换行?
在 Chromium 104 之后,浏览器对屏幕边界处文本宽度不足时的换行渲染策略发生了变化(详细原因见 issue #1022),导致浮层可能出现意外的换行行为。Semi Design 已经在 v2.17.0 版本修复了该问题,升级到该版本及以上即可避免。
源码结构速览
如果你想继续深入阅读 Dropdown 的实现,仓库中相关的关键文件如下:
- 组件渲染层:packages/semi-ui/dropdown/index.tsx(Dropdown 主组件)、dropdownMenu.tsx、dropdownItem.tsx、dropdownTitle.tsx、dropdownDivider.tsx、context.ts;
- 行为与状态层:packages/semi-foundation/dropdown/foundation.ts(显隐与 Trigger 键盘逻辑)、menuFoundation.ts(菜单内键盘导航)、constants.ts(位置/触发/类型常量与默认间距);
- 样式层:packages/semi-foundation/dropdown/dropdown.scss、variables.scss、animation.scss;
- 测试用例:packages/semi-ui/dropdown/test/dropdown.test.js 覆盖了显隐控制、事件回调、键盘交互等核心行为,是理解组件契约的很好补充。
- 前端
- UI组件
- 设计系统
【免费下载链接】semi-design
🚀A modern, comprehensive, flexible design system and React UI library, AI-friendly built-in.🎨Provide 3000+ Design Tokens, easy to build your design system. Make Semi Design to Any Design.🧑🏻💻 Design to Code in one click
相关推荐
Semi Design Notification 组件完全指南:API 用法、底层实现与无障碍实践
Semi Design Notification 组件完全指南:API 用法、底层实现与无障碍实践 Notification 是 Semi Design( @d
前端UI组件设计系统Ant Design Dropdown 下拉菜单组件完全指南:API、交互模式与源码解析
Ant Design Dropdown 下拉菜单组件完全指南:API、交互模式与源码解析 Dropdown 是 Ant Design 导航体系中的核心组件,用于
前端UI组件设计系统Ant Design Dropdown 按钮式下拉菜单(Button with dropdown menu)组合实战指南
Ant Design Dropdown 按钮式下拉菜单(Button with dropdown menu)组合实战指南 本指南围绕 ant design 官方
前端UI组件设计系统
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考