Skip to content

Description

Tabs are a set of buttons that allow navigation between content that is related and on the same level of hierarchy.

Demos

Tabs where content is provided from outside

As this may be a more common use case, we still have to ensure our tabs content is linked together with the tabs – because of accessibility.

You have to provide an id to both of the components.

NB: You don't need to use a function inside Tabs.Content – it can contain any element you need, as long as it is a React Node.

one

<Tabs
id="unique-linked-id"
data={[
{
title: 'One',
key: 'one',
},
{
title: 'Two',
key: 'two',
},
]}
/>
<Tabs.Content id="unique-linked-id">
{({ key }) => {
return <H2>{key}</H2>
}}
</Tabs.Content>

Tabs using 'data' property and content object

First

<Tabs
data={[
{ title: 'First', key: 'first' },
{ title: 'Second', key: 'second' },
{ title: 'Third', key: 'third', disabled: true },
{ title: 'Fourth', key: 'fourth' },
]}
>
{exampleContent /* See Example Content below */}
</Tabs>

Tabs using 'data' property only

First

<Tabs
data={{
first: {
title: 'First',
// See Example Content below
content: exampleContent.first,
},
second: {
title: 'Second',
// See Example Content below
content: exampleContent.second,
},
}}
// Only use "on_click" if you really have to
on_click={({ selected_key }) => {
console.log('on_click', selected_key)
}}
// Preferred way to listen on changes
on_change={({ selected_key }) => {
console.log('on_change', selected_key)
}}
/>

Tabs using React Components only

Also, this is an example of how to define a different content background color, by providing content_style.

First

<Tabs tabs_style="mint-green" content_style="black-3">
<Tabs.Content title="First">
<Section spacing top bottom style_type="white">
<H2 top={0} bottom>
First
</H2>
</Section>
</Tabs.Content>
<Tabs.Content title="Second">
<Section spacing top bottom style_type="white">
<H2 top={0} bottom>
Second
</H2>
</Section>
</Tabs.Content>
</Tabs>

Tabs without bottom border

First

<Tabs no_border={true}>
<Tabs.Content title="First">
<H2 top={0} bottom>
First
</H2>
</Tabs.Content>
<Tabs.Content title="Second">
<H2 top={0} bottom>
Second
</H2>
</Tabs.Content>
</Tabs>

Tabs and prerender

By using prerender={true} the content is kept inside the DOM.

Content 1

Smile at me 📸

<>
<Tabs prerender content_style="black-3">
<Tabs.Content title="Tab 1">
<H2>Content 1</H2>
</Tabs.Content>
<Tabs.Content title="Tab 2">
<div
style={{
height: '10rem',
display: 'flex',
alignItems: 'flex-end',
}}
>
<H2>Content 2</H2>
</div>
</Tabs.Content>
<Tabs.Content title="Tab 3">
<div
style={{
height: '20rem',
display: 'flex',
alignItems: 'flex-end',
}}
>
<H2>Content 3</H2>
</div>
</Tabs.Content>
</Tabs>
<P top>Smile at me 📸</P>
</>

Tabs optimized for narrow screens

Navigation buttons will be shown and the tabs-list will be scrollable.

Fourth
<Tabs data={manyTabs}>{manyTabsContent}</Tabs>

Horizontal aligned tabs

const FlexWrapper = styled.div`
display: flex;
flex-direction: row;
`
const LeftArea = styled.div`
/* Ensure no-wrap */
flex-shrink: 0;
`
const RightArea = styled.div`
/* Ensure the tabbar is hidden outside this area */
overflow: hidden;
/* Ensure the focus ring is visible! (because of overflow: hidden) */
margin: -2px;
padding: 2px;
`
function TabsHorizontalAligned() {
return (
<FlexWrapper>
<LeftArea>
<ToggleButton.Group value="first">
<ToggleButton text="first" value="first" />
<ToggleButton text="second" value="second" />
</ToggleButton.Group>
</LeftArea>
<RightArea>
<Tabs
left
no_border
selected_key="first"
id="unique-tabs-row"
data={manyTabs}
/>
</RightArea>
</FlexWrapper>
)
}
render(<TabsHorizontalAligned />)

max-width usage

const MaxWidthWrapper = styled.div`
max-width: 30rem;
background: var(--color-mint-green-12);
`
function TabsMaxWidth() {
return (
<MaxWidthWrapper>
<Tabs
top
no_border
selected_key="fifth"
id="unique-tabs-max-width"
data={manyTabs}
/>
</MaxWidthWrapper>
)
}
render(<TabsMaxWidth />)

Router integration

This demo uses @reach/router. More examples on CodeSandbox.

Example Content

const exampleContent = {
first: () => <H2>First</H2>,
second: () => <Input label="Label:">Focus me with next Tab key</Input>,
third: () => (
<>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</>
),
fourth: 'Fourth as a string only',
}