Tabs
Used to display a list of tabs that can be used to navigate between different sections of a page.
Anatomy
- Tab Wrapper
- Tab List
- Tab
- Tab Panel
Import
import { TabsProvider, TabsList, Tab, TabsPanel } from '@pluralsight/react'
Usage
In order for the Tabs be accessible, you must provide a matching id
and value
for each Tab that is unique to the Tab list.
Static Tabs
When you want to display set of Tabs that use static content, you can render all the components directly.
function StaticTabs() {
const tabs = useMemo(() => {
return [
{
id: 'tab-1',
label: 'Tab 1',
panel: 'panel-1',
},
{
id: 'tab-2',
label: 'Tab 2',
panel: 'panel-2',
},
{
id: 'tab-3',
label: 'Tab 3',
panel: 'panel-3',
},
]
}, [])
return (
<TabsProvider defaultActiveTab={tabs[0].id}>
<TabsList>
<For each={tabs}>
{(tab) => (
<Tab key={tab.id} controls={tab.panel} id={tab.id} value={tab.id}>
{tab.label}
</Tab>
)}
</For>
</TabsList>
<For each={tabs}>
{(tab) => (
<TabsPanel key={tab.panel} labelledBy={tab.id} id={tab.panel}>
{tab.panel} Content
</TabsPanel>
)}
</For>
</TabsProvider>
)
}
Dynamic Tabs
When you want to display a set of Tabs that use dynamic content, you can use the useTabs
hook to render the Tabs and Panels.
When fetching data for a Tab Panel, the Tabs will automatically display a loading state until the data is available. This is because we utilize Supsense
under the hood.
export default function App() { const data: string = "world" return <h1>Hello {data}</h1> }
Disabled Tabs
When you want to disable a Tab, you can use the disabled
prop on the Tab
component.
function StaticTabs() {
const tabs = useMemo(() => {
return [
{
id: 'tab-1',
label: 'Tab 1',
panel: 'panel-1',
},
{
id: 'tab-2',
label: 'Tab 2',
panel: 'panel-2',
},
{
id: 'tab-3',
label: 'Tab 3',
panel: 'panel-3',
},
]
}, [])
return (
<TabsProvider defaultActiveTab={tabs[0].id}>
<TabsList>
<For each={tabs}>
{(tab) => (
<Tab
key={tab.id}
controls={tab.panel}
disabled={tab.id === 'tab-2'}
id={tab.id}
value={tab.id}
>
{tab.label}
</Tab>
)}
</For>
</TabsList>
<For each={tabs}>
{(tab) => (
<TabsPanel key={tab.panel} labelledBy={tab.id} id={tab.panel}>
{tab.panel} Content
</TabsPanel>
)}
</For>
</TabsProvider>
)
}
Custom Tabs Components
When you want to customize the Tab family of components, you can use any of the native React features to overwrite styling for the elements.
export default function App() { const data: string = "world" return <h1>Hello {data}</h1> }
Headless Styles
When you want to create a set of your own Tab components from scratch, you can use the Headless Styles API along with the React Aria to make them accessible.
import {
getTabWrapperStyles,
getTabListStyles,
splitClassNameProp,
} from '@pluralsight/headless-styles'
import {
useAriaTabList,
type UseTabListOptions,
} from '@pluralsight/react-aria'
interface CustomTabListProps extends HTMLAttributes<HTMLDivElement>, UseTabListOptions {
activeTab: string,
}
export function CustomTabList(props: CustomTabListProps) {
const { activeTab, labelledBy, setFocus, tabsRefList, ...nativeProps } = props
const pandoStyles = getTabListStyles({
classNames: splitClassNameProp(nativeProps.className),
})
const ariaProps = useAriaTabList({
activeTabValue: ,
labelledBy,
setFocus: onTabClick,
tabsRefList,
})
return <div {...nativeProps} {...pandoStyles} {...ariaProps} />
}
Behavoir
Patterns
Do use Tabs when you need to display different content relative to the same page.
Don't use Tabs to navigate to different areas of a page or app.
Do keep the Tabs restricted to a single row.
Don't use present multiple rows of Tabs.
Usage
Do restrict the use of Tabs to once per page.
Don't use multiple Tabs within the same page.
Do keep the Tabs located on top of the panel content it is displaying.
Don't position the Tabs or realign them outside of the default top-left positioning.
API
TabsProvider
The TabsProvider
component is used to provide the context for the Tabs components. It is required to be used in order for the Tabs components to work.
Props
Prop | Type | Description |
---|---|---|
defaultActiveTab | string | The default active tab value. This is used to set the initial active tab. |
TabsList
The TabsList
component is used to wrap the Tab
components. It is required to be used in order for the Tabs components to work.
Props
Prop | Type | Description |
---|---|---|
labelledBy | string | The id of a Form Label associated with the Tab group. |
Tab
The Tab
component is used to represent a single tab within the TabsList
component.
Props
Prop | Type | Description |
---|---|---|
controls | string | The id of the TabsPanel component that the Tab controls. |
disabled | boolean | Whether or not the Tab is disabled. |
id | string | The id of the Tab. |
value | string | The value of the Tab which should match the id . |
TabsPanel
The TabsPanel
component is used to represent the content of a single tab within the TabsList
component.
Props
Prop | Type | Description |
---|---|---|
labelledBy | string | The id of the Tab component that the Tab Panel is associated with. |
id | string | The id of the Tab Panel. |
Accessibility
The Tabs component is built to be accessible to screen readers and keyboard users alike.
Screen Reader Interactions
Screen readers will announce the following:
- The number of Tabs
- The selected Tab
- The Tab Panel content
Keyboard Interactions
Key | Description |
---|---|
Tab | Moves focus to the next focusable element. |
Shift + Tab | Moves focus to the previous focusable element. |
Left Arrow | Moves focus to the previous Tab. |
Right Arrow | Moves focus to the next Tab. |
Home | Moves focus to the first Tab. |
End | Moves focus to the last Tab. |
Space | Selects the current Tab. |
Enter | Selects the current Tab. |