{ "schemaVersion": 1, "sourceKind": "authored-spec", "provenance": "authored-in-repo", "specFile": "spec/移动端规格.md", "specSection": "28 · 搜索框 Search", "confidence": "high", "slug": "mobile-search", "name": "搜索框 Search", "semanticTypeCandidates": [ "search", "search-field", "filter-input" ], "variantDimensions": [ { "name": "round", "values": [ "true", "false" ] }, { "name": "showCancel", "values": [ "false", "true" ] } ], "representativeVariants": [ { "round": "true", "showCancel": "true", "label": "胶囊形 + 取消(页面顶部常用)" }, { "round": "false", "showCancel": "false", "label": "方角无取消(嵌在卡片或工具栏里)" }, { "round": "true", "showCancel": "false", "label": "胶囊形无取消" } ], "anatomy": { "search": "根元素,一行里放进「搜索框 + 取消动作」", "icon": "框内左侧放大镜,纯装饰(不承载语义,读屏由 label 承担)", "control": "原生 input type=\"search\",占满剩余宽度", "clear": "可选清除按钮,有值且清除可用时出现在图标与取消之间", "cancel": "可选取消动作,默认文案「取消」,由 showCancel 控制显隐" }, "structurePatterns": { "round": "true(胶囊形,页面顶部常用)/ false(方角,嵌在卡片或工具栏里)", "showCancel": "false(只有输入框)/ true(右侧出现取消动作)" }, "usageHints": [ "用关键词从长列表里取回一小段结果", "移动端的搜索框几乎总是页面顶部的独立一行", "输入即过滤(不等回车)", "触屏没有 Esc 键,用户清空关键词后仍需一键回到列表,因此要有明确的取消动作", "组件不发请求、不做防抖:只回传关键词,节流策略由宿主决定" ], "doNotInvent": [ "搜索的防抖时值与接口节流策略(由宿主决定)", "搜索历史的存储与展示", "搜索结果的高亮规则" ], "unknowns": [ "取消文案是否允许替换(如「返回」)", "是否需要自动聚焦并拉起键盘", "语音/扫码等扩展入口是否放进框内" ], "interaction": [ "搜索框高度不小于 44px,取消动作热区不小于 44px", "输入即触发 input 事件(不等回车);键盘「搜索」键触发 search 事件", "清除按钮只在有值时出现,点击清空并把焦点留在输入框", "清除与取消都是 44px 热区;两者同时出现时先清除、再取消(自右向左层级递进)" ], "accessibility": [ "输入框用原生 input type=\"search\"(iOS 键盘右下角键位变成「搜索」)", "搜索图标是装饰性的,置 aria-hidden=\"true\",名称由 aria-label 给出", "清除按钮是原生 button 且带 aria-label=\"清除\";取消动作是原生 button", "取消按钮不用图标代替文字(触屏上文字比图标更好点)" ], "api": { "source": "implementation", "note": "props / events / slots 为 6 端实现的公共接口(说明文字取自规格对应小节)。字段名与各端源码逐名核对:node tools/verify-mobile-docs.mjs", "requiredNote": "「必传」按严格定义:实现里**没有默认值**时才为 Y(本门禁逐条核对 props 与各端源码的默认值,防止契约与实现脱节)。", "props": [ { "name": "value", "type": "string", "default": "''", "desc": "受控关键词;有值时清除按钮才出现(规格 §28.5)", "required": false }, { "name": "placeholder", "type": "string", "default": "''", "desc": "占位文字,提示搜索范围(如「搜索商品」)(规格 §28.2 control)", "required": false }, { "name": "round", "type": "boolean", "default": "true", "desc": "变体 round:true 胶囊形,false 方角(规格 §28.3)", "required": false }, { "name": "showCancel", "type": "boolean", "default": "false", "desc": "变体 showCancel:右侧是否出现取消动作(规格 §28.3)", "required": false }, { "name": "clearable", "type": "boolean", "default": "true", "desc": "有值时是否允许清除(规格 §28.5)", "required": false }, { "name": "disabled", "type": "boolean", "default": "false", "desc": "状态 disabled:置灰且不可聚焦(规格 §28.4)", "required": false }, { "name": "cancelText", "type": "string", "default": "'取消'", "desc": "取消动作文案;不用图标代替文字(规格 §28.6)", "required": false }, { "name": "label", "type": "string", "default": "'搜索'", "desc": "无障碍名称,落到 aria-label(规格 §28.6)", "required": false } ], "events": [ { "name": "input", "params": "(value)", "desc": "输入即触发,不等回车(规格 §28.5)" }, { "name": "search", "params": "(value)", "desc": "键盘「搜索」键触发(规格 §28.5)" }, { "name": "clear", "params": "—", "desc": "点击清除按钮触发,值由宿主置空(规格 §28.5)" }, { "name": "cancel", "params": "—", "desc": "点击取消动作触发,由宿主退出搜索态(规格 §28.5)" } ], "slots": [ { "name": "default", "desc": "根元素内的追加内容(如右侧的筛选入口)(规格 §28.2 search)" } ] }, "variantClasses": { "round": { "true": [ ".kole-m-search--round" ], "false": [] }, "showCancel": { "false": [], "true": [ ".kole-m-search__cancel" ] } }, "demos": [ { "id": "basic", "group": "01 组件类型", "title": "基础用法", "desc": "页面顶部一行:放大镜 + 输入区,输入即过滤(不等回车)。", "variant": "round=true" }, { "id": "cancel", "group": "01 组件类型", "title": "带取消", "desc": "showCancel=true:触屏没有 Esc 键,退出搜索需要一个明确的文字动作。", "variant": "showCancel=true" }, { "id": "round", "group": "01 组件类型", "title": "圆角两态", "desc": "round=true 胶囊形用于页面顶部;round=false 方角嵌在卡片或工具栏里。", "variant": "round=true|false" }, { "id": "clear", "group": "01 组件类型", "title": "清除", "desc": "有值时清除按钮才出现;点它清空并把焦点留在输入框。", "variant": "clearable=true" }, { "id": "disabled", "group": "02 组件状态", "title": "禁用", "desc": "置灰且不可聚焦,键盘与读屏都会跳过。", "variant": "disabled=true" } ], "related": [ { "slug": "mobile-input", "why": "收集填写内容用输入框;目的就是从列表里取回结果时才用搜索框" }, { "slug": "cell", "why": "「搜索入口」只做跳转时用单元格,点开才是真搜索页" }, { "slug": "mobile-list", "why": "搜索结果用列表承载;搜索框只负责取关键词" } ] }