代码演示
如何引入
import { Tabs, TabPane } from '@fibrous/semi-ui-react';
基本用法
标签栏支持四种样式的显示:线条式,按钮式,卡片式,斜线式。默认选中第一个启用的标签页。
标签页支持两种传入方式,两者渲染流程上有所区别:
- 通过
tabList传入标签页对象的数组,当使用tabList时每次只渲染当前传入的节点 - 或使用
<TabPane>逐项显式传入,使用<TabPane>时默认会渲染所有面板,可以通过将keepDOM设为false只渲染当前面板,此时不会有动画效果。
代码
import { Tabs, TabPane } from '@fibrous/semi-ui-react';
export default function TabsDemo() {
return (
<div>
<Tabs type="line">
<TabPane tab="文档" itemKey="1">
<h3>文档</h3>
<p style={{ lineHeight: 1.8 }}>Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的 Web 应用。</p>
<p style={{ lineHeight: 1.8 }}>区别于其他的设计系统而言,Semi Design 以用户中心、内容优先、设计人性化为设计理念,具有以下优势:</p>
<ul>
<li>
<p>Semi Design 以内容优先进行设计。</p>
</li>
<li>
<p>更容易地自定义主题。</p>
</li>
<li>
<p>适用国际化场景。</p>
</li>
<li>
<p>效率场景加入人性化关怀。</p>
</li>
</ul>
</TabPane>
<TabPane tab="快速起步" itemKey="2">
<h3>快速起步</h3>
<pre
style={{
margin: '24px 0',
padding: '20px',
border: 'none',
whiteSpace: 'normal',
borderRadius: 'var(--semi-border-radius-medium)',
color: 'var(--semi-color-text-1)',
backgroundColor: 'var(--semi-color-fill-0)',
}}
>
<code>yarn add @fibrous/semi-ui-react</code>
</pre>
</TabPane>
<TabPane tab="帮助" itemKey="3">
<h3>帮助</h3>
<p style={{ lineHeight: 1.8, color: 'var(--semi-color-text-0)', fontWeight: 600 }}>Q:有新组件需求、或者现有组件feature不能满足业务需求?</p>
<p style={{ lineHeight: 1.8, color: 'var(--semi-color-text-1)' }}>右上角问题反馈,提交issue,label选择Feature Request / New Component Request 我们会高优处理这些需求。</p>
<p style={{ lineHeight: 1.8, color: 'var(--semi-color-text-0)', fontWeight: 600 }}>Q:对组件的使用有疑惑?</p>
<p style={{ lineHeight: 1.8, color: 'var(--semi-color-text-1)' }}>欢迎进我们的客服lark群进行咨询提问。</p>
</TabPane>
</Tabs>
</div>
);
}代码
import { Tabs, TabPane } from '@fibrous/semi-ui-react';
export default function TabsDemo() {
return (
<Tabs type="button">
<TabPane tab="文档" itemKey="1">
文档
</TabPane>
<TabPane tab="快速起步" itemKey="2">
快速起步
</TabPane>
<TabPane tab="帮助" itemKey="3">
帮助
</TabPane>
</Tabs>
);
}代码
import { useState } from 'react';
import { Tabs } from '@fibrous/semi-ui-react';
export default function TabsDemo() {
const [key, setKey] = useState('1');
const contentList = ['文档', '快速起步', '帮助'];
const tabList = [
{ tab: '文档', itemKey: '1' },
{ tab: '快速起步', itemKey: '2' },
{ tab: '帮助', itemKey: '3' },
];
return (
<Tabs type="card" tabList={tabList} onChange={setKey}>
<div>{contentList[Number(key) - 1]}</div>
</Tabs>
);
}代码
import { useState } from 'react';
import { Tabs } from '@fibrous/semi-ui-react';
export default function TabsDemo() {
const [key, setKey] = useState('1');
const contentList = ['文档', '快速起步', '帮助'];
const tabList = [
{ tab: '文档', itemKey: '1' },
{ tab: '快速起步', itemKey: '2' },
{ tab: '帮助', itemKey: '3' },
];
return (
<Tabs type="slash" tabList={tabList} onChange={setKey}>
<div>{contentList[Number(key) - 1]}</div>
</Tabs>
);
}带图标的
有图标的标签栏。
代码
import { IconFile, IconGlobe, IconHelpCircle } from '@fibrous/semi-icons-react';
import { Tabs, TabPane } from '@fibrous/semi-ui-react';
export default function TabsDemo() {
return (
<Tabs>
<TabPane
tab={
<span>
<IconFile />
文档
</span>
}
itemKey="1"
>
文档
</TabPane>
<TabPane
tab={
<span>
<IconGlobe />
快速起步
</span>
}
itemKey="2"
>
快速起步
</TabPane>
<TabPane
tab={
<span>
<IconHelpCircle />
帮助
</span>
}
itemKey="3"
>
帮助
</TabPane>
</Tabs>
);
}更多选项收入 More 展示
支持将多余 Tab 合并为「更多」下拉菜单,more 传入数字即可,数字表示收入下拉菜单的 Tab 数量。
代码
import { Tabs, TabPane } from '@fibrous/semi-ui-react';
export default function TabsDemo() {
return (
<Tabs more={4} style={{ width: '60%', margin: '20px' }} type="card">
{[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map((i) => (
<TabPane tab={`Tab-${i}`} itemKey={`Tab-${i}`} key={i}>
Content of card tab {i}
</TabPane>
))}
</Tabs>
);
}也支持高级配置,向 more 传入对象,内可传入
count: 表示收入下拉菜单的 Tab 数量render: 自定义 Trigger 的渲染函数,返回的 ReactNode 会被渲染为下拉菜单的 TriggerdropdownProps: 传入 DropDown Props,会被透传到下拉菜单,如果需要自定义下拉菜单,使用 dropdownProps 中的 render 方法
代码
import { Tabs, TabPane, Button } from '@fibrous/semi-ui-react';
export default function TabsDemo() {
return (
<Tabs
more={{
count: 4,
render: () => {
return <Button type="tertiary">Click to show More</Button>;
},
dropdownProps: { trigger: 'click', position: 'bottomRight' },
}}
style={{ width: '60%', margin: '20px' }}
type="card"
>
{[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map((i) => (
<TabPane tab={`Tab-${i}`} itemKey={`Tab-${i}`} key={i}>
Content of card tab {i}
</TabPane>
))}
</Tabs>
);
}垂直的标签栏
type 为 line, card, button 支持水平和垂直两种模式,tabPosition='left|top', 默认为 top。type 为 slash 仅支持水平模式,无需设置。
代码
import { useState } from 'react';
import { IconFile, IconGlobe, IconHelpCircle } from '@fibrous/semi-icons-react';
import { Tabs, TabPane, RadioGroup, Radio, type TabType, type RadioChangeEvent } from '@fibrous/semi-ui-react';
export default function TabsDemo() {
const [type, setType] = useState<TabType>('line');
const onSelect = (e: RadioChangeEvent) => {
setType(e.target.value);
};
return (
<>
<RadioGroup
onChange={onSelect}
value={type}
type="button"
style={{
display: 'flex',
width: 200,
justifyContent: 'center',
}}
>
<Radio value="line">Line</Radio>
<Radio value="card">Card</Radio>
<Radio value="button">Button</Radio>
</RadioGroup>
<br />
<br />
<Tabs tabPosition="left" type={type}>
<TabPane
tab={
<span>
<IconFile />
文档
</span>
}
itemKey="1"
>
<div style={{ padding: '0 24px' }}>
<h3>文档</h3>
<p style={{ lineHeight: 1.8 }}>Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的 Web 应用。</p>
<p style={{ lineHeight: 1.8 }}>区别于其他的设计系统而言,Semi Design 以用户中心、内容优先、设计人性化为设计理念,具有以下优势:</p>
</div>
</TabPane>
<TabPane
tab={
<span>
<IconGlobe />
快速起步
</span>
}
itemKey="2"
>
<div style={{ padding: '0 24px' }}>
<h3>快速起步</h3>
<pre
style={{
margin: '24px 0',
padding: '20px',
border: 'none',
whiteSpace: 'normal',
borderRadius: '6px',
color: 'var(--semi-color-text-1)',
backgroundColor: 'var(--semi-color-fill-0)',
}}
>
<code>yarn add @fibrous/semi-ui-react</code>
</pre>
</div>
</TabPane>
<TabPane
tab={
<span>
<IconHelpCircle />
帮助
</span>
}
itemKey="3"
>
<div style={{ padding: '0 24px' }}>
<h3>帮助</h3>
<p style={{ lineHeight: 1.8, color: 'var(--semi-color-text-0)', fontWeight: 600 }}>Q:有新组件需求、或者现有组件feature不能满足业务需求?</p>
<p style={{ lineHeight: 1.8, color: 'var(--semi-color-text-1)' }}>右上角问题反馈,提交issue,label选择Feature Request / New Component Request 我们会高优处理这些需求。</p>
<p style={{ lineHeight: 1.8, color: 'var(--semi-color-text-0)', fontWeight: 600 }}>Q:对组件的使用有疑惑?</p>
<p style={{ lineHeight: 1.8, color: 'var(--semi-color-text-1)' }}>欢迎进我们的客服lark群进行咨询提问。</p>
</div>
</TabPane>
</Tabs>
</>
);
}滚动折叠
通过设置 collapsible 可以支持滚动折叠,目前只支持 horizontal 模式。
代码
import { Tabs, TabPane } from '@fibrous/semi-ui-react';
export default function TabsDemo() {
return (
<Tabs style={{ width: '60%', margin: '20px' }} type="card" collapsible>
{[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map((i) => (
<TabPane tab={`Tab-${i}`} itemKey={`Tab-${i}`} key={i}>
Content of card tab {i}
</TabPane>
))}
</Tabs>
);
}自定义滚动箭头渲染
通过 renderArrow 修改滚动折叠模式下,左右切换箭头的渲染,入参为溢出的 items 和 位置, 点击处理函数,以及 defaultNode。
代码
import { useState } from 'react';
import { Tabs, TabPane, Dropdown, type TabsProps } from '@fibrous/semi-ui-react';
export default function TabsDemo() {
const [activeKey, setActiveKey] = useState('Tab-0');
const renderArrow: TabsProps['renderArrow'] = (items, pos, handleArrowClick) => {
const style = {
width: 32,
height: 32,
margin: '0 12px',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
padding: 0,
border: 'none',
borderRadius: '100%',
background: 'var(--semi-grey-1)',
color: 'var(--semi-color-text)',
fontFamily: 'inherit',
fontSize: 'inherit',
cursor: 'pointer',
};
return (
<Dropdown
render={
<Dropdown.Menu>
{items.map((item) => {
return (
<Dropdown.Item key={item.itemKey} onClick={() => setActiveKey(item.itemKey)}>
{item.itemKey}
</Dropdown.Item>
);
})}
</Dropdown.Menu>
}
>
{pos === 'start' ? (
<button type="button" style={style} onClick={handleArrowClick}>
←
</button>
) : (
<button type="button" style={style} onClick={handleArrowClick}>
→
</button>
)}
</Dropdown>
);
};
return (
<Tabs renderArrow={renderArrow} style={{ width: '50%', margin: '20px' }} activeKey={activeKey} type="card" collapsible onChange={(k) => setActiveKey(k)}>
{[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map((i) => (
<TabPane tab={`Tab-${i}`} itemKey={`Tab-${i}`} key={i}>
Content of card tab {i}
</TabPane>
))}
</Tabs>
);
}修改切换箭头的渲染位置
通过 arrowPosition 来修改溢出指示器的位置,可选 start both end
代码
import { Tabs, TabPane } from '@fibrous/semi-ui-react';
export default function TabsDemo() {
return (
<>
<Tabs style={{ width: '60%', margin: '20px' }} type="card" collapsible arrowPosition="start">
{[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map((i) => (
<TabPane tab={`Tab-${i}`} itemKey={`Tab-${i}`} key={i}>
Content of card tab {i}
</TabPane>
))}
</Tabs>
<Tabs style={{ width: '60%', margin: '20px' }} type="card" collapsible arrowPosition="both">
{[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map((i) => (
<TabPane tab={`Tab-${i}`} itemKey={`Tab-${i}`} key={i}>
Content of card tab {i}
</TabPane>
))}
</Tabs>
<Tabs style={{ width: '60%', margin: '20px' }} type="card" collapsible arrowPosition="end">
{[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map((i) => (
<TabPane tab={`Tab-${i}`} itemKey={`Tab-${i}`} key={i}>
Content of card tab {i}
</TabPane>
))}
</Tabs>
</>
);
}自动溢出检测
通过设置 collapsible="auto" 可以启用自动溢出检测功能。组件会自动检测 Tab 是否溢出容器:
- 当 Tab 超出容器宽度或发生换行时,自动启用折叠模式(显示左右箭头)
- 当容器宽度增加或 Tab 数量减少后,所有 Tab 可以完整显示时,自动退出折叠模式
这个功能避免了开发者需要手动判断是否需要折叠的问题,特别适用于响应式布局场景。
collapsible="auto" - 自动检测溢出
固定宽度 400px,测试较窄容器
代码
import { useState } from 'react';
import { Tabs, TabPane, Button } from '@fibrous/semi-ui-react';
export default function TabsDemo() {
const [count, setCount] = useState(8);
const tabs = Array.from({ length: count }, (_, i) => (
<TabPane tab={`Tab-${i + 1}`} itemKey={`${i}`} key={i}>
Content of Tab {i + 1}
</TabPane>
));
return (
<div>
<div style={{ marginBottom: 12 }}>
<Button onClick={() => setCount(Math.max(3, count - 2))} style={{ marginRight: 8 }}>
减少 Tab
</Button>
<Button onClick={() => setCount(Math.min(15, count + 2))}>增加 Tab</Button>
<span style={{ marginLeft: 12 }}>当前 Tab 数量: {count}</span>
</div>
<div style={{ border: '1px solid var(--semi-color-border)', padding: 12, marginBottom: 16 }}>
<p style={{ marginBottom: 8, color: 'var(--semi-color-text-2)', fontSize: 12 }}>collapsible="auto" - 自动检测溢出</p>
<Tabs type="card" collapsible="auto">
{tabs}
</Tabs>
</div>
<div style={{ border: '1px solid var(--semi-color-border)', padding: 12, maxWidth: 400 }}>
<p style={{ marginBottom: 8, color: 'var(--semi-color-text-2)', fontSize: 12 }}>固定宽度 400px,测试较窄容器</p>
<Tabs type="card" collapsible="auto">
{tabs}
</Tabs>
</div>
</div>
);
}禁用
禁用标签栏中的某一个标签页。
代码
import { Tabs, TabPane } from '@fibrous/semi-ui-react';
export default function TabsDemo() {
return (
<Tabs defaultActiveKey="1">
<TabPane tab="文档" itemKey="1">
文档
</TabPane>
<TabPane tab="快速起步" itemKey="2" disabled>
快速起步
</TabPane>
<TabPane tab="帮助" itemKey="3">
帮助
</TabPane>
</Tabs>
);
}标签栏内容扩展
传入 tabBarExtraContent 属性可以在标签栏右侧添加附加操作。
代码
import { Tabs, TabPane, Button } from '@fibrous/semi-ui-react';
export default function TabsDemo() {
return (
<Tabs
defaultActiveKey="1"
tabBarExtraContent={
<Button
onClick={() => {
alert('you have clicked me!');
}}
>
Extra Action
</Button>
}
>
<TabPane tab="文档" itemKey="1">
文档
</TabPane>
<TabPane tab="快速起步" itemKey="2">
快速起步
</TabPane>
<TabPane tab="帮助" itemKey="3">
帮助
</TabPane>
</Tabs>
);
}标签栏二次封装
传入 renderTabBar 函数可对标签栏进行二次封装。
代码
import { Tabs, TabPane } from '@fibrous/semi-ui-react';
export default function TabsDemo() {
return (
<Tabs
defaultActiveKey="1"
renderTabBar={(tabBarProps, DefaultTabBar) => {
return (
<div className="tab-bar-box">
这是二次封装的Tab Bar,当前ActiveKey:{tabBarProps.activeKey}
<DefaultTabBar {...tabBarProps} />
</div>
);
}}
>
<TabPane tab="文档" itemKey="1">
文档
</TabPane>
<TabPane tab="快速起步" itemKey="2">
快速起步
</TabPane>
<TabPane tab="帮助" itemKey="3">
帮助
</TabPane>
</Tabs>
);
}拖拽排序
通过 renderTabBar API 结合第三方拖拽库(如 @dnd-kit)可以实现标签栏的拖拽排序功能。
代码
import { useState } from 'react';
import { Accessibility } from '@dnd-kit/dom';
import { arrayMove } from '@dnd-kit/helpers';
import { DragDropProvider, type DragEndEvent } from '@dnd-kit/react';
import { isSortable, useSortable } from '@dnd-kit/react/sortable';
import { Tabs, TabPane, type PlainTab, type TabsProps, type TabItemProps } from '@fibrous/semi-ui-react';
// The Provider drops the Accessibility plugin so TabItem keeps role="tab" and roving tabIndex, without aria-pressed
interface SortableTabItemProps extends Pick<TabItemProps, 'selected' | 'size' | 'type' | 'tabPosition' | 'onClick'> {
item: PlainTab;
index: number;
}
const SortableTabItem = ({ item, index, selected, size, type, tabPosition, onClick }: SortableTabItemProps) => {
const { ref, isDragging } = useSortable({
id: item.itemKey,
index,
disabled: item.disabled,
});
const style = {
cursor: item.disabled ? 'not-allowed' : 'grab',
opacity: isDragging ? 0.5 : 1,
display: 'inline-flex',
};
return <Tabs.TabItem ref={ref} style={style} itemKey={item.itemKey} tab={item.tab} icon={item.icon} disabled={item.disabled} selected={selected} size={size} type={type} tabPosition={tabPosition} onClick={onClick} />;
};
export default function TabsDemo() {
const [activeKey, setActiveKey] = useState('1');
const [items, setItems] = useState([
{ itemKey: '1', tab: '文档', content: '文档内容' },
{ itemKey: '2', tab: '表格', content: '表格内容' },
{ itemKey: '3', tab: '幻灯片', content: '幻灯片内容' },
{ itemKey: '4', tab: '表单', content: '表单内容' },
]);
const handleDragEnd = (event: DragEndEvent) => {
const { source } = event.operation;
if (!event.canceled && isSortable(source)) {
setItems((prev) => arrayMove(prev, source.initialIndex, source.index));
}
};
const renderTabBar: TabsProps['renderTabBar'] = ({ type = 'line', size = 'medium', tabPosition = 'top' }) => {
const barCls = `semi-tabs-bar semi-tabs-bar-${type} semi-tabs-bar-${tabPosition}`;
return (
<DragDropProvider plugins={(defaults) => defaults.filter((plugin) => plugin !== Accessibility)} onDragEnd={handleDragEnd}>
<div className={barCls} role="tablist">
{items.map((item, index) => (
<SortableTabItem key={item.itemKey} item={item} index={index} selected={activeKey === item.itemKey} size={size} type={type} tabPosition={tabPosition} onClick={(key) => setActiveKey(key)} />
))}
</div>
</DragDropProvider>
);
};
return (
<Tabs type="line" activeKey={activeKey} onChange={setActiveKey} renderTabBar={renderTabBar}>
{items.map((item) => (
<TabPane key={item.itemKey} tab={item.tab} itemKey={item.itemKey}>
<div style={{ padding: 20 }}>{item.content}</div>
</TabPane>
))}
</Tabs>
);
}动态更新
通过绑定事件,可以使标签栏动态更新。
代码
import { useRef, useState } from 'react';
import { Tabs, TabPane, ButtonGroup, Button } from '@fibrous/semi-ui-react';
export default function TabsDemo() {
const newTabIndex = useRef(0);
const [panes, setPanes] = useState([
{ title: 'Tab 1', content: 'Content of Tab Pane 1', itemKey: '1' },
{ title: 'Tab 2', content: 'Content of Tab Pane 2', itemKey: '2' },
]);
const [activeKey, setActiveKey] = useState('1');
const add = () => {
const index = newTabIndex.current++;
setPanes([...panes, { title: `New Tab ${index}`, content: 'New Tab Pane', itemKey: `newTab${index}` }]);
setActiveKey(`newTab${index}`);
};
const remove = () => {
if (panes.length > 1) {
const rest = panes.slice(0, -1);
setPanes(rest);
setActiveKey(rest[rest.length - 1].itemKey);
}
};
return (
<Tabs
activeKey={activeKey}
onChange={setActiveKey}
tabBarExtraContent={
<ButtonGroup>
<Button onClick={add}>新增</Button>
<Button onClick={remove}>删除</Button>
</ButtonGroup>
}
>
{panes.map((pane) => (
<TabPane tab={pane.title} itemKey={pane.itemKey} key={pane.itemKey}>
{pane.content}
</TabPane>
))}
</Tabs>
);
}关闭
关闭标签栏中的某一个标签页。
四种样式的页签都支持关闭选项,在对应的标签页上设置 closable 来开启。禁用的标签页不能关闭。标签页的移除由使用方在关闭回调中完成。
代码
import { useState } from 'react';
import { Tabs, TabPane } from '@fibrous/semi-ui-react';
export default function TabsDemo() {
const [tabList, setTabList] = useState([
{ tab: '文档', itemKey: '1', text: '文档', closable: true },
{ tab: '快速起步', itemKey: '2', text: '快速起步', closable: true },
{ tab: '帮助', itemKey: '3', text: '帮助' },
]);
const close = (key: string) => {
setTabList(tabList.filter((t) => t.itemKey !== key));
};
return (
<Tabs type="card" defaultActiveKey="1" onTabClose={close}>
{tabList.map((t) => (
<TabPane closable={t.closable} tab={t.tab} itemKey={t.itemKey} key={t.itemKey}>
{t.text}
</TabPane>
))}
</Tabs>
);
}API 参考
Tab
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| activeKey | 当前激活的标签页的 itemKey,受控。传 null 时不激活任何标签页,仍是受控;不传或为 undefined 时按非受控处理。 | string | null | - |
| arrowPosition | 折叠模式下,左右切换箭头的位置,可选 start、end 或 both。 | TabBarProps['arrowPosition'] | "both" |
| children | TabPane 子元素,必须是 Tabs 的直接子元素;其余节点按原顺序作为内容渲染。传了 tabList 时,TabPane 子元素被忽略,其余节点是当前标签页的内容。 | TypeReactNode | Array<ReactNode> | [] |
| className | 根元素的类名。 | string | - |
| collapsible | 是否开启滚动折叠(仅水平模式)。传 auto 时在标签溢出或换行时自动折叠,放得下时自动退出。 | boolean | 'auto' | false |
| contentStyle | 内容区域外层的样式对象。 | CSSProperties | - |
| defaultActiveKey | 非受控时初始选中的 itemKey。不传时取第一个启用且有 itemKey 的标签页。 | string | - |
| dropdownProps | 折叠模式下,分别透传给起始侧(start)与末尾侧(end)箭头下拉菜单的 Dropdown 属性。 | TabsDropDownProps | - |
| keepDOM | 使用 TabPane 子元素时,是否渲染未激活面板的 DOM。为 false 时只渲染当前面板,没有切换动画。 | boolean | true |
| lazyRender | 懒渲染:面板被激活过才渲染内容,之后保留。 | boolean | false |
| more | 将末尾的一部分标签页收入「更多」下拉菜单。传数字时表示收入菜单的标签数;传对象时 count 为标签数,render 返回自定义触发器,dropdownProps 透传给下拉菜单。 | Typenumber | { count: number; render?: () => ReactNode; dropdownProps?: DropdownProps } | - |
| onChange | 切换标签页时触发,参数为新激活的 itemKey。 | Type(activeKey: string) => void | - |
| onTabClick | 单击,或用 Enter、Space 激活标签页时触发,参数为 itemKey 与事件;键盘激活时事件是 KeyboardEvent。 | Type(activeKey: string, e: MouseEvent | KeyboardEvent) => void | - |
| onTabClose | 关闭标签页时触发,参数为被关闭标签页的 itemKey。标签页的移除由使用方完成。 | Type(tabKey: string) => void | - |
| onVisibleTabsChange | 折叠模式下溢出项的可见状态变化时触发,参数为 Map<string, boolean>,键为 itemKey,值表示该标签页是否可见。 | TabBarProps['onVisibleTabsChange'] | - |
| preventScroll | 组件内部调用 focus 时,是否阻止浏览器滚动文档以显示新聚焦的元素。 | boolean | - |
| ref | 根元素 div 的引用。 | TypeReact.Ref<HTMLDivElement> | - |
| renderArrow | 替换折叠模式下的每个滚动箭头。参数依次为溢出的 items、位置 pos、点击处理函数 handleArrowClick 与默认箭头 defaultNode。 | TabBarProps['renderArrow'] | - |
| renderTabBar | 替换整个标签栏,每次渲染都会调用。参数为标签栏属性 tabBarProps 与默认标签栏组件 defaultTabBar。用它替换标签栏时,aria-label 与 aria-labelledby 在 tabBarProps 中,需要自行写在 role="tablist" 的元素上。 | Type(tabBarProps: TabBarProps, defaultTabBar: typeof TabBar) => ReactNode | - |
| showRestInDropdown | 折叠模式下,是否将收起的标签页展示在下拉菜单中。 | boolean | true |
| size | 标签栏尺寸,可选 small、medium 或 large;目前仅线条式(line)标签栏支持。 | TabSize | "large" |
| style | 根元素的样式对象。 | CSSProperties | - |
| tabBarClassName | 标签栏的类名。 | string | - |
| tabBarExtraContent | 标签栏的附加内容,位于 tablist 之外。 | ReactNode | - |
| tabBarStyle | 标签栏的样式对象。 | CSSProperties | - |
| tabList | 标签页的数据数组,每项含 itemKey、tab、icon、disabled、closable。只要传了数组(含空数组),children 就是当前标签页的内容,并优先于 TabPane 子元素。 | PlainTab[] | - |
| tabPaneMotion | 切换面板时是否使用动画。 | boolean | true |
| tabPosition | 标签栏位置:top 为水平,left 为垂直。 | TabPosition | "top" |
| type | 标签栏样式,可选 line、card、button、slash;slash 仅支持水平模式。 | TabType | "line" |
| visibleTabsStyle | 折叠模式下,整体滚动区域的样式对象。 | TabBarProps['visibleTabsStyle'] | - |
其他原生属性(如 id、data-*、onFocus)落在根元素 div 上;aria-label 与 aria-labelledby 由 Tabs 转给标签栏,落在 role="tablist" 元素上。
TabPane
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| children | 面板内容。 | React.ReactNode | - |
| className | 面板根元素(role="tabpanel")的类名。 | string | - |
| closable | 是否允许关闭该标签页,关闭时触发 Tabs 的 onTabClose。 | boolean | - |
| disabled | 是否禁用该标签页。 | boolean | - |
| icon | 标签栏中该标签的图标,由 Tabs 渲染。 | ReactNode | - |
| itemKey | 标签页的唯一标识,对应 Tabs 的 activeKey。 | string | - |
| ref | 面板根元素(role="tabpanel")的引用。 | TypeReact.Ref<HTMLDivElement> | - |
| style | 面板根元素的样式对象。 | CSSProperties | - |
| tab | 标签栏中该标签的内容,由 Tabs 渲染。 | ReactNode | - |
| tabIndex | 面板的 tabIndex,未设置时为 0。 | number | - |
其他原生属性(如 data-*、onFocus)落在面板根元素(role="tabpanel")上;id、role、aria-hidden 与 aria-labelledby 由组件生成,不会被覆盖。
TabItem
自定义标签栏(renderTabBar)中单个标签的组件,通过 Tabs.TabItem 使用。在 Tabs 内,它使用 Tabs 的键盘与关闭处理,但点击时不会自行选中标签页,需要在 onClick 中更新 activeKey。
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| className | 根元素的类名。 | string | - |
| closable | 是否显示关闭按钮。 | boolean | - |
| deleteTabItem | 点击关闭按钮时的处理函数,参数为 itemKey 与事件。在 Tabs 内默认使用 Tabs 的处理函数,通常无需设置。 | Type(tabKey: string, event: MouseEvent) => void | - |
| disabled | 是否禁用;禁用时点击与关闭按钮均不生效,关闭按钮仍会显示。 | boolean | - |
| handleKeyDown | 键盘处理函数,参数为事件、itemKey 与 closable。在 Tabs 内默认使用 Tabs 的键盘处理函数,通常无需设置。 | Type(event: React.KeyboardEvent, itemKey: string, closable: boolean) => void | - |
| icon | 标签图标;没有内容则不渲染图标。 | ReactNode | - |
| itemKey | 标签的唯一标识,对应 Tabs 的 activeKey。 | string | - |
| onClick | 单击标签时触发,参数为 itemKey 与事件;禁用时不触发。TabItem 本身不会选中标签页,需在回调中更新 Tabs 的 activeKey。 | Type(itemKey: string, e: MouseEvent) => void | - |
| ref | 标签根元素(role="tab")的引用。 | TypeReact.Ref<HTMLDivElement> | - |
| selected | 是否为选中状态,影响样式与 aria-selected。 | boolean | - |
| size | 尺寸,small 与 medium 会添加对应的类名。 | TabSize | - |
| tab | 标签内容。 | ReactNode | - |
| tabPosition | 位置,未设置时取所在 Tabs 的 tabPosition。 | TabPosition | - |
| type | 样式,未设置时取所在 Tabs 的 type。 | TabType | - |
其他原生属性落在根元素(role="tab")上;role、aria-selected、aria-disabled 与 tabIndex 由组件管理,在 Tabs 内 id 与 aria-controls 也由组件管理,均不会被覆盖。
Accessibility
ARIA
- 关于 role
- TabBar 中只包含 Tab 的元素对应的 role 为
tablist,切换箭头、「更多」和tabBarExtraContent在它之外 - TabBar 中的 Tab 对应的 role 为
tab - TabPane 对应的 role 为
tabpanel
- TabBar 中只包含 Tab 的元素对应的 role 为
- aria-label、aria-labelledby: 传给 Tabs 时落在
role="tablist"的元素上,用于给标签栏命名 - aria-orientation: 表明 TabBar 的方向,有
vertical和horizontal两种。当传入 tabPosition 为 left 时, aria-orientation 会被设置为vertical,tabPosition 为 top 时,设置为horizontal - aria-disabled: 当 TabPane 设置为 disabled 时,对应 Tab 的 aria-disabled 会被设置为 true
- aria-selected: 表明 Tab 是否被选中
- aria-controls: 指向 Tab 标签所控制的 TabPane;文档中只有当前选中项的面板时(使用
tabList,或keepDOM为 false),只有选中的 Tab 带有此属性 - aria-labelledby: 指向设置 TabPane 标签的元素
键盘和焦点
WAI-ARIA: https://www.w3.org/WAI/ARIA/apg/patterns/tabpanel/
- 选项卡可以被获取到焦点,但禁用的选项卡除外
- 键盘用户可以使用
Tab键,将焦点移动到已被选择的选项卡元素的选项卡面板上 - 当焦点位于水平选项卡列表中的选项卡元素上时,使用
左右箭头来切换选项(RTL 页面中左右箭头方向对调) - 当焦点位于垂直选项卡列表中的选项卡元素上时,使用
上下箭头来切换选项 - 当焦点位于选项卡列表中的未被激活的选项卡元素上时,可以使用
Space或Enter键来激活该选项卡 - 当键盘用户想要直接将焦点聚焦到选项卡列表中的最后一个选项卡元素时:
- Mac 用户:
fn+右箭头 - Windows 用户:
End
- Mac 用户:
- 当键盘用户想要直接将焦点聚焦到选项卡列表中的第一个选项卡元素时:
- Mac 用户:
fn+左箭头 - Windows 用户:
Home
- Mac 用户:
- 使用
more时,默认的「更多」触发器是原生button,可以用Tab键聚焦,Enter或Space打开下拉菜单,并带有aria-haspopup="menu"与aria-expanded - 当选项卡允许被删除时:
- 用户可以使用
Delete或Backspace键删除选项卡,禁用的选项卡除外 - 删除后,焦点转移到被删除选项卡元素的后一个元素上;若被删除元素无后一个元素则转移到前一个元素上
- 用户可以使用
设计变量
| Sass 变量 | 值 | 用法 |
|---|---|---|
| $transition_duration-tabs_tab_line-border | var(--semi-transition_duration-none) | 线条式标签页标示线-边框-动画持续时间 |
| $transition_function-tabs_tab_line-border | var(--semi-transition_function-easeIn) | 线条式标签页标示线-边框-过渡曲线 |
| $transition_delay-tabs_tab_line-border | var(--semi-transition_delay-none) | 线条式标签页标示线-边框-延迟时间 |
| $transition_duration-tabs_tab_line-text | var(--semi-transition_duration-none) | 线条式标签页-文字-动画持续时间 |
| $transition_function-tabs_tab_line-text | var(--semi-transition_function-easeIn) | 线条式标签页-文字-过渡曲线 |
| $transition_delay-tabs_tab_line-text | var(--semi-transition_delay-none) | 线条式标签页-文字-延迟时间 |
| $transition_duration-tabs_tab_button-bg | var(--semi-transition_duration-none) | 按钮式标签页-背景色-动画持续时间 |
| $transition_function-tabs_tab_button-bg | var(--semi-transition_function-easeIn) | 按钮式标签页-背景色-过渡曲线 |
| $transition_delay-tabs_tab_button-bg | var(--semi-transition_delay-none) | 按钮式标签页-背景色-延迟时间 |
| $transition_duration-tabs_tab_card-bg | var(--semi-transition_duration-none) | 卡片式标签页文字-背景色-动画持续时间 |
| $transition_function-tabs_tab_card-bg | var(--semi-transition_function-easeIn) | 卡片式标签页文字-背景色-过渡曲线 |
| $transition_delay-tabs_tab_card-bg | var(--semi-transition_delay-none) | 卡片式标签页文字-背景色-延迟时间 |
| $transform_scale-tabs_tab_line-item | var(--semi-transform_scale-none) | 线条式标签页item 放大 |
| $transform_scale-tabs_tab_button-item | var(--semi-transform_scale-none) | 按钮式标签页item 放大 |
| $transform_scale-tabs_tab_card-item | var(--semi-transform_scale-none) | 线条式标签页item 放大 |
| $animation_transform_translateX-tabs_tabPanel-leftShow | 60px | 左侧展示时,tabPanel的水平偏移值 |
| $animation_transform_translateX-tabs_tabPanel-rightShow | -60px | 右侧展示时,tabPanel的水平偏移值 |
| $animation_opacity-tabs_tabPanel_show | 0 | tabPanel的动画开始时透明度 |
| $animation_duration-tabs_tabPanel-show | 200ms | tabPanel的展示动画持续时间 |
| $animation_function-tabs_tabPanel-show | ease-in-out | tabPanel的展示动画曲线 |
| $animation_delay-tabs_tabPanel-show | 0s | tabPanel的展示动画延迟时间 |
| $color-tabs_tab_line_default-border-default | var(--semi-color-border) | 线条式页签轨道颜色 - 默认 |
| $color-tabs_tab_line_default-text-default | var(--semi-color-text-2) | 线条式页签文本颜色 - 默认 |
| $color-tabs_tab_line_default-text-hover | var(--semi-color-text-0) | 线条式页签文本颜色 - 悬浮 |
| $color-tabs_tab_line_default-border-hover | var(--semi-color-fill-0) | 线条式页签标示线颜色 - 悬浮 |
| $color-tabs_tab_line_default-text-active | var(--semi-color-text-0) | 线条式页签文本颜色 - 按下 |
| $color-tabs_tab_line_default-border-active | var(--semi-color-fill-1) | 线条式页签标示线颜色 - 按下 |
| $color-tabs_tab_line_selected-text-default | var(--semi-color-text-0) | 线条式页签文本颜色 - 选中 |
| $color-tabs_tab_line_indicator_selected-icon-default | var(--semi-color-primary) | 线条式页签标示线颜色 - 选中 |
| $color-tabs_tab_line_vertical_selected-bg-default | var(--semi-color-primary-light-default) | 垂直线条式页签背景颜色 - 选中 |
| $color-tabs_tab_line_vertical-bg-hover | var(--semi-color-fill-0) | 垂直线条式页签背景颜色 - 悬浮 |
| $color-tabs_tab_line_vertical-bg-active | var(--semi-color-fill-1) | 垂直线条式页签背景颜色 - 按下 |
| $color-tabs_tab_line_disabled-text-default | var(--semi-color-disabled-text) | 禁用线条式页签文本颜色 - 默认 |
| $color-tabs_tab_line_disabled-text-hover | var(--semi-color-disabled-text) | 禁用线条式页签文本颜色 - 悬浮 |
| $color-tabs_tab_card_default-border-default | var(--semi-color-border) | 卡片式页签容器底部长线颜色 - 默认 |
| $color-tabs_tab_button_selected-bg-default | var(--semi-color-primary-light-default) | 按钮式页签背景颜色 - 选中 |
| $color-tabs_tab_button_selected-text-default | var(--semi-color-primary) | 按钮式页签文本颜色 - 选中 |
| $color-tabs_tab_button-text-default | var(--semi-color-text-2) | 按钮式页签文本颜色 - 默认 |
| $color-tabs_tab_button-bg-hover | var(--semi-color-fill-0) | 按钮式页签背景颜色 - 悬浮 |
| $color-tabs_tab_button-bg-active | var(--semi-color-fill-1) | 按钮式页签背景颜色 - 按下 |
| $color-tabs_tab_card_indicator_selected-icon-default | var(--semi-color-border) | 卡片式页签选中页签描边 |
| $color-tabs_tab_card-bg-hover | var(--semi-color-fill-0) | 卡片式页签背景颜色 - 悬浮 |
| $color-tabs_tab_card_selected-bg-default | var(--semi-color-bg-1) | 卡片式页签背景颜色 - 选中 |
| $color-tabs_tab_card-bg-active | var(--semi-color-fill-1) | 卡片式页签背景颜色 -按下 |
| $color-tabs_tab-icon-default | var(--semi-color-text-2) | 页签图标颜色 - 默认 |
| $color-tabs_tab-icon-hover | var(--semi-color-text-0) | 页签图标颜色 - 悬浮 |
| $color-tabs_tab-icon-active | var(--semi-color-text-0) | 页签图标颜色 - 按下 |
| $color-tabs_tab_selected-icon-default | var(--semi-color-primary) | 页签图标颜色 - 选中 |
| $color-tabs_tab-outline-focus | $color-focus-ring | 页签轮廓 - 聚焦 |
| $color-tabs_tab-pane-text-default | var(--semi-color-text-0) | 标签页内容文本颜色 - 默认 |
| $color-tabs_tab-pane_arrow-text-default | var(--semi-color-primary) | 滚动折叠箭头颜色 - 默认 |
| $color-tabs_tab-pane_arrow-border-default | transparent | 滚动折叠箭头边框颜色 - 默认 |
| $color-tabs_tab-pane_arrow-bg-default | transparent | 滚动折叠箭头背景色 - 默认 |
| $color-tabs_tab-pane_arrow-text-hover | var(--semi-color-primary) | 滚动折叠箭头颜色 - 悬浮 |
| $color-tabs_tab-pane_arrow-border-hover | transparent | 滚动折叠箭头边框颜色 - 悬浮 |
| $color-tabs_tab-pane_arrow-text-active | var(--semi-color-primary) | 滚动折叠箭头颜色 - 按下 |
| $color-tabs_tab-pane_arrow-border-active | transparent | 滚动折叠箭头边框颜色 - 按下 |
| $color-tabs_tab-pane_arrow_disabled-bg-default | transparent | |
| $color-tabs_tab-pane_arrow_disabled-bg-hover | transparent | |
| $color-tabs_tab-pane_arrow_disabled-text-default | var(--semi-color-disabled-text) | |
| $color-tabs_tab-pane_arrow_disabled-text-hover | var(--semi-color-disabled-text) | |
| $color-tabs_tab_slash_line | var(--semi-color-text-2) | 斜线式页签分割线颜色 |
| $font-tabs_tab-fontWeight | $font-weight-regular | 页签文本字重 - 默认 |
| $font-tabs_tab_active-fontWeight | $font-weight-bold | 页签文本字重 - 选中 |
| $height-tabs_overflow_list | 300px | 页签折叠收起菜单高度 |
| $width-tabs_bar_line-border | $border-thickness-control | 线条式页签底部分割线宽度 |
| $width-tabs_bar_line_tab-border | 2px | 页签标示线宽度 |
| $width-tabs_bar_card-border | $border-thickness-control | 卡片式页签容器底部长线宽度 |
| $width-tabs-outline | $width-focus-ring | 聚焦轮廓宽度 |
| $width-tabs-outline-offset | -2px | 聚焦轮廓偏移宽度 |
| $width-tabs_bar_line-outline-offset | -1px | 线条式页签聚焦轮廓偏移宽度 |
| $width-tabs_tab-pane_arrow-border | 0px | 滚动折叠箭头边框宽度 |
| $width-tabs_tab_slash_line | 8px | 斜线式页签分割线宽度 |
| $height-tabs_tab_slash_line | 14px | 斜线式页签分割线高度 |
| $height-tabs_bar_extra_large | 50px | 大尺寸页签高度 |
| $font-tabs_bar_extra_large-lineHeight | $height-tabs_bar_extra_large | 大尺寸页签文字行高 |
| $height-tabs_bar_extra_small | 36px | 小尺寸页签高度 |
| $font-tabs_bar_extra_small-lineHeight | $height-tabs_bar_extra_small | 小尺寸页签文字行高 |
| $spacing-tabs_tab-more_trigger_icon-marginLeft | 8px | |
| $spacing-tabs_tab-more_trigger_icon-marginRight | 8px | |
| $spacing-tabs_tab-more_trigger_icon-marginTop | 0px | |
| $spacing-tabs_tab-more_trigger_icon-marginBottom | 0px | |
| $spacing-tabs_tab-pane_arrow | 8px | 滚动折叠箭头内边距 |
| $spacing-tabs_bar_extra-paddingY | 0px | 附加操作垂直内边距 |
| $spacing-tabs_bar_extra-paddingX | 5px | 附加操作水平内边距 |
| $spacing-tabs_tab_icon-marginRight | $spacing-tight | 附加操作垂直内边距 |
| $spacing-tabs_tab_icon-top | 3px | 页签图标顶部位置 |
| $spacing-tabs_overflow_icon-marginRight | 4px | 页签折叠切换按钮右侧外边距 |
| $spacing-tabs_overflow_icon-marginLeft | 4px | 页签折叠切换按钮左侧外边距 |
| $spacing-tabs_bar_line_tab-paddingTop | $spacing-base | 线条式页签 |
| $spacing-tabs_bar_line_tab-paddingRight | $spacing-extra-tight | 线条式页签右侧内边距 |
| $spacing-tabs_bar_line_tab-paddingBottom | $spacing-base - $width-tabs_bar_line_tab-border | 线条式页签底部内边距 |
| $spacing-tabs_bar_line_tab-paddingLeft | $spacing-extra-tight | 线条式页签左侧内边距 |
| $spacing-tabs_bar_line_tab-marginRight | $spacing-loose | 线条式页签右侧外边距 |
| $spacing-tabs_bar_line_tab_small-paddingTop | $spacing-tight | 小尺寸线条式页签顶部内边距 |
| $spacing-tabs_bar_line_tab_small-paddingRight | $spacing-extra-tight | 小尺寸线条式页签右侧内边距 |
| $spacing-tabs_bar_line_tab_small-paddingBottom | $spacing-tight - $width-tabs_bar_line_tab-border | 小尺寸线条式页签底部内边距 |
| $spacing-tabs_bar_line_tab_small-paddingLeft | $spacing-extra-tight | 小尺寸线条式页签左侧内边距 |
| $spacing-tabs_bar_line_tab_medium-paddingTop | $spacing-base-tight | 中等尺寸线条式页签顶部内边距 |
| $spacing-tabs_bar_line_tab_medium-paddingRight | $spacing-extra-tight | 中等尺寸线条式页签右侧内边距 |
| $spacing-tabs_bar_line_tab_medium-paddingBottom | $spacing-base-tight - $width-tabs_bar_line_tab-border | 中等尺寸线条式页签底部内边距 |
| $spacing-tabs_bar_line_tab_medium-paddingLeft | $spacing-extra-tight | 中等尺寸线条式页签左侧内边距 |
| $spacing-tabs_bar_line_tab_left-padding | 12px | 垂直线条式页签左侧内边距 |
| $spacing-tabs_bar_line_tab_left_small-padding | $spacing-tight - 2px | 小尺寸垂直线条式页签左侧内边距 |
| $spacing-tabs_bar_line_tab_left_medium-padding | $spacing-base-tight - 2px | 中等尺寸垂直线条式页签左侧内边距 |
| $spacing-tabs_bar_slash_tab-paddingY | 12px | 斜线式页签上下内边距 |
| $spacing-tabs_bar_slash_tab-paddingX | 0px | 斜线式页签水平内边距 |
| $spacing-tabs_bar_slash-marginRight | 16px | 斜线式页签右侧外边距 |
| $spacing-tabs_bar_slash_line_marginLeft | 16px | 斜线式页签斜线左侧外边距 |
| $spacing-tabs_bar_slash_line_marginTop | 3px | 斜线式页签斜线顶部外边距 |
| $spacing-tabs_bar_slash_line_marginBottom | 3px | 斜线式页签斜线底部外边距 |
| $spacing-tabs_content-paddingY | 5px | 页签内容区垂直方向内边距 |
| $spacing-tabs_content-paddingX | 0 | 页签内容区水平方向内边距 |
| $spacing-tabs_content_left-paddingX | 5px | 垂直页签内容区垂直方向内边距 |
| $spacing-tabs_content_left-paddingY | 0 | 垂直页签内容区水平方向内边距 |
| $spacing-tabs_bar_card_tab-marginRight | $spacing-tight | 卡片式页签右侧外边距 |
| $spacing-tabs_bar_card_tab_active-paddingTop | $spacing-tight | 卡片式选中页签顶部内边距 |
| $spacing-tabs_bar_card_tab_active-paddingBottom | $spacing-tight - 1px | 卡片式选中页签底部内边距 |
| $spacing-tabs_bar_card_tab_active-paddingLeft | $spacing-base-tight | 卡片式选中页签左侧内边距 |
| $spacing-tabs_bar_card_tab_active-paddingRight | $spacing-base-tight | 卡片式选中页签右侧内边距 |
| $spacing-tabs_bar_card_tab_left-marginBottom | $spacing-tight | 垂直卡片式页签底部外边距 |
| $spacing-tabs_bar_card_tab_left_active-paddingY | $spacing-tight | 垂直卡片式选中页签垂直内边距 |
| $spacing-tabs_bar_card_tab_left_active-paddingX | $spacing-base-tight | 垂直卡片式选中页签水平内边距 |
| $spacing-tabs_bar_card_tab-paddingY | $spacing-tight | 卡片式选中页签垂直内边距 |
| $spacing-tabs_bar_card_tab-paddingX | $spacing-base-tight | 卡片式选中页签水平内边距 |
| $spacing-tabs_bar_button_tab_left-marginBottom | $spacing-tight | 垂直按钮式页签底部外边距 |
| $spacing-tabs_bar_button_tab-marginRight | $spacing-tight | 按钮式页签右侧外边距 |
| $spacing-tabs_bar_button_tab-paddingY | $spacing-tight | 按钮式页签垂直内边距 |
| $spacing-tabs_bar_button_tab-paddingX | $spacing-base-tight | 按钮式页签水平内边距 |
| $radius-tabs_tab_card | var(--semi-border-radius-small) var(--semi-border-radius-small) 0 0 | 卡片式页签四向圆角 |
| $radius-tabs_tab_card_left | var(--semi-border-radius-small) 0 0 var(--semi-border-radius-small) | 垂直卡片式页签四向圆角 |
| $radius-tabs_tab_button | var(--semi-border-radius-small) | 按钮式页签圆角 |
| $font-tabs_bar_large-fontSize | $font-size-regular | 大号模式 字体大小 |
| $font-tabs_bar_small-fontSize | $font-size-regular | 小号模式 字体大小 |
| $font-tabs_bar_medium-fontSize | $font-size-regular | 中等模式 字体大小 |
文案规范
- 标签文案需要准确清晰地解释标签内容
- 用简短的,易区分的标签
- 尽量保持在一个词以内
FAQ
-
为什么在 Tabs 中使用 Typography 的省略 ellipsis 失效?
因为 Tabs 渲染 TabPane 时,默认是全部渲染 display: none。此时这些组件无法获取到正确的宽度或高度值。建议开启 lazyRender,或者关闭 keepDOM。
-
为什么在 Tabs 中使用 Collapse/Collapsible/Resizable Table 等组件的高度或宽度值不对?
原因同上,另外如果 collapse 不需要动画,也可以把它的
motion设为 false 来关闭动画效果。此时无需获取组件的高度。