A component for toggling between related panels on the same page.
import { Tabs } from '@backstage/ui';
<Tabs>
<TabList>
<Tab id="tab-1">Tab 1</Tab>
<Tab id="tab-2">Tab 2</Tab>
<Tab id="tab-3">Tab 3</Tab>
</TabList>
<TabPanel id="tab-1">Content for Tab 1</TabPanel>
<TabPanel id="tab-2">Content for Tab 2</TabPanel>
<TabPanel id="tab-3">Content for Tab 3</TabPanel>
</Tabs>Groups the tabs and the corresponding panels. Renders a <div> element.
| Prop | Type | Default | Responsive |
|---|---|---|---|
| isDisabled | boolean | - | No |
| disabledKeys | string[] | - | No |
| selectedKey | stringnull | - | No |
| defaultSelectedKey | string | - | No |
| onSelectionChange | (key: string) => void | - | No |
| children | ReactNode | - | No |
| className | string | - | No |
| style | CSSProperties | - | No |
An individual interactive tab button that toggles the corresponding panel. Renders a <button> element.
| Prop | Type | Default | Responsive |
|---|---|---|---|
| id | string | - | No |
| isDisabled | boolean | - | No |
| href | string | - | No |
| hrefLang | string | - | No |
| target | HTMLAttributeAnchorTarget | - | No |
| rel | string | - | No |
| matchStrategy | exactprefix | - | No |
| onHoverStart | (e: HoverEvent) => void | - | No |
| onHoverEnd | (e: HoverEvent) => void | - | No |
| onHoverChange | (isHovering: boolean) => void | - | No |
| children | ReactNode | - | No |
| className | string | - | No |
| style | CSSProperties | - | No |
To connect the tabs with the panels, you need to use the id prop on the tab and the tab panel.
<Tabs>
<TabList>
<Tab id="settings">Settings</Tab>
<Tab id="profile">Profile</Tab>
<Tab id="preferences">Preferences</Tab>
</TabList>
<TabPanel id="settings">Settings panel content goes here</TabPanel>
<TabPanel id="profile">Profile panel content goes here</TabPanel>
<TabPanel id="preferences">Preferences panel content goes here</TabPanel>
</Tabs>You can use the href prop on the tab to make it a link. This will use the react-router under the hood to navigate to the tab. We automatically detect if this is an external URL and render a <a> element instead of a <button>.
Current URL is mocked to be: /tab2
Notice how the "Tab 2" tab is selected (highlighted) because it matches the current path.
<Tabs>
<TabList>
<Tab id="tab-1" href="/tab-1">Tab 1</Tab>
<Tab id="tab-2" href="/tab-2">Tab 2</Tab>
<Tab id="tab-3" href="/tab-3">Tab 3 With long title</Tab>
</TabList>
</Tabs>You can use the matchStrategy prop on the tab to control how the tab is matched to the current URL.
Current URL: /catalog/users/john/details
The "Catalog" tab is active because it uses prefix matching and the URL starts with "/catalog".
This works for any level of nesting under "/catalog".
<Tabs>
<TabList>
<Tab id="home" href="/home">Home</Tab>
<Tab id="catalog" href="/catalog" matchStrategy="prefix">Catalog</Tab>
<Tab id="mentorship" href="/mentorship" matchStrategy="prefix">Mentorship</Tab>
</TabList>
</Tabs>Our theming system is based on a mix between CSS classes, CSS variables and data attributes. If you want to customise this component, you can use one of these class names below.
bui-Tabsbui-TabListbui-TabListWrapperbui-Tabbui-TabActivebui-TabHoveredbui-TabPanel0.9.0 - BREAKING: Changed className prop behavior to augment default styles instead of being ignored or overriding them.Affected components:
If you were passing custom className values to any of these components that relied on the previous behavior, you may need to adjust your styles to account for the default classes now being applied alongside your custom classes. #31496
0.8.0 - remove default selection of tab #312160.8.0 - Making href mandatory in tabs that are part of a Header component #313430.8.0 - Remove auto selection of tabs for tabs that all have href defined #312810.7.2 - Making href mandatory in tabs that are part of a Header component #313430.7.2 - Remove auto selection of tabs for tabs that all have href defined #312810.7.2 - remove default selection of tab #312160.4.0 - New Tabs component #29996