
gpui-kit Checkbox 组件完全指南从受控状态到无障碍交互【免费下载链接】gpui-kitRust GUI components for building fantastic cross-platform desktop application by using GPUI.项目地址: https://gitcode.com/GitHub_Trending/gp/gpui-kit本指南基于 gpui-kit 官方组件文档website/component/checkbox.md展开围绕gpui_kit::component::checkbox::Checkbox讲解如何用 GPUI 构建二进制选择控件。你将掌握受控状态下on_change回调的正确用法、on_click兼容别名的取舍、四种尺寸与禁用态的配置以及组件底层无样式基座 主题化外观的分层实现原理并借助仓库中的单元测试与集成测试验证行为契约。引入组件use gpui_kit::component::checkbox::Checkbox;Checkbox位于gpui_kit的component模块下由 crates/component/src/checkbox.rs 提供。它并非独立实现而是对gpui_base中无样式基座gpui_base::Checkbox见 crates/base/src/checkbox.rs的一层主题化外观封装外观层负责标签、指示器、尺寸、禁用色与动画行为层焦点、键盘、无障碍、点击语义全部由基座承担。基础用法基础复选框Checkbox::new(my-checkbox) .label(Accept terms and conditions) .checked(false) .on_change(|checked, _, _| { println!(Checkbox is now: {}, checked); })on_change在用户切换复选框时触发回调的第一个参数是新的勾选状态。注意在组件外观层回调签名为Fn(bool, mut Window, mut App)即收到的是请求后的新值而基座层gpui_base::Checkbox::on_change的签名是Fn(CheckboxState, ClickEvent, mut Window, mut App)见 crates/base/src/checkbox.rs多暴露了触发事件的ClickEvent调用方可读取其修饰键例如用于扩展多选。受控复选框Controlled Checkboxgpui-kit 的 Checkbox 是受控组件组件自身不持有状态勾选状态完全由应用拥有回调只报告请求的值应用写入后调用cx.notify()触发重绘struct MyView { is_checked: bool, } impl Render for MyView { fn render(mut self, _: mut Window, cx: mut ContextSelf) - impl IntoElement { Checkbox::new(checkbox) .label(Option) .checked(self.is_checked) .on_change(cx.listener(|view, checked, _, cx| { view.is_checked *checked; cx.notify(); })) } }checked(self.is_checked)负责把应用状态渲染到界面上on_change回调负责把用户意图写回应用状态。这个应用拥有状态、组件仅转发请求的模式在 crates/kit/tests/controls.rs 的checkbox_switch_and_tabs_report_controlled_state测试中得到验证点击agree后window.find(agree).checked()变为Some(true)同时保留的旧快照before仍为Some(false)证明每一帧都是独立的状态记录。尺寸与禁用状态不同尺寸Checkbox::new(cb).text_xs().label(Extra Small) Checkbox::new(cb).text_sm().label(Small) Checkbox::new(cb).label(Medium) // default Checkbox::new(cb).text_lg().label(Large)text_xs/text_sm/text_lg是StyledExt提供的快捷方法实际作用于Size枚举。底层实现中指示器方块大小随尺寸变化见 crates/component/src/checkbox.rsXSmall为0.75rem、Small为0.875rem、Medium为1rem、Large为1.125rem勾选图标则对应size_2/size_2p5/size_3/size_3p5。除文本快捷方法外还可以通过Sizabletrait 显式指定Checkbox::new(cb).with_size(Size::Large) // 或 .xsmall() / .small() / .large()Sizable定义于 crates/component/src/sizing.rs默认尺寸为Size::Medium也支持直接传入px(30.)自定义像素尺寸。禁用状态Checkbox::new(checkbox) .label(Disabled checkbox) .disabled(true) .checked(false)disabled(true)来自Disableabletrait。禁用后指针与键盘激活都会被忽略、不触发回调且点击事件会向父级冒泡——facade_disabled_is_inert_and_pointer_activation_bubbles测试crates/component/src/checkbox.rs断言禁用复选框点击后自身回调计数为 0、父容器收到 1 次点击。视觉上禁用态使用主题muted_foreground文字色已勾选与未勾选两种禁用外观都保持可见见 crates/story/src/stories/checkbox_story.rs 的 Disabled 章节。无标签复选框Checkbox::new(checkbox) .checked(true)省略label()后指示器独立渲染标签可由周围容器内容提供story 中 Without label 章节即演示了这种用法见 crates/story/src/stories/checkbox_story.rs。自定义 Tab 顺序Checkbox::new(checkbox) .label(Custom tab order) .tab_index(2) .tab_stop(true)tab_index默认0tab_stop默认true。基座层会把(tab_index, tab_stop)应用到FocusHandle上参与键盘焦点遍历见 crates/base/src/checkbox.rs。tab_stop(false)可将复选框从 Tab 遍历中移除但仍可点击。API 参考组件外观层完整 API 可查看源码 crates/component/src/checkbox.rs方法说明new(id)创建带稳定元素 ID 的复选框label(text)设置可见标签支持富文本Textchecked(bool)设置勾选状态受控on_change(handler)处理指针或键盘激活请求的新状态on_click(handler)on_change的兼容别名disabled(bool)禁用指针与键盘激活tab_index(isize)焦点遍历索引默认0tab_stop(bool)是否参与 Tab 遍历默认trueaccessibility_label(label)屏幕阅读器朗读名称覆盖可见标签tooltip(text)设置悬停提示文字role(role)覆盖无障碍角色with_size(size)设置尺寸Sizabletrait关于on_change与on_clickon_click是历史遗留的兼容别名两者共享同一个回调槽位链式调用时后者覆盖前者不会同时执行两个回调见 crates/component/src/checkbox.rs 的文档注释。官方文档建议统一使用on_change因为它更准确地表达了请求新值的受控语义。样式与 trait外观层实现了Sizable与Disableable并额外支持text_xs()/text_sm()/text_base()默认/text_lg()— 文本字号disabled(bool)— 禁用状态selected(bool)/is_selected()— 来自Selectabletraitselected是checked的别名便于与列表、表格等可选项组件统一处理focus_ring(bool)— 控制聚焦时是否绘制焦点环默认开启主题相关颜色全部取自ActiveTheme勾选色为theme.primary未勾选边框为theme.input禁用态文字为theme.muted_foreground。进阶中间态Indeterminate基座层定义了完整的三态枚举crates/base/src/checkbox.rspub enum CheckboxState { Unchecked, // 未勾选默认 Checked, // 已勾选 Indeterminate, // 中间态 }通过indeterminate(true)可设置中间态常见于全选/半选树形或表格场景checked(bool)设置后会清除中间态。激活时的状态迁移规则在activated()中定义crates/base/src/checkbox.rs中间态或未勾选态点击后变为已勾选已勾选态点击后变为未勾选。这一规则由indeterminate_activation_becomes_checked测试锁定crates/base/src/checkbox.rs。注意组件外观层目前只公开checked(bool)若需中间态可直接使用基座gpui_kit::base::checkbox::Checkbox与CheckboxState集成测试mixed_checkbox_radio_and_toggle_report_distinct_statescrates/kit/tests/interactions.rs即演示了三种状态如何分别上报。完整示例复选框列表v_flex() .gap_2() .child(Checkbox::new(cb1).label(Option 1).checked(true)) .child(Checkbox::new(cb2).label(Option 2).checked(false)) .child(Checkbox::new(cb3).label(Option 3).checked(false))表单集成struct FormView { agree_terms: bool, subscribe: bool, } v_flex() .gap_3() .child( Checkbox::new(terms) .label(I agree to the terms and conditions) .checked(self.agree_terms) .on_change(cx.listener(|view, checked, _, cx| { view.agree_terms *checked; cx.notify(); })) ) .child( Checkbox::new(subscribe) .label(Subscribe to newsletter) .checked(self.subscribe) .on_change(cx.listener(|view, checked, _, cx| { view.subscribe *checked; cx.notify(); })) )带说明文字与换行标签story 演示了更复杂的标签场景crates/story/src/stories/checkbox_story.rs标签下方可通过.child()挂载次要说明文字标签本身支持自动换行甚至可以直接嵌入 markdownCheckbox::new(description) .w(px(320.)) .checked(self.check4) .label(Automatic updates) .child( div() .text_xs() .text_color(cx.theme().muted_foreground) .child(Download updates when the application is idle.), ) .on_change(cx.listener(|this, checked, _, cx| { this.check4 *checked; cx.notify(); }))源码级原理剖析分层架构外观层与基座层从源码结构看Checkbox 遵循行为与视觉分离的设计基座层gpui_base::Checkboxcrates/base/src/checkbox.rs无样式但完整拥有切换、焦点、键盘与无障碍行为。它向无障碍树暴露Role::CheckBox角色、aria_toggled三态False/True/Mixed与可点击动作并可设置aria_label外观层gpui_component::Checkboxcrates/component/src/checkbox.rs负责渲染指示器方块、勾选图标、标签、禁用配色与焦点环通过base.role(...).checked(...).disabled(...)把视觉状态透传给基座。外观层通过CheckboxIndicatorcrates/base/src/checkbox.rs渲染方块并利用基座的styles()语义样式系统按状态投影样式checked/indeterminate/disabled三种语义样式会覆盖实例样式测试indicator_projects_state_styles_over_the_instance_layer验证了状态样式优先于实例样式见 crates/base/src/checkbox.rs。勾选动画弹簧过渡勾选图标的显示并非简单的条件渲染。checkbox_check_iconcrates/component/src/checkbox.rs使用spring弹簧动画驱动透明度勾选时为1.0取消时为0.0且只要透明度大于 0 就保留图标路径——这样在淡出动画期间不会因路径提前卸载而只显示淡入效果。禁用时图标使用primary_foreground的 50% 透明度。键盘与无障碍契约基座层测试crates/base/src/checkbox.rs锁定了完整的行为契约指针激活恰好触发一次点击未勾选复选框on_change收到且仅收到一次CheckedEnter 与 Space 均触发且不重复enter_and_space_each_emit_once验证两次按键各自只上报一次状态禁用复选框完全惰性disabled_checkbox_is_inert_and_allows_pointer_events_to_bubble验证禁用态不产生状态变更且点击冒泡给父级无障碍信息完整accessibility_exposes_role_label_and_all_toggle_statescrates/base/src/checkbox.rs验证 role 为CheckBox、标签正确、三态toggled分别映射为Toggled::False / True / Mixed且禁用态不再支持Click动作。外观层还保留了一项值得注意的交互细节鼠标按下时调用window.prevent_default()crates/component/src/checkbox.rs保持指针按下不移动焦点的既有行为。小结gpui-kit 的 Checkbox 是一个完整的受控表单控件on_change请求新值、应用持有状态并cx.notify()重绘on_click仅作为兼容别名存在四种尺寸、禁用态、自定义 Tab 顺序覆盖了绝大多数表单场景而外观层 基座层的分层架构则把视觉主题与交互行为彻底解耦基座层甚至可直接用于构建自定义样式的复选框。若要进一步验证行为仓库内置的单元测试crates/base/src/checkbox.rs 与 crates/component/src/checkbox.rs和集成测试crates/kit/tests/controls.rs提供了可直接参考的契约示例。【免费下载链接】gpui-kitRust GUI components for building fantastic cross-platform desktop application by using GPUI.项目地址: https://gitcode.com/GitHub_Trending/gp/gpui-kit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考