122 lines
6.1 KiB
JSON
122 lines
6.1 KiB
JSON
{
|
||
"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 命中渲染内联 <svg width=\"1em\">;未命中只认 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' | <CSS 长度>,默认 '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)。",
|
||
"图标不是热区:实际场景里图标放进 <button aria-label=\"新建\">,键盘可达与焦点环由 button 提供(示例 icon-ex-6)。",
|
||
"tone 只改颜色,演示里始终与文字或 label 同时出现,不把颜色当唯一信息通道(Icon.jsx:35-41)。"
|
||
],
|
||
"resources": [
|
||
{
|
||
"file": "frameworks/Icon.jsx",
|
||
"kind": "React 组件",
|
||
"desc": "Icon.jsx —— React 实现:props 签名、注入数据表、parsePaths/viewBoxOf 与三层内容优先序"
|
||
},
|
||
{
|
||
"file": "frameworks/Icon.css",
|
||
"kind": "样式文件",
|
||
"desc": "Icon.css —— 组件 import 的 .kole-icon-icon 变体类与场景类"
|
||
}
|
||
],
|
||
"exampleIds": [
|
||
"icon-ex-1",
|
||
"icon-ex-3",
|
||
"icon-ex-4",
|
||
"icon-ex-5",
|
||
"icon-ex-6",
|
||
"icon-ex-7"
|
||
],
|
||
"notes": [
|
||
"props 解构与默认值:frameworks/Icon.jsx:72-82",
|
||
"parsePaths 与 viewBoxOf:frameworks/Icon.jsx:57-70",
|
||
"类名拼接与 size 双路径:frameworks/Icon.jsx:86-100",
|
||
"内容优先序:frameworks/Icon.jsx:106-142",
|
||
"a11y 分流:frameworks/Icon.jsx:104",
|
||
"数据表注入来源与「勿手改」:frameworks/Icon.jsx:18-22",
|
||
"consumedApi.classes 里出现 className(Icon.jsx:86,114,141,145)是 JSX 属性名而非类名,未进 table。"
|
||
]
|
||
}
|