Tabs
A row of tabs. By default it is a tablist: one tab in the page's tab order, the arrow keys of its orientation moving between tabs, Enter or Space selecting.
A row of tabs. By default it is a tablist: one tab in the page's tab order, the arrow keys of
its orientation moving between tabs, Enter or Space selecting. With as="nav" the same look
is a navigation of buttons or links, the current one marked aria-current="page". The row can
carry content of its own before and after the tabs - an icon, a toolbar, a "+" button.
import { Tab, Tabs } from '@soroush.tech/design-system/Tabs'
;<Tabs value={value} onChange={setValue} textColor="secondary" color="secondary" aria-label="Items">
<Tab value="one" label="Item One" />
<Tab value="two" label="Item Two" icon={<Icon name="folder" size="sm" />} />
<Tab value="three" label="Item Three" disabled />
</Tabs>
Tabs holds its own value (defaultValue) or takes it (value / onChange). To show a panel for
each tab, put the tabs in a TabContext as a TabList - it links each tab to its TabPanel:
import { Tab, TabContext, TabList, TabPanel } from '@soroush.tech/design-system/Tabs'
;<TabContext value={value}>
<TabList onChange={setValue} aria-label="Items">
<Tab label="Item One" value="1" />
<Tab label="Item Two" value="2" />
</TabList>
<TabPanel value="1">...</TabPanel>
<TabPanel value="2">...</TabPanel>
</TabContext>
The family: Tabs, Tab, TabContext, TabList, TabPanel and TabScrollButton.
Examples
Default
Canvas
The content of Canvas. Choose another tab and this changes with it.
const args: Partial<TabsProps> = { variant: 'underline', orientation: 'horizontal', color: 'primary', size: 'md', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, 'aria-label': 'Views', defaultValue: 'canvas', } <WithContent args={args} />
Boxed
Canvas
The content of Canvas. Choose another tab and this changes with it.
const args: Partial<TabsProps> = { variant: 'boxed', orientation: 'horizontal', color: 'primary', size: 'sm', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, 'aria-label': 'Views', defaultValue: 'canvas', } <WithContent args={args} />
Tonal
Canvas
The content of Canvas. Choose another tab and this changes with it.
const args: Partial<TabsProps> = { variant: 'tonal', orientation: 'horizontal', color: 'primary', size: 'sm', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, 'aria-label': 'Views', defaultValue: 'canvas', } <WithContent args={args} />
Enclosed
Classic
The content of Classic. Choose another tab and this changes with it.
const args: Partial<TabsProps> = { variant: 'enclosed', orientation: 'horizontal', color: 'primary', size: 'md', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, 'aria-label': 'Views', defaultValue: 'classic', } <WithContent args={args}> <Tab value="images" label="Images" /> <Tab value="classic" label="Classic" /> <Tab value="videos" label="Videos" /> <Tab value="stores" label="Stores" /> <Tab value="settings" label="Settings" /> <Tab value="tools" label="Tools" /> </WithContent>
Enclosed Vertical
Classic
The content of Classic. Choose another tab and this changes with it.
const args: Partial<TabsProps> = { variant: 'enclosed', orientation: 'vertical', color: 'primary', size: 'md', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, 'aria-label': 'Views', defaultValue: 'classic', } <View width="28rem"> <WithContent args={args}> <Tab value="images" label="Images" /> <Tab value="classic" label="Classic" /> <Tab value="videos" label="Videos" /> </WithContent> </View>
Enclosed With Content Before And After
Classic
The content of Classic. Choose another tab and this changes with it.
const args: Partial<TabsProps> = { variant: 'enclosed', orientation: 'horizontal', color: 'primary', size: 'md', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, 'aria-label': 'Search', defaultValue: 'classic', } <WithContent args={{ ...args, startContent: <Icon name="zoom_in" size="sm" />, endContent: ( <Button size="sm" variant="text" aria-label="Add a view"> + </Button> ), }} > <Tab value="images" label="Images" /> <Tab value="classic" label="Classic" /> <Tab value="videos" label="Videos" /> </WithContent>
Divider
const args: Partial<TabsProps> = { variant: 'underline', orientation: 'horizontal', color: 'primary', size: 'md', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, 'aria-label': 'Views', defaultValue: 'canvas', } <Flex flexDirection="column" gap={4}> {tabsVariantTokens.flatMap((variant) => [true, false].map((hasDivider) => ( <Tabs key={`${variant}-${hasDivider}`} {...args} aria-label={`${variant}, ${hasDivider ? 'with' : 'without'} a divider`} variant={variant} hasDivider={hasDivider} startContent={<Icon name="zoom_in" size="sm" />} endContent={ <Button size="sm" variant="text" aria-label="Add a view"> + </Button> } /> )) )} </Flex>
Vertical
Canvas
The content of Canvas. Choose another tab and this changes with it.
const args: Partial<TabsProps> = { variant: 'underline', orientation: 'vertical', color: 'primary', size: 'md', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, 'aria-label': 'Views', defaultValue: 'canvas', } <View width="28rem"> <WithContent args={args} /> </View>
Full Width
Canvas
The content of Canvas. Choose another tab and this changes with it.
const args: Partial<TabsProps> = { variant: 'underline', orientation: 'horizontal', color: 'primary', size: 'md', fullWidth: true, isCentered: false, shouldSelectOnFocus: false, 'aria-label': 'Views', defaultValue: 'canvas', } <WithContent args={args} />
Centered
Canvas
The content of Canvas. Choose another tab and this changes with it.
const args: Partial<TabsProps> = { variant: 'underline', orientation: 'horizontal', color: 'primary', size: 'md', fullWidth: false, isCentered: true, shouldSelectOnFocus: false, 'aria-label': 'Views', defaultValue: 'canvas', } <WithContent args={args} />
Icon Position
Top
The content of Top. Choose another tab and this changes with it.
const args: Partial<TabsProps> = { variant: 'underline', orientation: 'horizontal', color: 'primary', size: 'md', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, 'aria-label': 'Views', defaultValue: 'top', } <WithContent args={{ ...args, 'aria-label': 'Icon by position' }}> <Tab value="top" label="Top" icon={<Icon name="table" size="sm" color="inherit" />} /> <Tab value="start" label="Start" icon={<Icon name="folder" size="sm" color="inherit" />} iconPosition="start" /> <Tab value="end" label="End" icon={<Icon name="link" size="sm" color="inherit" />} iconPosition="end" /> <Tab value="bottom" label="Bottom" icon={<Icon name="code" size="sm" color="inherit" />} iconPosition="bottom" /> </WithContent>
Wrapped Labels
const args: Partial<TabsProps> = { variant: 'underline', orientation: 'horizontal', color: 'primary', size: 'md', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, 'aria-label': 'Views', defaultValue: 'canvas', } <View width="18rem"> <Tabs {...args} fullWidth aria-label="Wrapped"> <Tab value="canvas" label="Canvas" /> <Tab value="long" label="A label long enough to wrap" isWrapped /> </Tabs> </View>
Disabled
Canvas
The content of Canvas. Choose another tab and this changes with it.
const args: Partial<TabsProps> = { variant: 'underline', orientation: 'horizontal', color: 'primary', size: 'md', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, 'aria-label': 'Views', defaultValue: 'canvas', } <WithContent args={args}> <Tab value="canvas" label="Canvas" /> <Tab value="system" label="Design system" disabled /> <Tab value="common" label="Common components" /> </WithContent>
Navigation
const args: Partial<TabsProps> = { variant: 'boxed', orientation: 'horizontal', color: 'primary', size: 'md', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, 'aria-label': 'Left panel', defaultValue: 'layers', } <Tabs {...args} as="nav"> <Tab value="layers" label="Layers" href="#layers" /> <Tab value="assets" label="Assets" href="#assets" /> <Tab value="variables" label="Variables" href="#variables" /> </Tabs>
Content Before And After
Light
The content of Light. Choose another tab and this changes with it.
const args: Partial<TabsProps> = { variant: 'boxed', orientation: 'horizontal', color: 'primary', size: 'sm', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, 'aria-label': 'Views', defaultValue: 'light', } <WithContent args={{ ...args, 'aria-label': 'Themes', startContent: <Icon name="groups" size="sm" />, endContent: ( <Button size="sm" variant="text" aria-label="Add a theme"> + </Button> ), }} > <Tab value="light" label="Light" /> <Tab value="dark" label="Dark" /> </WithContent>
With Panels
The canvas.
const { value: _value, defaultValue: _defaultValue, ...args } = { variant: 'underline', orientation: 'horizontal', color: 'primary', size: 'md', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, 'aria-label': 'Views', defaultValue: 'canvas', } <TabContext defaultValue="canvas"> <TabList {...args} /> <TabPanel value="canvas" p={2}> <Typography>The canvas.</Typography> </TabPanel> <TabPanel value="system" p={2}> <Typography>The design system.</Typography> </TabPanel> <TabPanel value="common" p={2}> <Typography>Common components.</Typography> </TabPanel> </TabContext>
Closable
const args: Partial<TabsProps> = { variant: 'boxed', orientation: 'horizontal', color: 'primary', size: 'sm', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, 'aria-label': 'Views', defaultValue: 'canvas', } <EditorTabs {...args} />
Secondary Action
const args: Partial<TabsProps> = { variant: 'boxed', orientation: 'horizontal', color: 'primary', size: 'sm', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, 'aria-label': 'Views', defaultValue: 'light', } <Tabs {...args} aria-label="Themes"> <Tab value="light" label="Light" secondaryAction={<ThemeMenu name="Light" />} /> <Tab value="dark" label="Dark" secondaryAction={<ThemeMenu name="Dark" />} /> </Tabs>
Scrolling
Component 1
The content of Component 1. Choose another tab and this changes with it.
const args: Partial<TabsProps> = { variant: 'underline', orientation: 'horizontal', color: 'primary', size: 'md', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, overflowBehavior: 'scroll', scrollButtons: 'auto', 'aria-label': 'Views', defaultValue: 0, } <View width="28rem" maxWidth="100%"> <WithContent args={{ ...args, 'aria-label': 'Components' }}>{manyTabs}</WithContent> </View>
Scroll Buttons Always
Component 1
The content of Component 1. Choose another tab and this changes with it.
const args: Partial<TabsProps> = { variant: 'underline', orientation: 'horizontal', color: 'primary', size: 'md', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, overflowBehavior: 'scroll', scrollButtons: 'always', 'aria-label': 'Views', defaultValue: 0, } <View width="28rem" maxWidth="100%"> <WithContent args={{ ...args, 'aria-label': 'Components' }}>{manyTabs}</WithContent> </View>
Visible Scrollbar
Component 1
The content of Component 1. Choose another tab and this changes with it.
const args: Partial<TabsProps> = { variant: 'underline', orientation: 'horizontal', color: 'primary', size: 'md', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, overflowBehavior: 'scroll', scrollButtons: 'never', hasVisibleScrollbar: true, 'aria-label': 'Views', defaultValue: 0, } <View width="28rem" maxWidth="100%"> <WithContent args={{ ...args, 'aria-label': 'Components' }}>{manyTabs}</WithContent> </View>
Overflow Menu
const args: Partial<TabsProps> = { variant: 'underline', orientation: 'horizontal', color: 'primary', size: 'md', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, overflowBehavior: 'menu', overflowLabel: 'More tabs', 'aria-label': 'Views', defaultValue: 0, } <OverflowRow {...args} />
Overflow Menu Vertical
const args: Partial<TabsProps> = { variant: 'underline', orientation: 'vertical', color: 'primary', size: 'md', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, overflowBehavior: 'menu', overflowLabel: 'More tabs', 'aria-label': 'Views', defaultValue: 0, } <OverflowRow {...args} />
Overflow Menu Enclosed
const args: Partial<TabsProps> = { variant: 'enclosed', orientation: 'horizontal', color: 'primary', size: 'md', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, overflowBehavior: 'menu', overflowLabel: 'More tabs', 'aria-label': 'Views', defaultValue: 0, } <OverflowRow {...args} endContent={ <Button size="sm" variant="text" aria-label="New tab"> + </Button> } />
Vertical Scrolling
Component 1
The content of Component 1. Choose another tab and this changes with it.
const args: Partial<TabsProps> = { variant: 'underline', orientation: 'vertical', color: 'primary', size: 'md', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, overflowBehavior: 'scroll', 'aria-label': 'Views', defaultValue: 0, } <View width="28rem" height="16rem" display="flex"> <WithContent args={{ ...args, 'aria-label': 'Components' }}>{manyTabs}</WithContent> </View>
Customized
<ThemeProvider theme={customTheme}> <View width="30rem" maxWidth="100%"> <Tabs aria-label="Customized" defaultValue={0} overflowBehavior="scroll" shouldShowScrollButtonsOnMobile slots={{ scrollButton: ArrowButton }} > {Array.from({ length: 10 }, (_, index) => ( <Tab key={index} value={index} label={`Item ${index + 1}`} /> ))} </Tabs> </View> </ThemeProvider>
Enclosed Without Divider
The classic view - its tab shares this ground.
<TabContext defaultValue="classic"> <TabList aria-label="Views" variant="enclosed" hasDivider={false} bg="default" selectedBg="paper" > <Tab value="images" label="Images" /> <Tab value="classic" label="Classic" /> <Tab value="videos" label="Videos" /> </TabList> {['images', 'classic', 'videos'].map((value) => ( <TabPanel key={value} value={value} bg="paper" p={3}> <Typography>The {value} view - its tab shares this ground.</Typography> </TabPanel> ))} </TabContext>
Reference Structure
Item One
Item Two
Item Three
<ControlledTabContext />
Tab
Default
const args: Partial<TabProps> = { label: 'Canvas', disabled: false, isWrapped: false, value: 'canvas' } <Tabs aria-label="Views" defaultValue="canvas" variant="boxed"> <Tab {...args} /> <Tab value="system" label="Design system" /> </Tabs>
Own Look
<Tabs aria-label="Files" defaultValue="tabs" variant="enclosed" color="primary"> <Tab value="readme" label="README.md" /> <Tab value="tabs" label="Tabs.tsx ●" color="error" /> <Tab value="theme" label="theme.ts" selectedBg="default" bg="paper" /> <Tab value="notes" label="notes" size="sm" textColor="secondary" /> </Tabs>
With Icon
const args: Partial<TabProps> = { label: 'Canvas', iconPosition: 'start', disabled: false, isWrapped: false, value: 'canvas', } <Tabs aria-label="Views" defaultValue="canvas"> <Tab {...args} icon={icon('folder', 'sm')} /> <Tab value="code" label="Code" icon={icon('code', 'sm')} iconPosition={args.iconPosition} /> </Tabs>
Secondary Action
const args: Partial<TabProps> = { label: 'Canvas', disabled: false, isWrapped: false, value: 'canvas' } <Tabs aria-label="Views" defaultValue="canvas" variant="boxed" size="sm"> <Tab {...args} secondaryAction={ <Menu align="end" trigger={ <Button size="sm" variant="text" aria-label="Canvas options"> ⋮ </Button> } > <MenuItem value="rename">Rename...</MenuItem> <MenuItem value="duplicate">Duplicate</MenuItem> <MenuDivider /> <MenuItem value="close">Close</MenuItem> </Menu> } /> <Tab value="system" label="Design system" /> </Tabs>
Icon Positions
<Scenarios> <Scenario title="iconPosition - top when unset, then each side"> <Tabs aria-label="Icon positions" defaultValue="unset"> <Tab value="unset" label="unset" icon={icon('table', 'sm')} /> {tabIconPositionTokens.map((position) => ( <Tab key={position} value={position} label={position} icon={icon('folder', 'sm')} iconPosition={position} /> ))} </Tabs> </Scenario> <Scenario title="Icon only - no label; title names it"> <Tabs aria-label="Icon only" defaultValue="files"> <Tab value="files" title="Files" icon={icon('folder', 'sm')} /> <Tab value="code" title="Code" icon={icon('code', 'sm')} /> <Tab value="history" title="History" icon={icon('history', 'sm')} /> </Tabs> </Scenario> <Scenario title="Mixed in one row - every label on the same line"> <Tabs aria-label="Mixed" defaultValue="plain"> <Tab value="plain" label="Plain" /> <Tab value="start" label="Start" icon={icon('folder', 'sm')} iconPosition="start" /> <Tab value="top" label="Top" icon={icon('table', 'sm')} /> <Tab value="end" label="End" icon={icon('link', 'sm')} iconPosition="end" /> </Tabs> </Scenario> <Scenario title="Below the label - labels on the row's first line"> <Tabs aria-label="Icons below" defaultValue="files"> <Tab value="files" label="Files" icon={icon('folder', 'sm')} iconPosition="bottom" /> <Tab value="code" label="Code" icon={icon('code', 'md')} iconPosition="bottom" /> <Tab value="history" label="History" icon={icon('history')} iconPosition="bottom" /> </Tabs> </Scenario> </Scenarios>
Icon Sizes
<Scenarios> {(['start', 'top'] as const).flatMap((position) => tabSizes.map((tabSize) => ( <Scenario key={`${position}-${tabSize}`} title={`Tabs size="${tabSize}", iconPosition="${position}" - an icon of every size`} > <Tabs aria-label={`${position} icons, ${tabSize} tabs`} size={tabSize} defaultValue="unset" > {iconSizes.map((iconSize) => ( <Tab key={iconSizeName(iconSize)} value={iconSizeName(iconSize)} label={`icon ${iconSizeName(iconSize)}`} icon={icon(position === 'top' ? 'table' : 'folder', iconSize)} iconPosition={position} /> ))} </Tabs> </Scenario> )) )} </Scenarios>
Icons In Every Look
<Scenarios> {(['underline', 'boxed'] as const).map((variant) => ( <Scenario key={variant} title={`variant="${variant}"`}> <Tabs aria-label={`${variant} with icons`} variant={variant} defaultValue="start"> <Tab value="start" label="Start" icon={icon('folder', 'sm')} iconPosition="start" /> <Tab value="top" label="Top" icon={icon('table', 'sm')} /> <Tab value="plain" label="Plain" /> </Tabs> </Scenario> ))} <Scenario title="fullWidth - the tabs share the row"> <Tabs aria-label="Full width with icons" fullWidth defaultValue="start"> <Tab value="start" label="Start" icon={icon('folder', 'sm')} iconPosition="start" /> <Tab value="top" label="Top" icon={icon('table', 'sm')} /> <Tab value="end" label="End" icon={icon('link', 'sm')} iconPosition="end" /> </Tabs> </Scenario> <Scenario title='orientation="vertical"'> <Flex gap={4}> <Tabs aria-label="Vertical start icons" orientation="vertical" defaultValue="files"> <Tab value="files" label="Files" icon={icon('folder', 'sm')} iconPosition="start" /> <Tab value="code" label="Code" icon={icon('code', 'sm')} iconPosition="start" /> <Tab value="history" label="History" icon={icon('history', 'sm')} iconPosition="start" /> </Tabs> <Tabs aria-label="Vertical top icons" orientation="vertical" defaultValue="files"> <Tab value="files" label="Files" icon={icon('folder', 'sm')} /> <Tab value="code" label="Code" icon={icon('code', 'sm')} /> <Tab value="history" label="History" icon={icon('history', 'sm')} /> </Tabs> </Flex> </Scenario> <Scenario title='as="nav" - links'> <Tabs aria-label="Navigation with icons" as="nav" defaultValue="files"> <Tab value="files" label="Files" href="#files" icon={icon('folder', 'sm')} iconPosition="start" /> <Tab value="code" label="Code" href="#code" icon={icon('code', 'sm')} iconPosition="start" /> </Tabs> </Scenario> </Scenarios>
Icons With Every State
<Scenarios> <Scenario title="disabled"> <Tabs aria-label="Disabled with icons" defaultValue="on"> <Tab value="on" label="Enabled" icon={icon('folder', 'sm')} iconPosition="start" /> <Tab value="off" label="Disabled" icon={icon('lock', 'sm')} iconPosition="start" disabled /> </Tabs> </Scenario> <Scenario title="isWrapped - a long label on two lines"> <Flex width="16rem"> <Tabs aria-label="Wrapped with icons" fullWidth defaultValue="long"> <Tab value="long" label="A label long enough to wrap" icon={icon('folder', 'sm')} iconPosition="start" isWrapped /> <Tab value="top" label="Another long label here" icon={icon('table', 'sm')} isWrapped /> </Tabs> </Flex> </Scenario> <Scenario title="closeLabel - closable, with an icon"> <Tabs aria-label="Closable with icons" variant="boxed" defaultValue="button"> <Tab value="button" label="Button" icon={icon('code', 'sm')} iconPosition="start" closeLabel="Close Button" /> <Tab value="card" label="Card" icon={icon('table', 'sm')} closeLabel="Close Card" /> </Tabs> </Scenario> <Scenario title="secondaryAction - a menu, with an icon"> <Tabs aria-label="Secondary action with icons" variant="boxed" defaultValue="light"> <Tab value="light" label="Light" icon={icon('visibility', 'sm')} iconPosition="start" secondaryAction={ <Menu align="end" trigger={ <Button size="sm" variant="text" aria-label="Light options"> ⋮ </Button> } > <MenuItem value="rename">Rename...</MenuItem> </Menu> } /> <Tab value="dark" label="Dark" icon={icon('visibility', 'sm')} /> </Tabs> </Scenario> </Scenarios>
TabContext
Default
The layers panel.
const { defaultValue }: Partial<TabContextProps> = { defaultValue: 'layers' } <TabContext key={String(defaultValue)} defaultValue={defaultValue}> <TabList aria-label="Left panel"> {panelValues.map((value) => ( <Tab key={value} value={value} label={labelOf(value)} /> ))} </TabList> <Panels /> </TabContext>
Controlled Value
The layers panel.
const args: Partial<TabContextProps> = { defaultValue: 'layers' } <Controlled {...args} />
TabList
Default
Layers of the page.
const args: Partial<TabListProps> = { variant: 'underline', orientation: 'horizontal', color: 'primary', size: 'md', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, 'aria-label': 'Left panel', } <TabContext defaultValue="layers"> <TabList {...args} /> <TabPanel value="layers" p={2}> <Typography>Layers of the page.</Typography> </TabPanel> <TabPanel value="assets" p={2}> <Typography>The page's assets.</Typography> </TabPanel> </TabContext>
Vertical
Layers of the page.
const args: Partial<TabListProps> = { variant: 'underline', orientation: 'vertical', color: 'primary', size: 'md', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, 'aria-label': 'Left panel', } <TabContext defaultValue="layers"> <Flex flexDirection="row" gap={2}> <TabList {...args} /> <TabPanel value="layers" p={2}> <Typography>Layers of the page.</Typography> </TabPanel> <TabPanel value="assets" p={2}> <Typography>The page's assets.</Typography> </TabPanel> </Flex> </TabContext>
Overflow Menu
The layers panel.
const args: Partial<TabListProps> = { variant: 'underline', orientation: 'horizontal', color: 'primary', size: 'md', fullWidth: false, isCentered: false, shouldSelectOnFocus: false, overflowBehavior: 'menu', overflowLabel: 'More panels', 'aria-label': 'Left panel', } <TabContext defaultValue="layers"> <View width="18rem" maxWidth="100%" overflow="hidden" style={{ resize: 'horizontal' }}> <TabList {...args}> {panelValues.map((value) => ( <Tab key={value} value={value} label={value[0].toUpperCase() + value.slice(1)} /> ))} </TabList> </View> {panelValues.map((value) => ( <TabPanel key={value} value={value} p={2}> <Typography>The {value} panel.</Typography> </TabPanel> ))} </TabContext>
TabPanel
Default
Layers of the page.
const args: Partial<TabPanelProps> = { shouldKeepMounted: false, p: 2, value: 'layers' } <TabContext defaultValue="layers"> <TabList aria-label="Left panel"> <Tab value="layers" label="Layers" /> <Tab value="assets" label="Assets" /> </TabList> <TabPanel {...args} /> <TabPanel {...args} value="assets"> <Typography>The page's assets.</Typography> </TabPanel> </TabContext>
TabScrollButton
Default
<TabScrollButton direction="end" orientation="horizontal" />