Tabs (Motion)
Tabs are a navigational element that allows users to easily move between groups of related content.
Motion?
There are two main differences between the tabs-motion
module and the original tabs
module:
tabs-motion
has an updated design using an animated Tab highlight.tabs-motion
is implemented in accordance with the WAI-ARIA 1.1 specification.
The newer design will be considered our default Tabs component going forward but the older design will remain until our next major version (which is currently slated for late 2021).
Accessibility
This component implements the latest WAI-ARIA Tabs specifications. Here are the key takeaways from the spec:
- Proper
role
andaria
attributes are assigned based on the currently active Tab and TabList orientation. - Directional keys are used to move focus through Tabs.
- When a Tab is focused, the associated TabPanel is automatically opened unless
activateOnFocus
is set tofalse
. - When focusing a Tab, the next focusable target is the associated TabPanel's content.
Examples
A basic, uncontrolled Tabs
component. Try focusing a Tab and using the directional keys to move focus to other Tabs. Focus will "wrap" once you've reached the start or end of the TabList. To shift focus to the Tab's content, just hit Tab
at any time.
We use the index of each Tab to provide default keys. You can however, pass in your own keys to each Tab. React keys can be either a string or a number so 1
and "1"
are both valid. The component will default to numbers if no keys are provided.
By default, when a Tab receives focus it will activate the Tab and show the corresponding TabPanel. You can change this by setting activateOnFocus
to false
. In the example above, focus a Tab and then use the directional keys to move focus to other Tabs. To activate the Tab you need to press Enter
or the space bar.
Tabs can be displayed in either a horizontal
(the default) or vertical
orientation. The aria-orientation
attribute will be assigned accordingly. Note, when in the vertical
orientation, the Up
and Down
keys are used to move focus between Tabs. While a Tab is focused, the page's default vertical page scroll is disabled.
The fill
prop allows you to control how Tabs "fill" the available space.
By default, fill
is set to intrinsic
, which means Tabs will take up as much space as their title
content requires, with overflowing Tabs reachable via scrolling or moving focus with the direction keys.
In the example above, we set fill
to fixed
, which divides the space in the TabList equally between each Tab. With this setting you need to be sure the content of the Tab is short enough to fit.
You can disable all of the Tabs (except for the active one) by passing disabled
to the top-level Tabs
component. Note, you can also pass disabled
to individual Tab
components, which will override the top-level prop.
You can use a leading icon for each Tab with the artwork
prop. Icons from baseui/icon
will work out-of-the-box, as you can see in the example above. If you want to use a custom icon or component, your component will be rendered with a small margin between it and the Tab title. Your component will receive a size
and color
prop too if you want to use them.
By default, the content within a TabPanel
will only mount once the corresponding Tab is active. If you want the content of each TabPanel
to render when the Tabs
component renders, you can use the renderAll
prop as in the example above. If you inspect the markup for this example, you will notice that each Tab's content is rendered (though it still isn't visible). This option can be useful for SEO purposes where you might want all of your content to be crawlable.
In this example we align the Tabs and TabPanels with our LayoutGrid component. This allows the TabBorder to expand to fill the viewport. You may want to open this example in CodeSandbox to get a better sense of the visual effect.
You can pass refs to every internal element within the Tabs component using overrides
. There is one exception however: the button elements rendered by Tab
. Internally, the Tabs component keeps a ref attached to the active Tab's button element. This is used for the animated highlight. Because we already need to attach this ref internally, we "share" the ref via the tabRef
prop. If you pass a ref to the tabRef
you will receive a ref to the underlying button element, even when it is active.
If you don't need to control the component yourself you can use the stateful version.
Overrides can be passed to the root Tabs
component (check the playground at the top of page). You can also customize each individual tab. You can use these override keys:
ArtworkContainer
Tab
TabPanel
Resize observer
The animated highlight that slides to the active tab is absolutely positioned and sized. When the active tab changes, the layout of the highlight is recalculated. This means any change in the active tab's position or size, not caused by an active tab change, could lead to the highlight having an outdated layout.
To get around this potential issue we use a ResizeObserver
, which watches each tab for sizing updates and does a highlight re-layout as needed. The ResizeObserver
has full support across modern browsers but doesn't exist in any version of Internet Explorer. If you need this behavior in IE, we suggest using a polyfill for the ResizeObserver
such as this one. We do not include the polyfill by default to avoid adding a few KB to the bundle size of the Tabs component.
API
Tabs props
Name | Type | Description |
---|---|---|
activateOnFocus | boolean | Activate tabs when they receive focus. |
activeKey | string | Key of the the tab to be selected. |
children | react node | An array of Tab components. |
disabled | boolean | Disable all non-active tabs. |
fill | enum | Determines how Tabs fill the TabList. |
onChange | function | Change handler that is called every time a new tab is selected. |
orientation | enum | The orientation of the tab component. |
overrides | custom | Lets you customize all aspects of the component. |
renderAll | boolean | Renders all tab content for SEO purposes regardless of tab active state. |
Tab props
Name | Type | Description |
---|---|---|
artwork | react node | Optional leading icon or content. |
children | react node | The content of the TabPanel. |
overrides | custom | Lets you customize all aspects of the component. |
tabRef | ref | Use to pass a ref to the Tab. |
title | react node | The content of the Tab. |
Exports
You can import this module like so:
import {ORIENTATION} from 'baseui/tabs-motion'
It exports the following components or utility functions: