尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

用 ConfigProvider 主题 Token 在 antd 中还原 V4 风格 Menu:menu-v4 示例深度拆解

用 ConfigProvider 主题 Token 在 antd 中还原 V4 风格 Menu:menu-v4 示例深度拆解 用 ConfigProvider 主题 Token 在 antd 中还原 V4 风格 Menumenu-v4 示例深度拆解【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/ant/ant-designAnt Design 从 v5 起全面切换到 CSS-in-JS 的 Design Token 体系Menu 组件的视觉细节也随之调整。对于希望沿用 v4 时代方角、无内边距、左侧竖条指示导航风格的老项目或设计规范官方在components/menu/demo/menu-v4.tsx中给出了一个标为 debug 的示例对应文档 components/menu/demo/menu-v4.md仅通过ConfigProvider覆盖 8 个组件级 Token即可在 v5 组件上完整还原 v4 的 Menu 观感。读完本文你将掌握这套 Token 的每个取值含义、其背后的样式生成原理以及如何按需微调成自己的类 v4导航样式。V4 风格 Menu 的视觉特征在动手配置之前先明确V4 样式到底指什么。对比当前版本 Menu 的默认外观圆角菜单项、左右留白、hover 灰底V4 风格主要包含以下特征直角布局菜单项与子菜单项不设圆角零横向外边距菜单项横向紧贴容器没有margin-inline留白左侧选中指示条inline 模式下选中项左侧有一条约 3px 的竖条V4 经典墨条品牌蓝交互色hover 与选中文字均为#1890ffV4 主色浅蓝选中底色选中项背景为#e6f7ffV4 的item-selected-bghover 无底色变化紧凑密度菜单项高度、间距沿用 V4 的紧凑规格。这些特征全部可以通过 Menu 组件级 Token 精确还原无需写任何自定义 CSS。完整示例直接可运行的还原代码以下代码完整来自官方 democomponents/menu/demo/menu-v4.tsx它定义了一份包含普通项、带图标项、二级与三级子菜单、外部链接项的数据并在ConfigProvider中集中覆盖 Menu Tokenimport React, { useState } from react; import { AppstoreOutlined, CalendarOutlined, LinkOutlined, MailOutlined, SettingOutlined, } from ant-design/icons; import { ConfigProvider, Menu, Switch, Typography } from antd; import type { MenuProps } from antd; type MenuItem RequiredMenuProps[items][number]; const items: MenuItem[] [ { key: 1, icon: MailOutlined /, label: Navigation One, }, { key: 2, icon: CalendarOutlined /, label: Navigation Two, }, { key: sub1, icon: AppstoreOutlined /, label: Navigation Two, children: [ { key: 3, label: ( Typography.Text ellipsis Ant Design, a design language for background applications, is refined by Ant UED Team /Typography.Text ), }, { key: 4, label: Option 4 }, { key: sub1-2, label: Submenu, children: [ { key: 5, label: Option 5 }, { key: 6, label: Option 6 }, ], }, ], }, { key: sub2, label: Navigation Three, icon: SettingOutlined /, children: [ { label: Option 7, key: 7 }, { label: Option 8, key: 8 }, { label: Option 9, key: 9 }, { label: Option 10, key: 10 }, ], }, { key: link, icon: LinkOutlined /, label: ( a hrefhttps://ant.design target_blank relnoopener noreferrer Ant Design /a ), }, ]; const App: React.FC () { const [mode, setMode] useStatevertical | inline(inline); const changeMode (value: boolean) { setMode(value ? vertical : inline); }; return ( Switch onChange{changeMode} / Change Mode br / br / ConfigProvider theme{{ components: { Menu: { itemBorderRadius: 0, subMenuItemBorderRadius: 0, itemHoverColor: #1890ff, itemSelectedColor: #1890ff, itemSelectedBg: #e6f7ff, activeBarWidth: 3, itemMarginInline: 0, itemHoverBg: transparent, }, }, }} Menu style{{ width: 256 }} defaultSelectedKeys{[1]} defaultOpenKeys{[sub1]} mode{mode} items{items} / /ConfigProvider / ); }; export default App;要点解读示例默认modeinline通过Switch可在inline与vertical之间即时切换用于观察两种布局下同一套 Token 的效果defaultSelectedKeys{[1]}与defaultOpenKeys{[sub1]}用于指定初始选中项与展开的子菜单对应 Menu API 文档 中的同名属性items使用RequiredMenuProps[items][number]推导类型保证每个菜单项的结构合法菜单项 label 中可以直接渲染Typography.Text、a链接等任意 ReactNode这也是 Menu items 泛型设计的典型用法。八个 Token 逐一解析V4 还原的关键配置下表汇总了示例中 8 个 Token 的作用、示例取值以及它们在当前仓库源码中的默认值默认值取自 components/menu/style/index.ts 的prepareComponentTokenToken作用示例取值源码默认值默认值来源itemBorderRadius菜单项圆角0borderRadiusLGstyle/index.tssubMenuItemBorderRadius弹出子菜单内菜单项圆角0borderRadiusSMstyle/index.tsitemHoverColor菜单项 hover 文字颜色#1890ffcolorTextstyle/index.tsitemSelectedColor选中项文字颜色#1890ffcolorPrimarystyle/index.tsitemSelectedBg选中项背景色#e6f7ffcontrolItemBgActivestyle/index.tsactiveBarWidthinline 模式选中指示条宽度30不显示指示条style/index.tsitemMarginInline菜单项横向外边距0marginXXSstyle/index.tsitemHoverBg菜单项 hover 背景色transparentcolorBgTextHoverstyle/index.ts可以发现V4 还原的核心逻辑是把 v5 引入的新视觉特征全部归零或替换圆角归零itemBorderRadius与subMenuItemBorderRadius置为0恢复 V4 的直角菜单项注意后者只作用于弹出层中的子菜单项见 style/index.ts交互色替换itemHoverColor、itemSelectedColor固定为 V4 主色#1890ff不随colorPrimary主题变量漂移选中态重塑itemSelectedBg使用 V4 经典的浅蓝#e6f7ffitemHoverBg置为transparent去掉 v5 的 hover 灰底只保留文字变蓝指示条开启activeBarWidth: 3激活 inline 模式左侧竖条itemMarginInline: 0让竖条与容器边缘对齐形成 V4 的贴边墨条。源码原理这些 Token 如何驱动样式生成activeBarWidthinline 模式的左侧竖条在 components/menu/style/theme.ts 中inline 模式为每个-item生成了一个::after伪元素[${componentCls}-item]: { position: relative, ::after: { position: absolute, insetBlock: 0, insetInlineEnd: 0, borderInlineEnd: ${unit(activeBarWidth)} solid ${itemSelectedColor}, transform: scaleY(0.0001), opacity: 0, ... }, },也就是说竖条本质上是一条border-inline-end宽度正是activeBarWidth颜色跟随itemSelectedColor。默认未选中时通过scaleY(0.0001)与opacity: 0隐藏选中时切换为scaleY(1)与opacity: 1并配合motionDurationMid的过渡实现 V4 时代的滑出动效。示例将宽度设为3并令itemSelectedColor为#1890ff即还原 V4 的经典蓝条。值得注意的是activeBarWidth的默认值是0见 style/index.ts这正是 v5 默认不显示左侧指示条的原因——手动赋值为3是开启该特性的开关。itemMarginInline影响菜单项实际宽度在 components/menu/style/vertical.ts 中inline/vertical 模式下的菜单项宽度并非简单的100%而是由itemWidth决定[${componentCls}-item, ${componentCls}-submenu-title]: { ... marginInline: itemMarginInline, width: itemWidth, },itemWidth的推导逻辑见 style/index.tsitemWidth: activeBarWidth ? calc(100% ${activeBarBorderWidth}px) : calc(100% - ${itemMarginInline * 2}px),当activeBarWidth为0v5 默认时菜单项宽度为100%减去两侧itemMarginInline即默认marginXXS4px的左右留白当启用指示条后宽度变为calc(100% activeBarBorderWidth)配合itemMarginInline: 0竖条能够紧贴容器右缘实现 V4 的贴边效果。这解释了为什么示例必须同时设置activeBarWidth: 3与itemMarginInline: 0二者共同作用才能得到容器内满宽 右缘竖条的 V4 形态。圆角与背景作用于不同层级itemBorderRadius直接作用于-item与-submenu-title见 style/index.tssubMenuItemBorderRadius只作用于弹出层popup中的菜单项style/index.ts所以示例将两者都设为0以保证所有层级的菜单项都是直角itemHoverBg仅在非水平模式下、且未选中/未展开的项上生效theme.ts置为transparent后 hover 只剩文字变色与 V4 行为一致选中态背景itemSelectedBg通过 ${componentCls}-item-selected的backgroundColor生效theme.ts。注意事项与扩展建议作用范围Token 通过ConfigProvider注入会影响该 Provider 子树内所有Menu 实例包括子菜单弹出层、以及 Layout Sider 等组合场景。如需全局统一类 v4导航可直接把这段theme.components.Menu配置放到应用根部的ConfigProvider若只想影响局部可像示例一样缩小 Provider 包裹范围。debug 标记该示例在 Menu 文档 中被标记为 debug属于风格兼容演示而非推荐默认样式使用时请确认团队设计规范确实需要 V4 观感。暗色主题若同时使用themedark的 Menu暗色 Token如darkItemBg、darkItemSelectedBg等见 style/index.ts仍会接管颜色上述亮色配置需另行针对暗色 Token 调整。继续微调在还原基础上可进一步调整itemHeightV4 更紧凑的 40px 高度、itemPaddingInline、groupTitleColor等 Token完整清单见 style/index.ts 的ComponentToken定义即可得到自定义密度与配色同一文件中的旧版 Token 别名如colorItemTextSelected、radiusItem已标记 deprecated新代码应使用上述标准名称。验证方式该 demo 同时被快照测试覆盖见components/menu/__tests__/__snapshots__/demo.test.tsx.snap中的menu-v4.tsx用例修改 Token 后可通过npm test运行组件测试确认样式输出无回归。小结V4 风格 Menu 的还原不需要任何 hack 或自定义 CSSactiveBarWidth、itemMarginInline、itemBorderRadius、itemSelectedBg等 8 个组件 Token 的组合就能完整复刻直角贴边 左侧蓝条 蓝色交互 浅蓝选中的经典观感。理解 theme.ts 中指示条伪元素与itemWidth的推导逻辑vertical.ts还能让你在此基础上自由派生属于自己的菜单风格。【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/ant/ant-design创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表