Version 0.10.0

Tabs

A component for toggling between related panels on the same page.

Usage#

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>

API reference#

Tabs#

Groups the tabs and the corresponding panels. Renders a <div> element.

PropTypeDefaultResponsive
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

Tab#

An individual interactive tab button that toggles the corresponding panel. Renders a <button> element.

PropTypeDefaultResponsive
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

Examples#

Simple tabs#

To connect the tabs with the panels, you need to use the id prop on the tab and the tab panel.

Settings panel content goes here
<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>

With deeply nested routes#

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>

Theming#

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-Tabs
  • bui-TabList
  • bui-TabListWrapper
  • bui-Tab
  • bui-TabActive
  • bui-TabHovered
  • bui-TabPanel

Changelog#

  • 0.9.0 - BREAKING: Changed className prop behavior to augment default styles instead of being ignored or overriding them.

Affected components:

  • Menu, MenuListBox, MenuAutocomplete, MenuAutocompleteListbox, MenuItem, MenuListBoxItem, MenuSection, MenuSeparator
  • Switch
  • Skeleton
  • FieldLabel
  • Header, HeaderToolbar
  • HeaderPage
  • Tabs, TabList, Tab, TabPanel

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 #31216
  • 0.8.0 - Making href mandatory in tabs that are part of a Header component #31343
  • 0.8.0 - Remove auto selection of tabs for tabs that all have href defined #31281
  • 0.7.2 - Making href mandatory in tabs that are part of a Header component #31343
  • 0.7.2 - Remove auto selection of tabs for tabs that all have href defined #31281
  • 0.7.2 - remove default selection of tab #31216
  • 0.4.0 - New Tabs component #29996