Tabs
- 组件说明:Tabs 用于在同一区域内组织和切换不同内容面板。对外 API 采用声明式配置:简单场景下
children作为触发器,面板内容通过items配置。 - 尺寸基线:容器高度=40px,标签间距=24px(Default/Underline)或 16px(Chevron)。
- 实现约定:
ui/tabs只保留结构骨架,design 层统一接管视觉 token。variant直接在Tabs上配置。 - Figma 规范
基础用法
结果
Loading...
实时编辑器
<Tabs defaultValue="tab1" items={[ { value: 'tab1', label: '账户', content: <p style={{ padding: '16px 0', color: '#333' }}>管理您的账户设置和偏好。</p>, }, { value: 'tab2', label: '设置', content: <p style={{ padding: '16px 0', color: '#333' }}>自定义应用程序设置。</p>, }, { value: 'tab3', label: '通知', content: <p style={{ padding: '16px 0', color: '#333' }}>配置通知偏好。</p>, }, ]} />
变体
3 种视觉变体,适配不同使用场景。
Default
纯文字标签页,最简视觉样式。
结果
Loading...
实时编辑器
<Tabs defaultValue="tab1" variant="default" items={[ { value: 'tab1', label: 'Tab 1', content: <p style={{ padding: '16px 0' }}>Content 1</p> }, { value: 'tab2', label: 'Tab 2', content: <p style={{ padding: '16px 0' }}>Content 2</p> }, { value: 'tab3', label: 'Tab 3', content: <p style={{ padding: '16px 0' }}>Content 3</p> }, ]} />
Underline
选中标签带 2px 底部边框指示。
结果
Loading...
实时编辑器
<Tabs defaultValue="tab1" variant="underline" items={[ { value: 'tab1', label: 'Tab 1', content: <p style={{ padding: '16px 0' }}>Content 1</p> }, { value: 'tab2', label: 'Tab 2', content: <p style={{ padding: '16px 0' }}>Content 2</p> }, { value: 'tab3', label: 'Tab 3', content: <p style={{ padding: '16px 0' }}>Content 3</p> }, ]} />
Chevron
选中标签显示下拉箭头图标,暗示可展开内容。
结果
Loading...
实时编辑器
<Tabs defaultValue="tab1" variant="chevron" items={[ { value: 'tab1', label: 'Tab 1', content: <p style={{ padding: '16px 0' }}>Content 1</p> }, { value: 'tab2', label: 'Tab 2', content: <p style={{ padding: '16px 0' }}>Content 2</p> }, { value: 'tab3', label: 'Tab 3', content: <p style={{ padding: '16px 0' }}>Content 3</p> }, ]} />
变体对比
三种变体并排展示。
结果
Loading...
实时编辑器
<div style={{ display: 'flex', flexDirection: 'column', gap: 32 }}> <div> <p style={{ fontSize: 12, color: '#999', marginBottom: 8 }}>Default</p> <Tabs defaultValue="tab1" variant="default" items={[ { value: 'tab1', label: 'Tab 1' }, { value: 'tab2', label: 'Tab 2' }, ]} /> </div> <div> <p style={{ fontSize: 12, color: '#999', marginBottom: 8 }}>Underline</p> <Tabs defaultValue="tab1" variant="underline" items={[ { value: 'tab1', label: 'Tab 1' }, { value: 'tab2', label: 'Tab 2' }, ]} /> </div> <div> <p style={{ fontSize: 12, color: '#999', marginBottom: 8 }}>Chevron</p> <Tabs defaultValue="tab1" variant="chevron" items={[ { value: 'tab1', label: 'Tab 1' }, { value: 'tab2', label: 'Tab 2' }, ]} /> </div> </div>
禁用状态
可以单独禁用某个标签页。
结果
Loading...
实时编辑器
<Tabs defaultValue="tab1" variant="underline" items={[ { value: 'tab1', label: '激活', content: <p style={{ padding: '16px 0' }}>激活内容</p> }, { value: 'tab2', label: '禁用', disabled: true, content: <p style={{ padding: '16px 0' }}>禁用内容</p>, }, { value: 'tab3', label: '正常', content: <p style={{ padding: '16px 0' }}>正常内容</p> }, ]} />
滚动溢出
标签过多时,列表自动支持水平滚动,并显示左右导航箭头。
结果
Loading...
实时编辑器
<Tabs defaultValue="t1" variant="underline" items={[ { value: 't1', label: '仪表盘', content: <p style={{ padding: '16px 0' }}>仪表盘内容</p> }, { value: 't2', label: '分析' }, { value: 't3', label: '报告' }, { value: 't4', label: '通知' }, { value: 't5', label: '设置' }, { value: 't6', label: '集成' }, { value: 't7', label: '账单' }, { value: 't8', label: '安全' }, { value: 't9', label: '团队' }, { value: 't10', label: 'API 密钥' }, ]} />
保留状态(destroyOnHidden)
默认情况下,非激活面板会从 DOM 卸载。设置 destroyOnHidden={false} 可保留面板在 DOM 中,保持内部状态(如滚动位置、表单输入)。
结果
Loading...
实时编辑器
const PreserveStateExample = () => { const [count, setCount] = useState(0) return ( <Tabs defaultValue="tab1" items={[ { value: 'tab1', label: '计数器', destroyOnHidden: false, content: ( <div style={{ padding: '16px 0' }}> <p>计数: {count}</p> <button onClick={() => setCount((current) => current + 1)} style={{ marginTop: 8, padding: '4px 12px', border: '1px solid #ccc', borderRadius: 4, }} > 增加 </button> <p style={{ fontSize: 12, color: '#999', marginTop: 8 }}>切换标签后计数不会丢失。</p> </div> ), }, { value: 'tab2', label: '其他', destroyOnHidden: false, content: <p style={{ padding: '16px 0' }}>其他内容。返回查看计数仍在。</p>, }, ]} /> ) } render(<PreserveStateExample />)
尺寸规范
| 维度 | 值 |
|---|---|
| 容器高度 | 40px |
| 标签间距(Default) | 24px |
| 标签间距(Underline) | 24px |
| 标签间距(Chevron) | 16px |
| 字号 | 14px |
| 行高 | 22px |
| 选中字重 | 500(medium) |
| 未选中字重 | 400(normal) |
| Underline 线条厚度 | 2px |
| Chevron 图标尺寸 | 20×20px |
Props
Tabs
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
items | TabsItem[] | - | 声明式标签配置 |
variant | 'default' | 'underline' | 'chevron' | 'default' | 视觉变体 |
defaultValue | string | - | 默认激活标签(非受控) |
value | string | - | 激活标签(受控) |
onValueChange | (value: string) => void | - | 激活标签变化回调 |
className | string | - | 外层容器类名 |
listClassName | string | - | 标签列表容器类名 |
TabsItem
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
value | string | - | 标签唯一标识值 |
label | ReactNode | - | Trigger 展示内容 |
content | ReactNode | - | 面板内容 |
disabled | boolean | false | 是否禁用该标签 |
triggerClassName | string | - | Trigger 自定义类名 |
contentClassName | string | - | 面板自定义类名 |
destroyOnHidden | boolean | true | false 时保留非激活面板 DOM |