{ "slug": "icon", "end": "react", "curated": true, "summary": "React 端图标组件:name 查表渲染内联 SVG,size/tone/spin 走类名,label 决定它是图片还是装饰。", "usage": [ "入参解构为 { name = '', size = 'default', tone = 'default', spin = false, label = '', color = '', icon = '★', children = null, onClick },前三个决定外观(Icon.jsx:72-82)。", "查表函数 parsePaths(name) 把路径串 'SM…|FM…' 解析成 [{ mode, d }],返回 null 表示未命中;viewBox 由 viewBoxOf(name) 从数据层取(Icon.jsx:26,57-70)。", "className 由数组拼接:基类 kole-icon-icon 加 SIZE_CLASS[size] 与 TONE_CLASS[tone](不在表内则为空串),spin 为真再加 --spin,最后 filter(Boolean) 去空(Icon.jsx:26-41,86-93)。", "尺寸关键字有 small/default/large/xlarge 四档;传非关键字(如 '18px'、数字 18)时不加尺寸类,改写 style.fontSize(数字会被补成 px)(Icon.jsx:27-32,97-100)。", "内容优先序是三层:name 命中渲染内联 ;未命中只认 children;name 为空时用 children,没有 children 才退到 icon 字段的字形字符(Icon.jsx:83-84,106-142)。", "onClick 直接挂在根 span 上;示例里图标放在 button 内部时并不依赖它,事件由按钮承担(Icon.jsx:81,145;示例 icon-ex-6)。" ], "bestPractices": [ "color 优先于 tone:两者同传时 tone 的类仍会加上但被内联 style.color 覆盖,写一处即可(Icon.jsx:11-13,95-96)。", "未命中的 name 不会抛错也不会显示「找不到」图标,只会渲染成空(无 children 且 name 非空时 content 为 null);排查空白图标时先核对名字是否在 311 名表里(Icon.jsx:110-142)。", "label 只影响 a11y 属性,不改变图形;读取同一张图做装饰时务必不传 label,否则读屏器会多念一次(Icon.jsx:77,104)。", "数据表 KOLE_ICON_DATA 由 tools/inject-icon-table.mjs 注入,注释明确写「勿手改」;要加图标请改 .design_library/kole-ui/icons/registry.json 后重跑注入(Icon.jsx:18-22)。" ], "apiCarrier": { "kind": "props", "note": "React 端 API 是九个 props 加一个 onClick:name/icon 决定图形来源,size/tone/color/spin 决定外观,label 决定无障碍语义,children 是未命中时的内容回退;没有 ref 句柄与具名插槽。", "table": [ { "name": "name", "type": "string,默认 ''", "desc": "图标名(311 名表内查),命中渲染内联 SVG" }, { "name": "size", "type": "'small' | 'default' | 'large' | 'xlarge' | ,默认 'default'", "desc": "关键字加尺寸类;非关键字写 style.fontSize(数字补 px)" }, { "name": "tone", "type": "'default' | 'brand' | 'secondary' | 'danger' | 'success' | 'warning',默认 'default'", "desc": "语义色,default 不产生类即继承父级文字色" }, { "name": "spin", "type": "boolean,默认 false", "desc": "为真时加 --spin 类,仅表示进行中" }, { "name": "label", "type": "string,默认 ''", "desc": "无障碍名称;有值输出 role=\"img\" + aria-label,无值输出 aria-hidden" }, { "name": "color", "type": "string,默认 ''", "desc": "任意 CSS 颜色,写内联 style.color,优先于 tone" }, { "name": "icon", "type": "string,默认 '★'", "desc": "历史字段,字形字符;仅在 name 为空且无 children 时使用" }, { "name": "children", "type": "ReactNode,默认 null", "desc": "内容回退:name 未命中时渲染它(不猜图标、不抛错)" }, { "name": "onClick", "type": "(e) => void", "desc": "挂在内层 span 上的点击回调;语义强调用外层按钮承载" }, { "name": "kole-icon-icon", "type": "className", "desc": "根 span 基类名" }, { "name": "kole-icon-icon__svg", "type": "className", "desc": "内联 SVG 的类名" }, { "name": "kole-icon-icon__glyph", "type": "className", "desc": "字形字符容器类名(icon 字段路径)" } ] }, "a11y": [ "label 有值时根节点带 role=\"img\" 与 aria-label,读屏器按图片播报名称(示例里的「校验通过」「加载中」);不传 label 则带 aria-hidden=\"true\",纯装饰不进序列(Icon.jsx:77,104)。", "内联 SVG 固定 aria-hidden=\"true\" 加 focusable=\"false\",语义只由外层 span 表达,不会双重播报(Icon.jsx:113-120)。", "图标不是热区:实际场景里图标放进