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="info" content_style="info"> <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 without breakout bottom border
First
<Tabs breakout={false}> <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>
prerender
Tabs and By using prerender={true}
the content is kept inside the DOM.
Also, when switching the tabs, the height is animated.
Content 1
Smile at me 📸
<> <Tabs prerender content_style="info"> <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.
<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-white); ` 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',}