Tabs

Switch between different views
Import

Usage

Gallery tab content
Color
Variant
TabPadding
xs
sm
md
lg
xl
Orientation
import { Tabs } from '@mantine/core';
import { Photo, MessageCircle, Settings } from 'tabler-icons-react';
function Demo() {
return (
<Tabs>
<Tabs.Tab label="Gallery" icon={<Photo size={14} />}>Gallery tab content</Tabs.Tab>
<Tabs.Tab label="Messages" icon={<MessageCircle size={14} />}>Messages tab content</Tabs.Tab>
<Tabs.Tab label="Settings" icon={<Settings size={14} />}>Settings tab content</Tabs.Tab>
</Tabs>
);
}

Controlled Tabs

import { useState } from 'react';
import { Tabs } from '@mantine/core';
function Demo() {
const [activeTab, setActiveTab] = useState(1);
return (
<Tabs active={activeTab} onTabChange={setActiveTab}>
<Tabs.Tab label="First">First tab content</Tabs.Tab>
<Tabs.Tab label="Second">Second tab content</Tabs.Tab>
<Tabs.Tab label="Third">Third tab content</Tabs.Tab>
</Tabs>
);
}

Tabs.Tab accepts an optional tabKey prop, if included the tabKey will be included as second argument in the onTabChange callback:

import { useState } from 'react';
import { Tabs } from '@mantine/core';
function Demo() {
const [activeTab, setActiveTab] = useState(1);
const onChange = (active: number, tabKey: string) => {
setActiveTab(active);
console.log('tabKey', tabKey);
};
return (
<Tabs active={activeTab} onTabChange={onChange}>
<Tabs.Tab label="First" tabKey="First">
First tab content
</Tabs.Tab>
<Tabs.Tab label="Second" tabKey="Second">
Second tab content
</Tabs.Tab>
<Tabs.Tab label="Third" tabKey="Third">
Third tab content
</Tabs.Tab>
</Tabs>
);
}

Tabs with icons

Add any React node as icon by setting icon prop on Tabs.Tab component. If icon prop is set, it is not necessary to pass label:

Chat here
import { Tabs } from '@mantine/core';
import { Settings, MessageCircle, Coin } from 'tabler-icons-react';
function Demo() {
return (
<Tabs>
<Tabs.Tab label="Chat" icon={<MessageCircle size={14} />}>Chat here</Tabs.Tab>
<Tabs.Tab label="Settings" icon={<Settings size={14} />}>Settings</Tabs.Tab>
<Tabs.Tab icon={<Coin size={14} />}>Get money!</Tabs.Tab>
</Tabs>
);
}

Change colors

Change color of individual tab by setting color property to Tabs.Tab component, or change color of all tabs by setting color on Tabs component. Color that you pass to these components should be defined in theme.colors.

Teal tab content
import { Tabs } from '@mantine/core';
function Demo() {
return (
<Tabs color="teal">
<Tabs.Tab label="Teal tab">Teal tab content</Tabs.Tab>
<Tabs.Tab label="Still teal">Teal tab #2</Tabs.Tab>
<Tabs.Tab label="Pink tab" color="pink">
Pink tab content
</Tabs.Tab>
</Tabs>
);
}

Tabs position

Tabs controls position is controlled with grow and position props. If grow property is set to true, controls will take 100% of available space and position property is ignored.

First tab content
Variant
import { Tabs } from '@mantine/core';
function Demo() {
return (
<Tabs>
<Tabs.Tab label="First">First tab content</Tabs.Tab>
<Tabs.Tab label="Second">Second tab content</Tabs.Tab>
<Tabs.Tab label="Third">Third tab content</Tabs.Tab>
</Tabs>
);
}

Tab component props

In addition to icon and label props shown before, Tab component accepts color, disabled and any other props from regular button (e.g. style, title, aria-, data-). color prop will override color defined in Tabs component.

First tab content
import { Tabs } from '@mantine/core';
function Demo() {
return (
<Tabs>
<Tabs.Tab label="First" title="Reveal hidden truth on long mouse over">
First tab content
</Tabs.Tab>
<Tabs.Tab label="Not allowed" disabled>
https://youtu.be/dQw4w9WgXcQ
</Tabs.Tab>
<Tabs.Tab label="Delete this?" color="red" style={{ fontWeight: 500 }}>
Yes, delete this
</Tabs.Tab>
</Tabs>
);
}

Add your styles with styles API

You can change styles of any element in button component with Styles API to match your design requirements. To remove all default styles set variant prop to unstyled:

import { TabsProps, Tabs } from '@mantine/core';
import { Photo, MessageCircle, Settings } from 'tabler-icons-react';
function StyledTabs(props: TabsProps) {
return (
<Tabs
variant="unstyled"
styles={(theme) => ({
tabControl: {
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[6] : theme.white,
color: theme.colorScheme === 'dark' ? theme.colors.dark[0] : theme.colors.gray[9],
border: `1px solid ${theme.colorScheme === 'dark' ? theme.colors.dark[6] : theme.colors.gray[4]}`,
fontSize: theme.fontSizes.md,
padding: `${theme.spacing.lg}px ${theme.spacing.xl}px`,
'&:not(:first-of-type)': {
borderLeft: 0,
},
'&:first-of-type': {
borderTopLeftRadius: theme.radius.md,
borderBottomLeftRadius: theme.radius.md,
},
'&:last-of-type': {
borderTopRightRadius: theme.radius.md,
borderBottomRightRadius: theme.radius.md,
},
},
tabActive: {
backgroundColor: theme.colors.blue[7],
borderColor: theme.colors.blue[7],
color: theme.white,
},
})}
{...props}
/>
);
}
function Demo() {
return (
<StyledTabs>
<Tabs.Tab label="Settings" icon={<Settings size={16} />} />
<Tabs.Tab label="Messages" icon={<MessageCircle size={16} />} />
<Tabs.Tab label="Gallery" icon={<Photo size={16} />} />
</StyledTabs>
);
}

Get tab control ref

import { useRef } from 'react';
import { Tabs } from '@mantine/core';
function Demo() {
const secondTabRef = useRef<HTMLButtonElement>();
return (
<Tabs>
<Tabs.Tab label="First">First tab content</Tabs.Tab>
<Tabs.Tab label="Second" ref={secondTabRef}>
Second tab content
</Tabs.Tab>
<Tabs.Tab label="Third">Third tab content</Tabs.Tab>
</Tabs>
);
}

Accessibility and usability

Tabs component follows WAI-ARIA recommendations on accessibility:

  • Use right and left arrow keys to change tabs when orientation is horizontal
  • Use down and up arrow keys to change tabs when orientation is vertical
  • Only selected tab control can be focused
  • All elements have correct roles: tab, tablist and tabpanel
  • aria-orientation is set based off orientation prop (default is horizontal)