前端UI组件设计系统【免费下载链接】semi-designA 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项目地址https://gitcode.com/gh_mirrors/se/semi-design点击查看免费下载本指南以 Semi Designdouyinfe/semi-ui开源仓库中 Switch 开关组件的官方文档为主体系统讲解该组件的引入方式、受控/非受控用法、尺寸与状态禁用、加载中、内嵌文本配置、完整 API、无障碍ARIA 与键盘操作及文案规范并结合仓库源码组件层、foundation 层、SCSS 主题变量与测试用例深入解析其底层实现原理。读完本文你将能够在 Semi Design 项目中正确、规范地使用 Switch并理解其 原生 checkbox ARIA 增强 的实现机制为定制主题或排查交互问题提供依据。组件概览与适用场景Switch 是 Semi Design 中用于切换两种互斥状态的交互组件官方文档定义为an interactive form used to switch two mutually exclusive states。与 Checkbox 的多选一语义不同Switch 表达的是一种即时生效的二元状态切换常见于设置面板、偏好开关、权限控制等场景例如开启/关闭消息通知、暗色模式切换、自动续费开关等。在 Semi Design 组件树中Switch 属于输入类Input组件位于 content/input/switch/index-en-US.md其组件实现位于 packages/semi-ui/switch/index.tsx底层逻辑foundation位于 packages/semi-foundation/switch/foundation.ts样式与主题变量位于 packages/semi-foundation/switch/switch.scss 与 packages/semi-foundation/switch/variables.scss。引入方式从douyinfe/semi-ui按需引入即可import { Switch } from douyinfe/semi-ui;Semi Design 采用组件级分包管理monorepo 结构Switch 的 UI 实现、foundation 逻辑与 SCSS 样式分属不同包但对外统一由semi-ui聚合导出使用者无需关心底层拆分。基本用法监听状态与设定初始选中你可以通过onChange监听状态变化通过defaultChecked非受控或受控的checked制定选中状态。官方建议通过aria-label描述该 Switch 的具体作用以保证可访问性import React from react; import { Switch } from douyinfe/semi-ui; () ( div Switch onChange{(v, e) console.log(v)} aria-labela switch for demo/Switch br / Switch defaultChecked{true} onChange{(v, e) console.log(v)} aria-labela switch for demo/Switch /div );要点说明onChange回调签名是(checked: boolean, e: React.ChangeEventHTMLInputElement) void第一个参数即最新的选中值第二个参数是原生 change 事件见 packages/semi-ui/switch/index.tsx 中SwitchProps的类型定义。defaultChecked仅在组件首次挂载时生效用于非受控场景后续状态由组件内部维护。未指定任何选中属性时Switch 默认处于未选中态checked的默认值为false。受控组件完全由外部状态驱动组件是否选中完全取决于传入的checked值配合onChange回调函数使用。这是典型的受控写法import React from react; import { Switch } from douyinfe/semi-ui; () { const [checked, setChecked] useState(true); const onChange (checked) { setChecked(checked); }; return ( Switch checked{checked} aria-labela switch for demo onChange{onChange} / ); };受控/非受控的底层判定逻辑从 foundation 源码可以看到 Semi 如何区分两种模式packages/semi-foundation/switch/foundation.ts 的handleChangehandleChange(checked: boolean, e: any): void { const propChecked this.getProps().checked; const isControlledComponent typeof propChecked ! undefined; if (isControlledComponent) { this._adapter.notifyChange(checked, e); } else { this._adapter.setNativeControlChecked(checked); this._adapter.notifyChange(checked, e); } }受控模式只要外部传入了checked属性typeof propChecked ! undefined点击开关时只回调onChange不直接修改内部状态最终选中态由父组件通过新checked值决定。非受控模式内部先更新nativeControlChecked状态再通知onChange。组件层在componentDidUpdate中会监听checked属性变化并同步内部状态this.foundation.setChecked(this.props.checked)保证受控模式外部状态回写生效。仓库测试 packages/semi-ui/switch/test/switch.test.js 的 switch controlled mode 用例也验证了这一行为模拟 change 事件后onChange被调用一次外部更新checked后组件 DOM 呈现选中态。尺寸Size通过size属性指定尺寸可选值为large、default、small默认值为default该枚举定义在 packages/semi-foundation/switch/constants.ts 的SIZE_MAP: [default, small, large]组件 propTypes 通过PropTypes.oneOf约束。import React from react; import { Switch } from douyinfe/semi-ui; () ( div Switch sizesmall aria-labela switch for demo/Switch Switch defaultChecked{true} sizesmall aria-labela switch for demo/Switch Switch sizesmall loading aria-labela switch for demo / Switch sizesmall loading defaultChecked{true} aria-labela switch for demo / br / br / Switch/Switch Switch defaultChecked{true}/Switch Switch loading / Switch loading defaultChecked{true} / br / br / Switch sizelarge/Switch Switch defaultChecked{true} sizelarge/Switch Switch sizelarge loading / Switch sizelarge loading defaultChecked{true} / /div );三种尺寸的实际几何尺寸来自主题变量结合 packages/semi-foundation/switch/variables.scss 的 SCSS 变量三种尺寸的实体规格如下尺寸开关宽 × 高滑块直径选中态滑块位移圆角small26px × 16px12px11px高度的一半8pxdefault40px × 24px18px18px高度的一半12pxlarge54px × 32px24px26px高度的一半16px相关变量包括$width-switch、$width-switch_large、$width-switch_small、$spacing-switch_checked-translateX等且圆角统一定义为$radius-switch: $height-switch * 0.5胶囊造型。滑块按压时还会延展$width-switch_knob_expand: 6pxlarge 为 10px、small 为 2px配合 200ms 的transform过渡$motion-switch-transitionDuration: 200ms形成按压反馈的弹性动画。禁用状态Disabled设置disabled后开关不可交互未选中时以透明背景 描边呈现选中时使用禁用色填充import React from react; import { Switch } from douyinfe/semi-ui; () ( div Switch disabled aria-labela switch for demo/Switch br / Switch disabled checked{true} aria-labela switch for demo/Switch /div );实现层面packages/semi-ui/switch/index.tsx 的render根节点加上semi-switch-disabledclassSCSS 中cursor: not-allowed并使用--semi-color-border描边见 packages/semi-foundation/switch/switch.scss。原生 checkbox 同时被设置disabled与pointer-events: none阻断一切点击事件。组件在componentDidUpdate中监听disabled属性变化并同步nativeControlDisabled内部状态。仓库测试 packages/semi-ui/switch/test/switch.test.js 的 switch disabled when props.disabled 用例验证了disabled从true切到false时semi-switch-disabledclass 与内部nativeControlDisabled状态同步移除。带文本checkedText / uncheckedText可以通过checkedText与uncheckedText设置开关内嵌文本开启时展示内容 / 关闭时展示内容。注意此项功能在最小的开关即sizesmall时无效。import React from react; import { Switch } from douyinfe/semi-ui; () ( div Switch checkedTexton uncheckedTextoff / Switch checkedText uncheckedText〇 style{{ marginLeft: 5 }} / br / br / Switch defaultChecked checkedTexton uncheckedTextoff / Switch defaultChecked checkedText uncheckedText〇 style{{ marginLeft: 5 }} / br / br / Switch checkedTexton uncheckedTextoff sizelarge / Switch checkedText uncheckedText〇 sizelarge style{{ marginLeft: 5 }} / br / br / Switch defaultChecked checkedTexton uncheckedTextoff sizelarge / Switch defaultChecked checkedText uncheckedText〇 sizelarge style{{ marginLeft: 5 }} / /div );实现细节见 packages/semi-ui/switch/index.tsx 的renderconst showCheckedText checkedText nativeControlChecked size ! small; const showUncheckedText uncheckedText !nativeControlChecked size ! small;只有size ! small时才会渲染文本节点semi-switch-checked-text/semi-switch-unchecked-text这正是文档所说small 尺寸下无效的代码依据。文本节点带有x-semi-prop标记便于 Semi 的 Design to Code 能力识别。SCSS 中文本区域宽 20pxlarge 尺寸为 26px开启态文本颜色为--semi-color-white关闭态为--semi-color-text-2。推荐将文本说明放在 Switch 外部相比于通过checkedText与uncheckedText设置内嵌文本官方更推荐将文本说明放置在 Switch 外部并用开关状态驱动外部文案import React, { useState } from react; import { Switch, Typography } from douyinfe/semi-ui; () { const [open, setOpen] useState(); const { Title } Typography; return ( div style{{ display: flex, alignItems: center }} Title heading{6} style{{ margin: 8 }} {open ? Open : Closed} /Title Switch checked{open} onChange{setOpen} / /div ); };这种做法的优势长文本不受开关尺寸限制、布局更灵活、文案更清晰且能天然获得可读的标签有利于无障碍。加载中状态loading通过设置loadingtrue开启加载中状态。加载时开关内部渲染 Spin 加载图标而非滑块同时禁用交互import React from react; import { Switch } from douyinfe/semi-ui; () ( div Switch loading / br / Switch loading defaultChecked{true} / /div );实现层面packages/semi-ui/switch/index.tsxloading时用Spin替换滑块节点Spin 尺寸跟随开关尺寸size default ? middle : size并套用semi-switch-loading-spinclass。原生 checkbox 的disabled同时被设为nativeControlDisabled || loading即加载中同样不可点击。SCSS 中加载态背景使用--semi-color-fill-1关闭态/--semi-color-success-hover开启态spin 颜色为--semi-color-white并按尺寸10px / 18px / 28px缩放图标见 packages/semi-foundation/switch/switch.scss。API 参考以下为 Switch 完整 API 表来源content/input/switch/index-en-US.md属性说明类型默认值版本aria-label用来给当前元素加上的标签描述用于屏幕上没有可见文本标签的场景提升可访问性string2.2.0aria-labelledby表明某些元素的 id 是某一对象的标签用于建立控件组与其标签之间的联系提升可访问性string2.2.0className外层元素的 CSS 类名stringchecked指示当前是否选中配合 onChange 使用受控booleanfalsecheckedText打开时展示的内容size 为 small 时无效ReactNodedefaultChecked组件挂载初始化时是否选中非受控booleanfalsedisabled是否禁用booleanfalseloading设置加载状态booleanfalseonChange变化时回调函数function(checked: boolean)onMouseEnter鼠标移入时回调function()onMouseLeave鼠标移出时回调function()size尺寸可选值large、default、smallstringdefaultstyle内联样式objectuncheckedText关闭时展示的内容size 为 small 时无效ReactNode说明组件层还支持aria-describedby、aria-errormessage、aria-invalid、id等属性见 packages/semi-ui/switch/index.tsx 的SwitchProps与propTypes这些属性会直接透传到内部原生 checkbox 上属于文档 API 表之外的扩展能力。默认值disabled: false、onChange: noop、loading: false、onMouseEnter: noop、onMouseLeave: noop、size: default由组件defaultProps提供并可通过全局配置覆盖getDefaultPropsFromGlobalConfig。无障碍AccessibilitySemi Design 对 Switch 的无障碍支持包含 ARIA 语义与键盘操作两个层面。ARIASwitch 具有switchrole当checked为true时aria-checked会被自动设置为true反之亦然。作为表单控件Switch 应该带有 Label当你使用Form.Switch时Label 会被自动带上。如果你单独使用 Switch建议使用aria-label描述当前标签作用。这些语义在 packages/semi-ui/switch/index.tsx 的渲染逻辑中直接体现内部渲染一个typecheckbox的原生 input视觉上透明覆盖显式设置roleswitch、aria-checked{nativeControlChecked}并透传aria-label/aria-labelledby/aria-describedby/aria-invalid/aria-errormessage/aria-disabled。因此虽然视觉上看到的是自定义轨道与滑块但屏幕阅读器读到的是语义完整的 switch 控件。键盘和焦点键盘用户可以使用Tab及Shift Tab切换焦点。聚焦时可以通过Space键切换开启或关闭状态原生 checkbox 的键盘行为 roleswitch语义组合而成。焦点视觉反馈由 foundation 的handleFocusVisible实现在 focus 事件中检测target.matches(:focus-visible)决定是否设置focusVisible状态触发时根节点添加semi-switch-focusclass 并显示 2px 的--semi-color-primary-light-active轮廓见 packages/semi-foundation/switch/foundation.ts 与 packages/semi-foundation/switch/switch.scss。若浏览器不支持:focus-visible会发出 warning 提示。文案规范Content Guidelines官方对 Switch 的描述文案给出三条规范源自 content/input/switch/index-en-US.md首字母大写不需要标点符号。间接明了地说明该设置的开启或关闭状态。如果需要解释给用户开启和关闭状态所代表的情况。即文案应简洁、语义明确让用户无需阅读说明即可理解该开关控制什么功能。设计变量Design TokensSwitch 的视觉完全由 Semi 的设计变量Design Tokens驱动可通过主题定制改变外观。核心变量见 packages/semi-foundation/switch/variables.scss包括背景色关闭态var(--semi-color-fill-0)hover 为 fill-1按下为 fill-2开启态var(--semi-color-success)hover 为 success-hover按下为 success-active禁用态使用--semi-color-border描边与--semi-color-success-disabled填充。滑块--semi-white背景、--semi-color-border描边按下时延展宽度实现按压反馈。位移滑块开启/关闭位移2px ↔ 18pxlarge 为 3px ↔ 26pxsmall 为 1px ↔ 11px。动画背景色与滑块 transform 过渡时长为 200ms。圆角为高度的一半保持胶囊造型。由于这些变量全部基于 Semi 的全局语义色板--semi-color-*在暗色模式与主题定制content/advanced/customize-theme/index.md下无需改动组件即可自动适配。源码结构与测试验证若需深入源码可按以下路径查阅组件层packages/semi-ui/switch/index.tsx —— 负责状态管理、class 拼接、ARIA 属性透传、Spin/滑块渲染。逻辑层packages/semi-foundation/switch/foundation.ts —— 受控/非受控判定、禁用同步、focus-visible 处理。常量packages/semi-foundation/switch/constants.ts —— CSS class 前缀与尺寸枚举。样式packages/semi-foundation/switch/switch.scss含 animation.scss、rtl.scss与 variables.scss。测试packages/semi-ui/switch/test/switch.test.js —— 覆盖 className/style、checkedText/uncheckedText 渲染、disabled 切换、onChange 调用、onMouseEnter/onMouseLeave、尺寸 class、受控模式等行为可作为使用与二次开发的回归参考。Storybook 示例packages/semi-ui/switch/_story/switch.stories.tsx。从源码结构看Switch 采用 Semi 统一的 组件层 foundation 层 架构组件层只负责渲染与事件转发业务逻辑集中在可跨框架复用的 foundation 中这也是 Semi Design 支持多端/多框架如 Web Components见 content/ecosystem/web-components/index.md的基础设计。总结Semi Design 的 Switch 是一个功能完整、无障碍友好的二元状态切换组件通过defaultChecked/checked可灵活选择受控与非受控模式size、disabled、loading、checkedText/uncheckedText覆盖了常见交互需求底层基于原生 checkbox 叠加roleswitch与aria-checked的增强实现保证了键盘可达与屏幕阅读器兼容全部视觉细节由 Design Tokens 驱动天然支持主题定制。结合本文给出的源码路径与测试用例你可以放心地在生产项目中接入 Switch并在需要时深入定制。赞分享前端UI组件设计系统【免费下载链接】semi-designA 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项目地址https://gitcode.com/gh_mirrors/se/semi-design点击查看免费下载相关推荐Semi Design Switch 开关组件完全指南从基础用法到源码级原理与无障碍设计Semi Design Switch 开关组件完全指南从基础用法到源码级原理与无障碍设计 本篇技术指南围绕 Semi Design React UI 库中的前端UI组件设计系统Semi Design Notification 组件完全指南API 用法、底层实现与无障碍实践Semi Design Notification 组件完全指南API 用法、底层实现与无障碍实践 Notification 是 Semi Design d前端UI组件设计系统react-native-web CheckBox 组件完全指南受控状态、API 与无障碍实现解析react native web CheckBox 组件完全指南受控状态、API 与无障碍实现解析 CheckBox 是 react native web 提前端UI组件跨平台上一篇群晖NAS网速翻倍r8152驱动保姆级安装与调优实战指南下一篇物联大师快速上手指南5分钟部署一个免费轻量级物联网平台创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
