{ "schemaVersion": 1, "sourceKind": "authored-spec", "provenance": "authored-in-repo", "specFile": "spec/移动端规格.md", "specSection": "35 · 滑动选择器 Slider", "confidence": "high", "slug": "mobile-slider", "name": "滑动选择器 Slider", "semanticTypeCandidates": [ "slider", "range-slider", "gesture-input" ], "variantDimensions": [ { "name": "mode", "values": [ "single", "range" ] }, { "name": "marks", "values": [ "with-marks", "none" ] }, { "name": "showValue", "values": [ "true", "false" ] } ], "representativeVariants": [ { "mode": "single", "marks": "none", "showValue": "true", "label": "默认(单滑块 + 右侧数值)" }, { "mode": "single", "marks": "with-marks", "showValue": "true", "label": "带刻度(轨道上标出等分点)" }, { "mode": "range", "marks": "none", "showValue": "true", "label": "双滑块区间(左值不越过右值)" } ], "anatomy": { "slider": "根元素,一行里放进「轨道热区 + 数值」", "rail": "轨道热区,44px 高的可聚焦区域,承载指针事件与锚点", "track": "轨道本体(可视 4px),承载选中段与刻度的边界", "filled": "选中段,从起点铺到滑块位置", "thumb": "滑块,位置由当前值的百分比决定;拖动中放大作为「抓住了」的反馈", "mark": "刻度点,仅 marks=with-marks 时出现(只标位置,不写文案)" }, "structurePatterns": { "mode": "single(单滑块)/ range(双滑块,左值不越过右值)", "marks": "with-marks(轨道上标出等分点)/ none(不标刻度)", "showValue": "true(右侧显示当前值)/ false(不显示数值)" }, "usageHints": [ "在一个连续区间里用一次滑动选出数值(预算上限、价格区间、音量、亮度)", "轨道可视高度只有 4px,但整条轨道所在的行必须是 44px 高的热区", "按下任意位置就要跳到该处 —— 触屏上要求用户精确抓住 20px 的滑块是点不中的", "取值按 step 吸附并夹在 [min, max];mode=range 时左值不越过右值、右值不越过左值", "值变化立即触发 change 事件(连续回传),不做防抖;松手时才做业务提交" ], "doNotInvent": [ "数值输入框与滑块的双向绑定(宿主自行组合 Input,本组件只回传值)", "刻度上的文案标注与区间高亮(只标位置,不写文案)", "拖动结束后的「撤销 / 重置」流程", "纵向滑块与圆形表盘式选择器" ], "unknowns": [ "双滑块的最小间距是否应当是 1 个 step(当前是),还是用户可配", "刻度数量是否应由 step 推导(当前按 5 等分固定标点)", "拖动中是否要把当前值放大显示在滑块上方(气泡提示)" ], "interaction": [ "轨道热区高 44px,**按下任意位置即跳到该处**,随后横向拖动连续改值;不要求抓住滑块", "手势是「按下 + 拖动」一次连续动作,不响应长按或双击;横向分量优先,纵向滚动不被吞掉(touch-action: pan-y)", "取值按 step 吸附并夹在 [min, max];mode=range 时左值不越过右值、右值不越过左值", "拖动期间滑块放大到 24px,松手后 150ms 回弹;减少动态偏好下瞬时切换", "值变化立即触发 change 事件(连续回传),不做防抖;松手时才做业务提交" ], "accessibility": [ "单滑块:轨道热区是 role=\"slider\" 且可聚焦,写 aria-valuemin / aria-valuemax / aria-valuenow / aria-label", "双滑块:外层是 role=\"group\" + aria-label,每个滑块各自持有 aria-valuenow(两条独立数值)", "禁用时写 aria-disabled=\"true\",读屏会播报不可用", "键盘:聚焦后左右方向键按 step 步进(触屏之外的替代路径)" ], "api": { "source": "implementation", "note": "props / events / slots 为 6 端实现的公共接口(说明文字取自规格对应小节)。字段名与各端源码逐名核对:node tools/verify-mobile-docs.mjs", "requiredNote": "「必传」按严格定义:实现里**没有默认值**时才为 Y(本门禁逐条核对 props 与各端源码的默认值,防止契约与实现脱节)。", "props": [ { "name": "value", "type": "number", "default": "0", "desc": "受控当前值(range 模式下是左值),与 aria-valuenow 同步写(规格 §35.5)", "required": false }, { "name": "valueMax", "type": "number", "default": "100", "desc": "mode=range 时的右值(single 模式忽略)(规格 §35.3)", "required": false }, { "name": "min", "type": "number", "default": "0", "desc": "区间下限,拖动与键盘步进都不会低于它(规格 §35.5)", "required": false }, { "name": "max", "type": "number", "default": "100", "desc": "区间上限,拖动与键盘步进都不会高于它(规格 §35.5)", "required": false }, { "name": "step", "type": "number", "default": "1", "desc": "取值吸附步长;也是双滑块的最小间距与键盘步进量(规格 §35.5)", "required": false }, { "name": "mode", "type": "'single' | 'range'", "default": "'single'", "desc": "变体 mode:单滑块还是双滑块区间(规格 §35.3)", "required": false }, { "name": "marks", "type": "boolean", "default": "false", "desc": "变体 marks:轨道上是否标出等分刻度点(规格 §35.3)", "required": false }, { "name": "showValue", "type": "boolean", "default": "true", "desc": "变体 showValue:是否在轨道右侧显示当前值(规格 §35.3)", "required": false }, { "name": "disabled", "type": "boolean", "default": "false", "desc": "状态 disabled:整条置灰且不响应,指针与键盘都不改值(规格 §35.4)", "required": false }, { "name": "label", "type": "string", "default": "'滑动选择'", "desc": "无障碍名称,落到 role=\"slider\" 的 aria-label(规格 §35.6)", "required": false } ], "events": [ { "name": "change", "params": "(value)", "desc": "拖动或键盘步进改值时触发,连续回传当前值(range 模式回传 [左值, 右值])(规格 §35.5)" } ], "slots": [ { "name": "default", "desc": "数值之后的自定义内容(如单位文案,规格 §35.2 slider)" } ] }, "variantClasses": { "mode": { "single": [], "range": [ ".kole-m-slider--range" ] }, "marks": { "none": [], "with-marks": [ ".kole-m-slider--marks", ".kole-m-slider__mark" ] }, "showValue": { "true": [], "false": [] } }, "demos": [ { "id": "basic", "group": "01 组件类型", "title": "基础用法", "desc": "在轨道上按住拖动即改值;轨道可视 4px、热区 44px 高。", "variant": "mode=single" }, { "id": "steps", "group": "01 组件类型", "title": "带刻度", "desc": "marks=with-marks:轨道上标出等分点;取值仍按 step 吸附。", "variant": "marks=with-marks" }, { "id": "range", "group": "01 组件类型", "title": "双滑块区间", "desc": "mode=range:两个滑块各自独立拖动,左值不会越过右值。", "variant": "mode=range" }, { "id": "dragging", "group": "02 组件状态", "title": "拖动中", "desc": "滑块由 20px 放大到 24px,并给轨道加一层浅底作「抓住了」的反馈。", "variant": "状态 dragging" }, { "id": "disabled", "group": "02 组件状态", "title": "禁用", "desc": "整条置灰且不响应:读屏播报不可用,指针事件不再改值。", "variant": "disabled=true" } ], "related": [ { "slug": "mobile-stepper", "why": "有界区间里加减小整数、且需要精确值时用 Stepper;数值连续、更看重「大致位置」时才用 Slider" }, { "slug": "mobile-input", "why": "需要键盘输入精确数值(金额、编号)时用 Input + 数字键盘;Slider 只适合粗选" }, { "slug": "mobile-form", "why": "滑块作为表单里的一个字段时,标签、必填星号与错误提示由 Form 的 item 提供" } ] }