antd Segmented 尺寸体系详解:large / medium / small 三种规格的高度规范与实现原理
antd Segmented 尺寸体系详解large / medium / small 三种规格的高度规范与实现原理【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/GitHub_Trending/an/ant-designSegmented分段控制器是 antd 中用于“在多个互斥选项中单选一个”的控件。本指南基于 Segmented 组件演示文档 及其配套 size.tsx 演示源码系统讲解 Segmented 提供的large、medium、small三档尺寸——它们的高度分别为40px、32px与24px。阅读本文后你将掌握 Segmented 尺寸属性的完整用法、尺寸在 CSS-in-JS 中如何由 Design Token 推导落地以及如何通过 ConfigProvider 实现全站统一的尺寸继承。一、这个 Demo 在演示什么size.md是 Segmented 组件官方示例“Three sizes of Segmented”的说明文案中文与英文描述完全一致核心结论只有一句话antd 为Segmented /组件定义了三种尺寸大、中、小高度分别为40px、32px和24px。由于 antd 的 Demo 采用“Markdown 说明 .tsx可运行代码”的结构真正承载演示逻辑的是同目录下的 size.tsx。因此要完整理解本示例需要将两文件配合阅读。三种尺寸对应的取值关系如下size取值控件整体高度语义large40px大尺寸适合桌面端强调场景medium32px中尺寸默认值small24px小尺寸适合紧凑/密集布局二、最小可运行示例三档尺寸的写法size.tsx 的完整代码如下import React from react; import { Flex, Segmented } from antd; const App: React.FC () ( Flex gapsmall alignflex-start vertical Segmented sizelarge options{[Daily, Weekly, Monthly, Quarterly, Yearly]} / Segmented options{[Daily, Weekly, Monthly, Quarterly, Yearly]} / Segmented sizesmall options{[Daily, Weekly, Monthly, Quarterly, Yearly]} / /Flex ); export default App;逐行拆解这段演示代码sizelarge显式声明大尺寸 Segmented整体高度为 40px不传size中间这一行使用默认值medium高度为 32px。这也验证了size属性的默认行为在 index.en-US.md 的 API 表中标注为mediumsizesmall显式声明小尺寸 Segmented整体高度为 24px。外层用Flex gapsmall alignflex-start vertical将三个 Segmented 纵向排列并设置较小间距使三档高度差异在垂直方向上直观可见alignflex-start保证控件在交叉轴顶部对齐避免因高度不同而产生布局偏移。注意demo 中选项直接使用字符串数组[Daily, Weekly, ...]这属于options支持的SegmentedRawOption形式当需要禁用某项、附加图标或自定义 label 时可改用对象数组对象项支持value、label、icon、disabled、tooltip、className等字段详见 index.en-US.md。三、size属性速查根据 index.en-US.md 的 API 表格与尺寸相关的属性定义如下属性说明类型默认值size控件显示尺寸large|medium|smallmediumblock是否撑满父容器宽度每个选项等宽分配booleanfalsevertical垂直方向排布与orientation同时存在时orientation优先booleanfalse几点值得注意的边界情况size的类型约束在类型定义中size对应SizeType见下文该联合类型还历史性地包含middle值但它在 SizeContext.tsx 的注释中被标记为“已废弃将在 v7 移除请改用medium”因此新版应统一使用large/medium/small。size是组件级属性它作用于整个 Segmented 容器与全部选项而非单个选项。Demo 中的“三个 Segmented 各用一种尺寸”实际是三个独立组件实例。Segmented 从antd4.20.0起可用size属性为组件 API 的一部分index.en-US.md 顶部声明引入前请确认依赖版本满足该下限。四、尺寸落地的实现原理CSS 类名与高度推导了解“40/32/24”这三个数字从何而来比单纯记住取值更有价值。尺寸最终由三层机制共同决定。1. 尺寸类名的生成在 index.tsx 中customSize先经过useSizehook 合并出最终尺寸随后在拼接根节点 className 时按尺寸追加修饰类const mergedSize useSize(customSize); ... { [${prefixCls}-sm]: mergedSize small, [${prefixCls}-lg]: mergedSize large, }因此默认prefixCls即ant-segmented下渲染结果会带上ant-segmented-lglarge或ant-segmented-smsmallmedium 是默认值不追加任何尺寸类直接使用基础样式。这一断言可由单元测试印证index.test.tsx 中分别断言sizesmall渲染出ant-segmented-sm、sizelarge渲染出ant-segmented-lg同时 demo.test.ts.snap 快照也记录了 size demo 渲染出ant-segmented ant-segmented-lg与ant-segmented ant-segmented-sm的根节点结构。2. Design Token40/32/24 的来源三个数字并非写死在组件样式里的魔法值而是由 antd 主题系统的controlHeight系列 Token 推导而来medium32px对应基础 TokencontrolHeight其种子值在 seed.ts 中被定义为controlHeight: 32large40px对应controlHeightLGsmall24px对应controlHeightSM。这两个派生 Token 的计算逻辑集中在 genControlHeight.tscontrolHeightSM: controlHeight * 0.75, // 32 * 0.75 24 controlHeightXS: controlHeight * 0.5, // 16 controlHeightLG: controlHeight * 1.25, // 32 * 1.25 4040 32 × 1.25、24 32 × 0.75的推导关系一目了然。这意味着如果你通过 ConfigProvider 或 Token 定制改变了全局controlHeightSegmented 的三档高度会按同一套比例系数同步缩放而不是固定为 40/32/24。3. 尺寸样式细节在 style/index.ts 中选项 label 的行高按“控件高度减去两倍 track 内边距”计算const labelHeight token.calc(token.controlHeight).sub(token.calc(token.trackPadding).mul(2)).equal(); const labelHeightLG token.calc(token.controlHeightLG).sub(token.calc(token.trackPadding).mul(2)).equal(); const labelHeightSM token.calc(token.controlHeightSM).sub(token.calc(token.trackPadding).mul(2)).equal();其中trackPadding来自组件 Token 的prepareComponentToken取值为lineWidthBold见 style/index.ts即容器四周的内边距。结合容器自身padding: token.trackPadding最终控件整体高度恰好等于controlHeight32px 体系与 Demo 文案中的 40/32/24 完全吻合。除高度外大/小尺寸还会联动调整细节style/index.tsant-segmented-lglabel 字号切换为fontSizeLG项/滑块圆角提升一级borderRadius级整体视觉更饱满ant-segmented-smlabel 使用更紧凑的横向 paddingsegmentedPaddingHorizontalSM项/滑块圆角收窄borderRadiusXS级适配紧凑场景。滑块thumb与容器的圆角、字号、间距会随尺寸类同步变化保证三档规格在视觉上自成比例、而非简单拉伸。五、与 ConfigProvider 联动全局尺寸继承机制size默认值medium只是“没有显式指定时的兜底”。Segmented 的尺寸解析走的是 useSize.tsconst size React.useContextSizeType(SizeContext); const mergedSize React.useMemoT(() { if (!customSize) return size as T; // 未传 size → 读取全局 Context if (isString(customSize)) return customSize; // 显式字符串 → 直接采用 if (isFunction(customSize)) return customSize(size); // 函数 → 基于上下文计算 return size as T; }, [customSize, size]);其优先级为显式size 函数式size(ctx) ConfigProvider 全局尺寸 默认medium。也就是说单个Segmented sizesmall总是覆盖全局配置不写size时Segmented 会沿 React Context 读取上游SizeContextProvider的值该 Context 由ConfigProvider componentSize...注入Context 定义见 SizeContext.tsx。由此可低成本实现“全站统一尺寸”例如import { ConfigProvider, Segmented } from antd; const App () ( ConfigProvider componentSizesmall {/* 不写 size继承全局 small24px */} Segmented options{[Map, Transit, Satellite]} / {/* 显式 large局部覆盖仍为 40px */} Segmented sizelarge options{[Map, Transit, Satellite]} / /ConfigProvider );这使 Segmented 能与 Button、Input、Select 等同样消费controlHeight体系与componentSize的组件保持高度一致避免表单场景中“控件高度参差不齐”的问题这也是仓库中存在size-consistentdebug 演示、专门讨论“一致高度”的原因。六、测试如何保障尺寸行为仓库为 Segmented 的尺寸行为提供了两层自动化保障单元测试层index.test.tsx 覆盖sizesmall/sizelarge两种显式尺寸断言根节点分别携带ant-segmented-sm/ant-segmented-lg类防止类名映射被意外破坏Demo 快照层demo.test.ts.snap 与 demo-extend.test.ts.snap 会对size.tsx的真实渲染 DOM 拍快照锁定三档尺寸 demo 的结构不被回归。若你修改了 Segmented 尺寸相关的样式或类名逻辑运行对应测试仓库根目录执行单元测试即可校验是否破坏上述行为。七、实践建议确定默认尺寸时以场景为准medium32px与默认表单控件高度一致适合默认列表/表单small适合工具栏、筛选条等紧凑区域large适合移动端触控或作为页面主入口级分段器。多控件混排务必对齐尺寸体系当 Segmented 与 Input、Select、Button 并排时要么都写同一个size要么依赖 ConfigProvider 的componentSize统一注入避免视觉错位。图标类选项注意最小触控高度small下若使用“仅图标”选项需自行评估可点击区域是否符合可用性要求图标与文字共存时样式层已为-item-icon预留了与 label 的间距见 style/index.ts 的-icon *规则。想要整体更大/更小而不限于三档不要硬编码height应通过主题定制调整controlHeight及controlHeightLG/SMToken让 Segmented 与周边组件一起按比例缩放。综上antd Segmented 的“三档尺寸”是一条贯穿「demo 文案 → 组件类名 → 主题 Token」的完整链路开发者只需记住large/medium/small三个词而其背后的 40/32/24px 高度、字号圆角联动以及全局继承能力均由组件库统一维护。理解这条链路后无论是单点使用还是全站尺寸治理你都能做出符合 antd 设计语言规范的选择。【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/GitHub_Trending/an/ant-design创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考