113 lines
5.6 KiB
JSON
113 lines
5.6 KiB
JSON
{
|
||
"slug": "tabs",
|
||
"end": "react",
|
||
"curated": true,
|
||
"summary": "标签页:tabs 给配置,value/defaultValue 定受控,面板由 renderPanel(key) 返回。",
|
||
"usage": [
|
||
"React 端面板内容用函数式 props 交出去:renderPanel={key => <Panel/>},组件只负责用它渲染激活项(Tabs.jsx:26,29,61)。",
|
||
"受控与非受控按 value 是否传区分:不传才读 defaultValue(Tabs.jsx:28),本端不存在 v-model 双向语法。",
|
||
"关闭与新增是回调组合:closable 渲染 ×、onTabRemove(key) 通知移除;addable 渲染 +、onTabAdd() 通知新增,列表始终由父组件维护(Tabs.jsx:46-57)。",
|
||
"禁用与不可关闭是两个字段:tabs 项支持 disabled,另有 preventClose 可保留关闭按钮但阻止回调(Tabs.jsx:46)。",
|
||
"形态切换只改一个枚举:type 取 line/card/pill,拼成外层类 type-{type}(Tabs.jsx:11,37)。"
|
||
],
|
||
"bestPractices": [
|
||
"tabs 的 key 必须稳定且唯一,renderPanel 以当前 key 调用,父组件可用它做条件渲染或路由匹配。",
|
||
"切换标签不会重置 renderPanel 的返回内容——需要重置子组件状态时请给面板节点加 key。",
|
||
"受控模式必须回填 value,否则点击标签不会有任何视觉变化(内部只通过 onChange 上报)。"
|
||
],
|
||
"apiCarrier": {
|
||
"kind": "props",
|
||
"note": "React 端的 API 载体是 props 与回调:属性驱动外观(type/size/disabled 等布尔与枚举),交互经 onXxx 回传(如 onChange/onClick/onSelectionChange);没有 v-model,受控组件固定写成 value + onChange,非受控则用 defaultValue。",
|
||
"table": [
|
||
{
|
||
"name": "value",
|
||
"type": "string",
|
||
"desc": "受控的激活 key,传入即为受控"
|
||
},
|
||
{
|
||
"name": "defaultValue",
|
||
"type": "string",
|
||
"desc": "非受控的初始激活 key"
|
||
},
|
||
{
|
||
"name": "tabs",
|
||
"type": "Array<{ key, label, disabled?, preventClose? }>",
|
||
"desc": "标签配置数组"
|
||
},
|
||
{
|
||
"name": "type",
|
||
"type": "'line' | 'card' | 'pill'",
|
||
"desc": "形态,拼成 type-{type} 类"
|
||
},
|
||
{
|
||
"name": "closable",
|
||
"type": "boolean",
|
||
"desc": "是否显示关闭标记"
|
||
},
|
||
{
|
||
"name": "addable",
|
||
"type": "boolean",
|
||
"desc": "是否显示新增标记"
|
||
},
|
||
{
|
||
"name": "onChange",
|
||
"type": "(key) => void",
|
||
"desc": "激活标签变化回调"
|
||
},
|
||
{
|
||
"name": "onTabRemove",
|
||
"type": "(key) => void",
|
||
"desc": "点击关闭标记的回调"
|
||
},
|
||
{
|
||
"name": "onTabAdd",
|
||
"type": "() => void",
|
||
"desc": "点击新增标记的回调"
|
||
},
|
||
{
|
||
"name": "renderPanel",
|
||
"type": "(key) => ReactNode",
|
||
"desc": "面板内容渲染函数,也可用函数式 children"
|
||
}
|
||
]
|
||
},
|
||
"a11y": [
|
||
"标签项是 div,未使用 role=\"tab\"/aria-selected/tabIndex,键盘不能在标签间移动,读屏也不会播报选中态;需要严格无障碍时建议外包一层 tablist 实现。",
|
||
"关闭标记带 title=\"关闭\"、新增标记带 title=\"新增标签\"(Tabs.jsx:49,56),有文本提示可被辅助技术读取。",
|
||
"禁用标签在 choose 中被短路,但视觉与语义只靠 is-disabled 类,未加 aria-disabled。"
|
||
],
|
||
"resources": [
|
||
{
|
||
"file": "frameworks/Tabs.jsx",
|
||
"kind": "React(React)",
|
||
"desc": "React 端组件实现源码,props 与回调的唯一定义处"
|
||
},
|
||
{
|
||
"file": "frameworks/Tabs.css",
|
||
"kind": "样式",
|
||
"desc": "该 React 实现依赖的样式文件"
|
||
}
|
||
],
|
||
"exampleIds": [
|
||
"tabs-ex-1",
|
||
"tabs-ex-2",
|
||
"tabs-ex-3"
|
||
],
|
||
"notes": [
|
||
"frameworks/Tabs.jsx:9 中可指到 value(string)——受控的激活 key,传入即为受控",
|
||
"frameworks/Tabs.jsx:9 中可指到 defaultValue(string)——非受控的初始激活 key",
|
||
"frameworks/Tabs.jsx:10 中可指到 tabs(Array<{ key, label, disabled?, preventClose? }>)——标签配置数组",
|
||
"frameworks/Tabs.jsx:11 中可指到 type('line' | 'card' | 'pill')——形态,拼成 type-{type} 类",
|
||
"frameworks/Tabs.jsx:12 中可指到 closable(boolean)——是否显示关闭标记",
|
||
"frameworks/Tabs.jsx:12 中可指到 addable(boolean)——是否显示新增标记",
|
||
"frameworks/Tabs.jsx:13 中可指到 onChange((key) => void)——激活标签变化回调",
|
||
"frameworks/Tabs.jsx:13 中可指到 onTabRemove((key) => void)——点击关闭标记的回调",
|
||
"frameworks/Tabs.jsx:13 中可指到 onTabAdd(() => void)——点击新增标记的回调",
|
||
"frameworks/Tabs.jsx:14 中可指到 renderPanel((key) => ReactNode)——面板内容渲染函数,也可用函数式 children",
|
||
"props 解构清单见 frameworks/Tabs.jsx:16-27;本文件 table 只列该端真正消费的属性与回调。",
|
||
"过滤口径:事实包 consumedApi 里还包含绑在组件内部节点上的同名处理器(如 onClick/onChange 绑在内部 button、input、checkbox 上,见 frameworks/Tabs.jsx 全文),它们不是对外 props,因此未进 table。",
|
||
"table 构成核验:10 行中 10 行是 frameworks/Tabs.jsx 解构出的顶层 props(解构块 frameworks/Tabs.jsx:16-27);本组件 table 全部为顶层 props。",
|
||
"文档注释在 Tabs.jsx:14 声称支持函数式 children(key),但函数签名(Tabs.jsx:16-27)并未解构 children,第 29 行的 typeof children 判定永远为 undefined,属文档与实现不符;本表因此只列 renderPanel。"
|
||
]
|
||
}
|