{ "schemaVersion": 1, "sourceKind": "authored-spec", "provenance": "authored-in-repo", "specFile": "spec/移动端规格.md", "specSection": "34 · 多选框 Checkbox", "confidence": "high", "slug": "mobile-checkbox", "name": "多选框 Checkbox", "semanticTypeCandidates": [ "checkbox", "checkbox-group", "multi-choice" ], "variantDimensions": [ { "name": "orientation", "values": [ "vertical", "horizontal" ] }, { "name": "button", "values": [ "false", "true" ] }, { "name": "selectAll", "values": [ "false", "true" ] } ], "representativeVariants": [ { "orientation": "vertical", "button": "false", "selectAll": "false", "label": "默认(方框 + 文字,纵向排列并画分隔线)" }, { "orientation": "vertical", "button": "false", "selectAll": "true", "label": "带全选行(组首一行「全选」,三态由组内推导)" }, { "orientation": "horizontal", "button": "true", "selectAll": "false", "label": "胶囊标签式横向(无方框,筛选条用)" } ], "anatomy": { "group": "根元素,role=\"group\" + aria-label 说明这组在选什么", "item": "单个选项,整行都是热区(原生 button + role=\"checkbox\")", "icon": "方框,未选中是空心框、选中是品牌底 + 反色勾号、半选是品牌底 + 横杠", "label": "选项文字,占满剩余宽度", "desc": "可选说明行,跟在文字下方(如「需先绑定手机号」)", "all": "全选行,不存储自己的状态,由组内各项推导" }, "structurePatterns": { "orientation": "vertical(纵向排列,组内画分隔线)/ horizontal(横向排列,靠间距分组)", "button": "false(方框 + 文字)/ true(胶囊标签式,无方框)", "selectAll": "false(不显示全选行)/ true(组首显示全选行)" }, "usageHints": [ "在一组选项里同时选中任意多项(兴趣标签、订阅范围、筛选维度),并支持「全选」", "触屏上没有鼠标悬停预告状态,全选行在「部分选中」时必须显示出与「全选 / 全不选」都不同的第三态(横杠)", "整行(方框 + 文字)都是热区,行高不小于 44px", "点全选行:只要还有未选中项就全部选中,否则全部清空(不在「半选」上停留)", "全选的选中态是推导值,不单独存储 —— 单项变化后立即重算" ], "doNotInvent": [ "「最多选 N 项」的数量上限与超出提示(业务规则在宿主)", "分组嵌套(一组里再分组)的层级表达", "与表单一起提交时的隐藏字段(由宿主添加)", "选项内容的异步加载与「已选 N 项」的汇总条" ], "unknowns": [ "全选行是否显示「已选 2/5」这类计数", "半选态在非全选行上的用例(如父级节点)", "胶囊按钮式是否也需要禁用态的视觉层(当前复用同一条置灰规则)" ], "interaction": [ "整行(方框 + 文字)都是热区,行高不小于 44px;横向组里每项自身也保持这个边长", "一次触摸即切换,各项互相独立;不限制同时选中的数量上限", "点全选行:只要还有未选中项就全部选中,否则全部清空(不在「半选」上停留)", "全选的选中态是**推导值**,不单独存储 —— 单项变化后立即重算,避免出现「全选已勾上但还有一项没选」", "切换动效是勾号 150ms 缩放;减少动态偏好下瞬时切换", "每次切换立即触发 change 事件,回传切换后的完整值数组" ], "accessibility": [ "组用 role=\"group\" + aria-label 说明分组名称", "每项是原生 button + role=\"checkbox\" + aria-checked(读屏会播报「复选框,已选中/未选中」)", "全选行的半选态用 aria-checked=\"mixed\"(checkbox 角色允许的第三个值)", "方框与勾号是纯装饰,对读屏隐藏(aria-hidden),语义全靠 role=\"checkbox\"", "禁用项用原生 disabled 并补 aria-disabled=\"true\"" ], "api": { "source": "implementation", "note": "props / events / slots 为 6 端实现的公共接口(说明文字取自规格对应小节)。字段名与各端源码逐名核对:node tools/verify-mobile-docs.mjs", "requiredNote": "「必传」按严格定义:实现里**没有默认值**时才为 Y(本门禁逐条核对 props 与各端源码的默认值,防止契约与实现脱节)。", "props": [ { "name": "options", "type": "Array", "default": "[]", "desc": "选项数组,每项 { value, label, desc, disabled }(规格 §34.2)", "required": false }, { "name": "value", "type": "Array", "default": "[]", "desc": "受控选中值数组,每项与 aria-checked 同步写(规格 §34.5)", "required": false }, { "name": "orientation", "type": "'vertical' | 'horizontal'", "default": "'vertical'", "desc": "变体 orientation:纵向(画分隔线)还是横向排列(规格 §34.3)", "required": false }, { "name": "button", "type": "boolean", "default": "false", "desc": "变体 button:胶囊标签式(无方框),用于筛选条(规格 §34.3)", "required": false }, { "name": "selectAll", "type": "boolean", "default": "false", "desc": "变体 selectAll:组首是否显示全选行(规格 §34.3)", "required": false }, { "name": "disabled", "type": "boolean", "default": "false", "desc": "状态 disabled:整组置灰且不可聚焦(规格 §34.4)", "required": false }, { "name": "label", "type": "string", "default": "'多选项'", "desc": "分组名称,落到 group 的 aria-label(规格 §34.6)", "required": false } ], "events": [ { "name": "change", "params": "(value)", "desc": "切换任一项或全选时触发,回传切换后的完整值数组(规格 §34.5)" } ], "slots": [ { "name": "default", "desc": "额外选项内容(宿主自己渲染的项,追在 options 之后,规格 §34.2 item)" } ] }, "variantClasses": { "orientation": { "vertical": [], "horizontal": [ ".kole-m-checkbox-group--horizontal" ] }, "button": { "false": [], "true": [ ".kole-m-checkbox--button" ] }, "selectAll": { "false": [], "true": [ ".kole-m-checkbox--all" ] } }, "demos": [ { "id": "basic", "group": "01 组件类型", "title": "复选框组", "desc": "多选:各项互不影响;点一项即切换该项的选中态。", "variant": "orientation=vertical" }, { "id": "all", "group": "01 组件类型", "title": "全选与半选", "desc": "全选行不存储自己的状态:全选 / 半选 / 空都由下面各项推导。", "variant": "selectAll=true" }, { "id": "horizontal", "group": "01 组件类型", "title": "横向排列", "desc": "orientation=horizontal:值少、文案短时用,不再画分隔线。", "variant": "orientation=horizontal" }, { "id": "states", "group": "02 组件状态", "title": "三种选中态", "desc": "未选中 / 选中 / 半选:勾号出现与消失是形状差异,不只靠颜色。", "variant": "状态 checked | indeterminate" }, { "id": "disabled", "group": "02 组件状态", "title": "禁用项", "desc": "置灰且不响应:原生 disabled 让读屏播报不可用、键盘跳过。", "variant": "disabled=true" } ], "related": [ { "slug": "mobile-radio", "why": "选项之间互斥(只能选一项)时用 Radio;可以同时成立多项时才用 Checkbox" }, { "slug": "mobile-switch", "why": "单个开关类配置用 Switch(即时生效、二值);需要提交一组值时才用 Checkbox 组" }, { "slug": "mobile-form", "why": "复选框组作为表单里的一个字段时,标签、必填星号与错误提示由 Form 的 item 提供" } ] }