Tabs
Tabs make it easy to switch between different views.
When To Use#
Ant Design has 3 types of Tabs for different situations.
Card Tabs: for managing too many closeable views.
Normal Tabs: for functional aspects of a page.
RadioButton: for secondary tabs.
Examples
Content of Tab Pane 1
import { Tabs } from 'antd';
const TabPane = Tabs.TabPane;
function callback(key) {
console.log(key);
}
ReactDOM.render(
<Tabs defaultActiveKey="1" onChange={callback}>
<TabPane tab="Tab 1" key="1">Content of Tab Pane 1</TabPane>
<TabPane tab="Tab 2" key="2">Content of Tab Pane 2</TabPane>
<TabPane tab="Tab 3" key="3">Content of Tab Pane 3</TabPane>
</Tabs>
, mountNode);
Tab 1
import { Tabs } from 'antd';
const TabPane = Tabs.TabPane;
ReactDOM.render(
<Tabs defaultActiveKey="1">
<TabPane tab="Tab 1" key="1">Tab 1</TabPane>
<TabPane tab="Tab 2" disabled key="2">Tab 2</TabPane>
<TabPane tab="Tab 3" key="3">Tab 3</TabPane>
</Tabs>
, mountNode);
Tab 2
import { Tabs, Icon } from 'antd';
const TabPane = Tabs.TabPane;
ReactDOM.render(
<Tabs defaultActiveKey="2">
<TabPane tab={<span><Icon type="apple" />Tab 1</span>} key="1">
Tab 1
</TabPane>
<TabPane tab={<span><Icon type="android" />Tab 2</span>} key="2">
Tab 2
</TabPane>
</Tabs>
, mountNode);
Content of tab 1
import { Tabs, Radio } from 'antd';
const TabPane = Tabs.TabPane;
class SlidingTabsDemo extends React.Component {
constructor(props) {
super(props);
this.state = {
mode: 'top',
};
}
handleModeChange = (e) => {
const mode = e.target.value;
this.setState({ mode });
}
render() {
const { mode } = this.state;
return (
<div>
<Radio.Group onChange={this.handleModeChange} value={mode} style={{ marginBottom: 8 }}>
<Radio.Button value="top">Horizontal</Radio.Button>
<Radio.Button value="left">Vertical</Radio.Button>
</Radio.Group>
<Tabs
defaultActiveKey="1"
tabPosition={mode}
style={{ height: 220 }}
>
<TabPane tab="Tab 1" key="1">Content of tab 1</TabPane>
<TabPane tab="Tab 2" key="2">Content of tab 2</TabPane>
<TabPane tab="Tab 3" key="3">Content of tab 3</TabPane>
<TabPane tab="Tab 4" key="4">Content of tab 4</TabPane>
<TabPane tab="Tab 5" key="5">Content of tab 5</TabPane>
<TabPane tab="Tab 6" key="6">Content of tab 6</TabPane>
<TabPane tab="Tab 7" key="7">Content of tab 7</TabPane>
<TabPane tab="Tab 8" key="8">Content of tab 8</TabPane>
<TabPane tab="Tab 9" key="9">Content of tab 9</TabPane>
<TabPane tab="Tab 10" key="10">Content of tab 10</TabPane>
<TabPane tab="Tab 11" key="11">Content of tab 11</TabPane>
</Tabs>
</div>
);
}
}
ReactDOM.render(<SlidingTabsDemo />, mountNode);
Content of tab 1
import { Tabs, Button } from 'antd';
const TabPane = Tabs.TabPane;
const operations = <Button>Extra Action</Button>;
ReactDOM.render(
<Tabs tabBarExtraContent={operations}>
<TabPane tab="Tab 1" key="1">Content of tab 1</TabPane>
<TabPane tab="Tab 2" key="2">Content of tab 2</TabPane>
<TabPane tab="Tab 3" key="3">Content of tab 3</TabPane>
</Tabs>
, mountNode);
Content of tab 2
import { Tabs } from 'antd';
const TabPane = Tabs.TabPane;
ReactDOM.render(
<Tabs defaultActiveKey="2" size="small">
<TabPane tab="Tab 1" key="1">Content of tab 1</TabPane>
<TabPane tab="Tab 2" key="2">Content of tab 2</TabPane>
<TabPane tab="Tab 3" key="3">Content of tab 3</TabPane>
</Tabs>
, mountNode);
Tab position:
top
Content of Tab 1
import { Tabs, Select } from 'antd';
const TabPane = Tabs.TabPane;
const Option = Select.Option;
class Demo extends React.Component {
state = {
tabPosition: 'top',
}
changeTabPosition = (tabPosition) => {
this.setState({ tabPosition });
}
render() {
return (
<div>
<div style={{ marginBottom: 16 }}>
Tab position:
<Select
value={this.state.tabPosition}
onChange={this.changeTabPosition}
dropdownMatchSelectWidth={false}
>
<Option value="top">top</Option>
<Option value="bottom">bottom</Option>
<Option value="left">left</Option>
<Option value="right">right</Option>
</Select>
</div>
<Tabs tabPosition={this.state.tabPosition}>
<TabPane tab="Tab 1" key="1">Content of Tab 1</TabPane>
<TabPane tab="Tab 2" key="2">Content of Tab 2</TabPane>
<TabPane tab="Tab 3" key="3">Content of Tab 3</TabPane>
</Tabs>
</div>
);
}
}
ReactDOM.render(<Demo />, mountNode);
Content of Tab Pane 1
import { Tabs } from 'antd';
const TabPane = Tabs.TabPane;
function callback(key) {
console.log(key);
}
ReactDOM.render(
<Tabs onChange={callback} type="card">
<TabPane tab="Tab 1" key="1">Content of Tab Pane 1</TabPane>
<TabPane tab="Tab 2" key="2">Content of Tab Pane 2</TabPane>
<TabPane tab="Tab 3" key="3">Content of Tab Pane 3</TabPane>
</Tabs>
, mountNode);
Content of Tab 1
import { Tabs } from 'antd';
const TabPane = Tabs.TabPane;
class Demo extends React.Component {
constructor(props) {
super(props);
this.newTabIndex = 0;
const panes = [
{ title: 'Tab 1', content: 'Content of Tab 1', key: '1', closable: false },
{ title: 'Tab 2', content: 'Content of Tab 2', key: '2' },
];
this.state = {
activeKey: panes[0].key,
panes,
};
}
onChange = (activeKey) => {
this.setState({ activeKey });
}
onEdit = (targetKey, action) => {
this[action](targetKey);
}
add = () => {
const panes = this.state.panes;
const activeKey = `newTab${this.newTabIndex++}`;
panes.push({ title: 'New Tab', content: 'Content of new Tab', key: activeKey });
this.setState({ panes, activeKey });
}
remove = (targetKey) => {
let activeKey = this.state.activeKey;
let lastIndex;
this.state.panes.forEach((pane, i) => {
if (pane.key === targetKey) {
lastIndex = i - 1;
}
});
const panes = this.state.panes.filter(pane => pane.key !== targetKey);
if (lastIndex >= 0 && activeKey === targetKey) {
activeKey = panes[lastIndex].key;
}
this.setState({ panes, activeKey });
}
render() {
return (
<Tabs
onChange={this.onChange}
activeKey={this.state.activeKey}
type="editable-card"
onEdit={this.onEdit}
>
{this.state.panes.map(pane => <TabPane tab={pane.title} key={pane.key} closable={pane.closable}>{pane.content}</TabPane>)}
</Tabs>
);
}
}
ReactDOM.render(<Demo />, mountNode);
Content of Tab Pane 1
Content of Tab Pane 1
Content of Tab Pane 1
import { Tabs } from 'antd';
const TabPane = Tabs.TabPane;
ReactDOM.render(
<div className="card-container">
<Tabs type="card">
<TabPane tab="Tab Title 1" key="1">
<p>Content of Tab Pane 1</p>
<p>Content of Tab Pane 1</p>
<p>Content of Tab Pane 1</p>
</TabPane>
<TabPane tab="Tab Title 2" key="2">
<p>Content of Tab Pane 2</p>
<p>Content of Tab Pane 2</p>
<p>Content of Tab Pane 2</p>
</TabPane>
<TabPane tab="Tab Title 3" key="3">
<p>Content of Tab Pane 3</p>
<p>Content of Tab Pane 3</p>
<p>Content of Tab Pane 3</p>
</TabPane>
</Tabs>
</div>
, mountNode);
.card-container > .ant-tabs-card > .ant-tabs-content {
height: 120px;
margin-top: -16px;
}
.card-container > .ant-tabs-card > .ant-tabs-content > .ant-tabs-tabpane {
background: #fff;
padding: 16px;
}
.card-container > .ant-tabs-card > .ant-tabs-bar {
border-color: #fff;
}
.card-container > .ant-tabs-card > .ant-tabs-bar .ant-tabs-tab {
border-color: transparent;
background: transparent;
}
.card-container > .ant-tabs-card > .ant-tabs-bar .ant-tabs-tab-active {
border-color: #fff;
background: #fff;
}
Content of Tab Pane 1
import { Tabs, Button } from 'antd';
const TabPane = Tabs.TabPane;
class Demo extends React.Component {
constructor(props) {
super(props);
this.newTabIndex = 0;
const panes = [
{ title: 'Tab 1', content: 'Content of Tab Pane 1', key: '1' },
{ title: 'Tab 2', content: 'Content of Tab Pane 2', key: '2' },
];
this.state = {
activeKey: panes[0].key,
panes,
};
}
onChange = (activeKey) => {
this.setState({ activeKey });
}
onEdit = (targetKey, action) => {
this[action](targetKey);
}
add = () => {
const panes = this.state.panes;
const activeKey = `newTab${this.newTabIndex++}`;
panes.push({ title: 'New Tab', content: 'New Tab Pane', key: activeKey });
this.setState({ panes, activeKey });
}
remove = (targetKey) => {
let activeKey = this.state.activeKey;
let lastIndex;
this.state.panes.forEach((pane, i) => {
if (pane.key === targetKey) {
lastIndex = i - 1;
}
});
const panes = this.state.panes.filter(pane => pane.key !== targetKey);
if (lastIndex >= 0 && activeKey === targetKey) {
activeKey = panes[lastIndex].key;
}
this.setState({ panes, activeKey });
}
render() {
return (
<div>
<div style={{ marginBottom: 16 }}>
<Button onClick={this.add}>ADD</Button>
</div>
<Tabs
hideAdd
onChange={this.onChange}
activeKey={this.state.activeKey}
type="editable-card"
onEdit={this.onEdit}
>
{this.state.panes.map(pane => <TabPane tab={pane.title} key={pane.key}>{pane.content}</TabPane>)}
</Tabs>
</div>
);
}
}
ReactDOM.render(<Demo />, mountNode);
API#
Tabs#
Property | Description | Type | Default |
---|---|---|---|
activeKey | Current TabPane's key | string | - |
defaultActiveKey | Initial active TabPane's key, if activeKey is not set. | string | - |
onChange | Callback executed when active tab is changed | Function | - |
onTabClick | Callback executed when tab is clicked | Function | - |
onPrevClick | Callback executed when prev button is clicked | Function | - |
onNextClick | Callback executed when next button is clicked | Function | - |
tabBarExtraContent | Extra content in tab bar | React.ReactNode | - |
tabBarStyle | Tab bar style object | object | - |
type | Basic style of tabs | line | card | editable-card | line |
size | Tab bar size. Only works while type="line" . | default | small | default |
tabPosition | Position of tabs | top | right | bottom | left | top |
onEdit | Callback executed when tab is added or removed. Only works while type="editable-card" | (targetKey, action): void | - |
hideAdd | Hide plus icon or not. Only works while type="editable-card" | boolean | false |
animated | Whether to change tabs with animation. Only works while tabPosition="top"\|"bottom" | boolean | {inkBar:boolean, tabPane:boolean} | true , false when type="card" |
Tabs.TabPane#
Property | Description | Type | Default |
---|---|---|---|
key | TabPane's key | string | - |
tab | Show text in TabPane's head | string|ReactNode | - |
forceRender | Forced render of content in tabs, not lazy render after clicking on tabs | boolean | false |