{ "schemaVersion": 1, "sourceKind": "authored-spec", "provenance": "authored-in-repo", "specFile": "spec/移动端规格.md", "specSection": "38 · 分段器 Segmented", "confidence": "high", "slug": "mobile-segmented", "name": "分段器 Segmented", "semanticTypeCandidates": [ "segmented-control", "tab-switcher", "radio-group" ], "variantDimensions": [ { "name": "size", "values": [ "default", "small" ] }, { "name": "block", "values": [ "false", "true" ] } ], "representativeVariants": [ { "size": "default", "block": "false", "label": "三项基础(44px 高,宽度随内容)" }, { "size": "default", "block": "true", "label": "等分铺满(与筛选条同宽)" }, { "size": "small", "block": "false", "label": "小尺寸(32px 高,卡片内次级筛选)" } ], "anatomy": { "segmented": "容器,浅底 + 内边距,横向排列选项;role=\"radiogroup\" 并带 aria-label 说明这组在选什么", "item": "单个选项,原生 button + role=\"radio\"(整项可点、可键盘聚焦),data-value 携带取值", "label": "选项文字(可含装饰图标,图标 aria-hidden 由文字承担语义)" }, "structurePatterns": { "size": "default 44px / small 32px(卡片内次级筛选)", "block": "false 宽度随内容 / true 占满容器且各项等分", "状态类": "is-active 选中 / is-disabled 整段禁用" }, "usageHints": [ "在 2~5 个互斥选项里选一个,并让「当前选的是哪个」一眼可见(订单状态、时间范围、列表/网格视图切换)", "触屏没有悬停预告,所以选中项必须靠形态(白底滑块 + 阴影)而非色相区分", "选中态是视觉与属性的双向同步:除类名外必须同时更新 aria-checked", "选中项再次点击不重复触发 change(值未变不发事件)", "受控:组件不存值,只回传目标值 change;宿主不采纳时视觉不变化" ], "doNotInvent": [ "多选(同时选中多个)—— 需要多选时改用标签组或多选框", "选项的横向滚动、换行与「更多」折叠(超过 5 个应换组件)", "选中项的下划线滑块动画(那是标签栏的视觉语言,不是分段器)", "选项禁用条件与业务权限的判断" ], "unknowns": [ "选项数量上限是否应硬约束在 5 个(当前只写建议,不做运行时拦截)", "size=small 的命中区是否需要在纵向自动补到 44px", "是否需要「滑动经过即选中」(当前只认轻点,滑动不选中)" ], "interaction": [ "选项切换是一次轻点:点击后该项 is-active、同组其它项复位;不响应长按、双击与拖动", "选中态是视觉与属性的双向同步:除类名外必须同时更新 aria-checked", "每项热区高 ≥ 44px(size=small 时视觉 32px,但触摸命中区仍按 44px 计,纵向不留死区)", "选中项再次点击不重复触发 change(值未变不发事件)", "切换动效 120ms(--kole-duration-fast),prefers-reduced-motion 下瞬时切换" ], "accessibility": [ "容器 role=\"radiogroup\" + aria-label;每个选项原生 button + role=\"radio\" + aria-checked", "选项名称由文字承担;装饰性图标必须 aria-hidden=\"true\"", "禁用时容器补 aria-disabled=\"true\",选项用原生 disabled", "键盘:Tab 进入分组,左右方向键在选项间移动并选中" ], "api": { "source": "implementation", "note": "props / events / slots 为 6 端实现的公共接口(说明文字取自规格对应小节)。字段名与各端源码逐名核对:node tools/verify-mobile-docs.mjs", "requiredNote": "「必传」按严格定义:实现里**没有默认值**时才为 Y(本门禁逐条核对 props 与各端源码的默认值,防止契约与实现脱节)。", "props": [ { "name": "value", "type": "string", "default": "''", "desc": "当前选中值(受控;与选项的 data-value 对应)(规格 §38.5)", "required": false }, { "name": "options", "type": "Array<{ value, label, disabled? }>", "default": "[]", "desc": "选项列表,2~5 个(规格 §38.2 item)", "required": false }, { "name": "size", "type": "'default' | 'small'", "default": "'default'", "desc": "变体 size:default 44px / small 32px(规格 §38.3)", "required": false }, { "name": "block", "type": "boolean", "default": "false", "desc": "变体 block:占满容器且各项等分(规格 §38.3)", "required": false }, { "name": "disabled", "type": "boolean", "default": "false", "desc": "整段禁用(规格 §38.4)", "required": false }, { "name": "label", "type": "string", "default": "'分段选择'", "desc": "这组选项在选什么的说明,落到 aria-label(规格 §38.6)", "required": false } ], "events": [ { "name": "change", "params": "(value: string)", "desc": "选中项变化时回传目标值;值未变不发事件(规格 §38.5)" } ], "slots": [] }, "variantClasses": { "size": { "default": [ ".kole-m-segmented--default" ], "small": [ ".kole-m-segmented--small" ] }, "block": { "false": [], "true": [ ".kole-m-segmented--block" ] } }, "demos": [ { "id": "basic", "group": "01 组件类型", "title": "基础用法", "desc": "三项互斥:选中项是白底滑块 + 品牌字色,靠形态而不是色相区分;容器 data-value 随选中同步。", "variant": "size=default" }, { "id": "block", "group": "01 组件类型", "title": "等分铺满", "desc": "block=true:两项等分容器宽度,适合与筛选条同宽;选项少时也不出现半截空白。", "variant": "block=true" }, { "id": "small", "group": "01 组件类型", "title": "小尺寸", "desc": "size=small:32px 高,用于卡片内的次级筛选;视觉更矮但命中区仍按 44px 计。", "variant": "size=small" }, { "id": "icon-text", "group": "02 组件状态", "title": "带图标", "desc": "选项内容可含装饰图标;图标 aria-hidden,语义全部由文字承担,读屏不会读出符号。", "variant": "选项含图标" }, { "id": "disabled", "group": "02 组件状态", "title": "禁用", "desc": "整段置灰且不响应:选中项也不再高亮,点击与键盘都不改值,读屏播报不可用。", "variant": "disabled=true" } ], "related": [ { "slug": "tabbar", "why": "切换的是页面级内容区且选项 ≥ 4 个时用底部标签栏,分段器只用于同一区块内的轻量切换" }, { "slug": "mobile-tag", "why": "多选筛选条件用标签组(可同时选中多个),分段器只表达单选" }, { "slug": "mobile-radio", "why": "选项需要文字说明或纵向排列时用单选框列表,横向挤在一行才用分段器" } ] }