Tabs
Tabs are used to organize content by grouping similar information on the same page.Default
The default form of tabs.
Tab 1
Tab 2
Tab 3
This is the content area of the first tab.
/**
* @jsxRuntime classic
* @jsx jsx
*/
import { type ReactNode } from 'react';
import { css, jsx } from '@compiled/react';
import Tabs, { Tab, TabList, TabPanel } from '@atlaskit/tabs';
import { token } from '@atlaskit/tokens';
const panelStyles = css({
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'column',
flexGrow: 1,
backgroundColor: token('color.background.neutral'),
borderRadius: '3px',
color: token('color.text.subtlest'),
font: token('font.heading.xxlarge'),
marginBlockEnd: token('space.100', '8px'),
marginBlockStart: token('space.200', '16px'),
paddingBlockEnd: token('space.400', '32px'),
paddingBlockStart: token('space.400', '32px'),
paddingInlineEnd: token('space.400', '32px'),
paddingInlineStart: token('space.400', '32px'),
});
export const Panel = ({ children, testId }: { children: ReactNode; testId?: string }) => (
<div css={panelStyles} data-testid={testId}>
{children}
</div>
);
export default function TabsDefaultExample() {
return (
<Tabs onChange={(index) => console.log('Selected Tab', index + 1)} id="default">
<TabList>
<Tab>Tab 1</Tab>
<Tab>Tab 2</Tab>
<Tab>Tab 3</Tab>
</TabList>
<TabPanel>
<Panel>This is the content area of the first tab.</Panel>
</TabPanel>
<TabPanel>
<Panel>This is the content area of the second tab.</Panel>
</TabPanel>
<TabPanel>
<Panel>This is the content area of the third tab.</Panel>
</TabPanel>
</Tabs>
);
}
Controlled
Tabs can be used as a controlled component.
Tab 1
Tab 2
Tab 3
This is the content area of the first tab.
/**
* @jsxRuntime classic
* @jsx jsx
*/
import { type ReactNode, useCallback, useState } from 'react';
import { css, jsx } from '@compiled/react';
import Button from '@atlaskit/button/new';
import { Box } from '@atlaskit/primitives/compiled';
import Tabs, { Tab, TabList, TabPanel } from '@atlaskit/tabs';
import { type SelectedType } from '@atlaskit/tabs/types';
import { token } from '@atlaskit/tokens';
const panelStyles = css({
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'column',
flexGrow: 1,
backgroundColor: token('color.background.neutral'),
borderRadius: '3px',
color: token('color.text.subtlest'),
font: token('font.heading.xxlarge'),
marginBlockEnd: token('space.100', '8px'),
marginBlockStart: token('space.200', '16px'),
paddingBlockEnd: token('space.400', '32px'),
paddingBlockStart: token('space.400', '32px'),
paddingInlineEnd: token('space.400', '32px'),
paddingInlineStart: token('space.400', '32px'),
});
export const Panel = ({ children, testId }: { children: ReactNode; testId?: string }) => (
<div css={panelStyles} data-testid={testId}>
{children}
</div>
);
export default function TabsControlledExample() {
const [selected, setSelected] = useState(0);
const handleUpdate = useCallback((index: SelectedType) => setSelected(index), [setSelected]);
return (
<Box>
<Tabs onChange={handleUpdate} selected={selected} id="controlled">
<TabList>
<Tab>Tab 1</Tab>
<Tab>Tab 2</Tab>
<Tab>Tab 3</Tab>
</TabList>
<TabPanel>
<Panel>This is the content area of the first tab.</Panel>
</TabPanel>
<TabPanel>
<Panel>This is the content area of the second tab.</Panel>
</TabPanel>
<TabPanel>
<Panel>This is the content area of the third tab.</Panel>
</TabPanel>
</Tabs>
<Button isDisabled={selected === 2} onClick={() => handleUpdate(2)}>
Select the last tab
</Button>
</Box>
);
}
Customizing tab
Wrapping tab
You can wrap a tab in other presentational components. In this example we have added a tooltip to each tab.
Tab 1
Tab 2
Tab 3
This is the content area of the first tab.
/**
* @jsxRuntime classic
* @jsx jsx
*/
import { type ReactNode } from 'react';
import { css, jsx } from '@compiled/react';
import Tabs, { Tab, TabList, TabPanel } from '@atlaskit/tabs';
import { token } from '@atlaskit/tokens';
import Tooltip from '@atlaskit/tooltip';
const panelStyles = css({
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'column',
flexGrow: 1,
backgroundColor: token('color.background.neutral'),
borderRadius: '3px',
color: token('color.text.subtlest'),
font: token('font.heading.xxlarge'),
marginBlockEnd: token('space.100', '8px'),
marginBlockStart: token('space.200', '16px'),
paddingBlockEnd: token('space.400', '32px'),
paddingBlockStart: token('space.400', '32px'),
paddingInlineEnd: token('space.400', '32px'),
paddingInlineStart: token('space.400', '32px'),
});
export const Panel = ({ children }: { children: ReactNode }) => (
<div css={panelStyles}>{children}</div>
);
const TooltipTab = ({ label, tooltip }: { label: string; tooltip: string }) => (
<Tooltip content={tooltip}>
<Tab>{label}</Tab>
</Tooltip>
);
const TabTooltipExample = () => (
<Tabs id="tooltip-tabs">
<TabList>
<TooltipTab label="Tab 1" tooltip="Tooltip for tab 1" />
<TooltipTab label="Tab 2" tooltip="Tooltip for tab 2" />
<TooltipTab label="Tab 3" tooltip="Tooltip for tab 3" />
</TabList>
<TabPanel>
<Panel>This is the content area of the first tab.</Panel>
</TabPanel>
<TabPanel>
<Panel>This is the content area of the second tab.</Panel>
</TabPanel>
<TabPanel>
<Panel>This is the content area of the third tab.</Panel>
</TabPanel>
</Tabs>
);
export default TabTooltipExample;
Custom tab
To customize a tab, call useTab
and spread those attributes onto the custom tab.
Tab 1
Tab 2
Tab 3
This is the content area of the first tab.
/**
* @jsxRuntime classic
* @jsx jsx
*/
import { type ReactNode } from 'react';
import { css } from '@compiled/react';
import { cssMap, jsx } from '@atlaskit/css';
import { Box } from '@atlaskit/primitives/compiled';
import Tabs, { TabList, TabPanel, useTab } from '@atlaskit/tabs';
import { token } from '@atlaskit/tokens';
const styles = cssMap({
customTab: {
font: token('font.body.small'),
},
});
const panelStyles = css({
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'column',
flexGrow: 1,
backgroundColor: token('color.background.neutral'),
borderRadius: '3px',
color: token('color.text.subtlest'),
font: token('font.heading.xxlarge'),
marginBlockEnd: token('space.100', '8px'),
marginBlockStart: token('space.200', '16px'),
paddingBlockEnd: token('space.400', '32px'),
paddingBlockStart: token('space.400', '32px'),
paddingInlineEnd: token('space.400', '32px'),
paddingInlineStart: token('space.400', '32px'),
});
export const Panel = ({ children }: { children: ReactNode }) => (
<div css={panelStyles}>{children}</div>
);
const CustomTab = ({ label }: { label: string }) => {
const tabAttributes = useTab();
return (
<Box xcss={styles.customTab} {...tabAttributes}>
{label}
</Box>
);
};
const TabCustomExample = () => (
<Tabs id="custom-tabs">
<TabList>
<CustomTab label="Tab 1" />
<CustomTab label="Tab 2" />
<CustomTab label="Tab 3" />
</TabList>
<TabPanel>
<Panel>This is the content area of the first tab.</Panel>
</TabPanel>
<TabPanel>
<Panel>This is the content area of the second tab.</Panel>
</TabPanel>
<TabPanel>
<Panel>This is the content area of the third tab.</Panel>
</TabPanel>
</Tabs>
);
export default TabCustomExample;
Customizing tab panel
To customize a tab panel, call useTabPanel
and spread those attributes onto the custom tab panel.
Tab 1
Tab 2
Tab 3
One
Body of tab one
/**
* @jsxRuntime classic
* @jsx jsx
*/
import { css, jsx } from '@compiled/react';
import { Box } from '@atlaskit/primitives/compiled';
import Tabs, { Tab, TabList, useTabPanel } from '@atlaskit/tabs';
import { token } from '@atlaskit/tokens';
const customPanelStyles = css({
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'column',
flexGrow: 1,
backgroundColor: token('color.background.neutral'),
borderRadius: '3px',
color: token('color.text.subtlest'),
font: token('font.heading.xxlarge'),
marginBlockEnd: token('space.100', '8px'),
marginBlockStart: token('space.200', '16px'),
paddingBlockEnd: token('space.400', '32px'),
paddingBlockStart: token('space.400', '32px'),
paddingInlineEnd: token('space.400', '32px'),
paddingInlineStart: token('space.400', '32px'),
// eslint-disable-next-line @atlaskit/design-system/no-nested-styles, @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Ignored via go/DSP-18766
'&&': {
paddingBlockEnd: token('space.400', '32px'),
paddingBlockStart: token('space.400', '32px'),
paddingInlineEnd: token('space.400', '32px'),
paddingInlineStart: token('space.400', '32px'),
},
});
const CustomTabPanel = ({ heading, body }: { heading: string; body: string }) => {
const tabPanelAttributes = useTabPanel();
return (
<div css={customPanelStyles} {...tabPanelAttributes}>
<Box as="span">{heading}</Box>
<p>{body}</p>
</div>
);
};
const TabPanelCustomExample = () => (
<Tabs id="custom-panel">
<TabList>
<Tab>Tab 1</Tab>
<Tab>Tab 2</Tab>
<Tab>Tab 3</Tab>
</TabList>
<CustomTabPanel heading="One" body="Body of tab one" />
<CustomTabPanel heading="Two" body="Body of tab two" />
<CustomTabPanel heading="Three" body="Body of tab three" />
</Tabs>
);
export default TabPanelCustomExample;