--- title: Tabs description: "`Tabs` is a component for switching between different display areas." links: - style: https://github.com/yamada-ui/yamada-ui/tree/main/packages/react/src/components/tabs/tabs.style.ts - source: https://github.com/yamada-ui/yamada-ui/tree/main/packages/react/src/components/tabs - storybook: https://yamada-ui.github.io/yamada-ui?path=/story/components-tabs--basic --- ```tsx 孫悟空 ベジータ フリーザ クリリンのことか……クリリンのことかーーーっ!!!!! へっ!きたねぇ花火だ 私の戦闘力は530000です。ですがもちろんフルパワーであなたと戦う気はありませんからご心配なく…… ``` ## Usage ```tsx import { Tabs } from "@yamada-ui/react" ``` ```tsx import { Tabs } from "@/components/ui" ``` ```tsx import { Tabs } from "@workspaces/ui" ``` ```tsx ``` ### Use items ```tsx const items = useMemo( () => [ { panel: "クリリンのことか……クリリンのことかーーーっ!!!!!", tab: "孫悟空", }, { panel: "へっ!きたねぇ花火だ", tab: "ベジータ", }, { panel: "私の戦闘力は530000です。ですがもちろんフルパワーであなたと戦う気はありませんからご心配なく……", tab: "フリーザ", }, ], [], ) return ( ) ``` ### Change Variants ```tsx const items = useMemo( () => [ { panel: "クリリンのことか……クリリンのことかーーーっ!!!!!", tab: "孫悟空", }, { panel: "へっ!きたねぇ花火だ", tab: "ベジータ", }, { panel: "私の戦闘力は530000です。ですがもちろんフルパワーであなたと戦う気はありませんからご心配なく……", tab: "フリーザ", }, ], [], ) return ( {(variant) => ( )} ) ``` ### Change Size ```tsx const items = useMemo( () => [ { panel: "クリリンのことか……クリリンのことかーーーっ!!!!!", tab: "孫悟空", }, { panel: "へっ!きたねぇ花火だ", tab: "ベジータ", }, { panel: "私の戦闘力は530000です。ですがもちろんフルパワーであなたと戦う気はありませんからご心配なく……", tab: "フリーザ", }, ], [], ) return ( {(size) => ( )} ) ``` ### Select a Default Item ```tsx const items = useMemo( () => [ { panel: "クリリンのことか……クリリンのことかーーーっ!!!!!", tab: "孫悟空", }, { panel: "へっ!きたねぇ花火だ", tab: "ベジータ", }, { panel: "私の戦闘力は530000です。ですがもちろんフルパワーであなたと戦う気はありませんからご心配なく……", tab: "フリーザ", }, ], [], ) return ( ) ``` ### Change Orientation ```tsx const items = useMemo( () => [ { panel: "クリリンのことか……クリリンのことかーーーっ!!!!!", tab: "孫悟空", }, { panel: "へっ!きたねぇ花火だ", tab: "ベジータ", }, { panel: "私の戦闘力は530000です。ですがもちろんフルパワーであなたと戦う気はありませんからご心配なく……", tab: "フリーザ", }, ], [], ) return ( {(orientation) => ( )} ) ``` ### Change Alignment ```tsx const items = useMemo( () => [ { panel: "クリリンのことか……クリリンのことかーーーっ!!!!!", tab: "孫悟空", }, { panel: "へっ!きたねぇ花火だ", tab: "ベジータ", }, { panel: "私の戦闘力は530000です。ですがもちろんフルパワーであなたと戦う気はありませんからご心配なく……", tab: "フリーザ", }, ], [], ) return ( {(align) => ( )} ) ``` ### Stretch to Container Width ```tsx const items = useMemo( () => [ { panel: "クリリンのことか……クリリンのことかーーーっ!!!!!", tab: "孫悟空", }, { panel: "へっ!きたねぇ花火だ", tab: "ベジータ", }, { panel: "私の戦闘力は530000です。ですがもちろんフルパワーであなたと戦う気はありませんからご心配なく……", tab: "フリーザ", }, ], [], ) return ( ) ``` ### Disable ```tsx const items = useMemo( () => [ { panel: "クリリンのことか……クリリンのことかーーーっ!!!!!", tab: "孫悟空", }, { disabled: true, panel: "へっ!きたねぇ花火だ", tab: "ベジータ", }, { panel: "私の戦闘力は530000です。ですがもちろんフルパワーであなたと戦う気はありませんからご心配なく……", tab: "フリーザ", }, ], [], ) return ( ) ``` ### Manual Activation By default, the focused tab is automatically activated. If you want to activate the tab at a specific time (when `Enter` or `Space` is pressed), set `manual` to `true`. ```tsx const items = useMemo( () => [ { panel: "クリリンのことか……クリリンのことかーーーっ!!!!!", tab: "孫悟空", }, { panel: "へっ!きたねぇ花火だ", tab: "ベジータ", }, { panel: "私の戦闘力は530000です。ですがもちろんフルパワーであなたと戦う気はありませんからご心配なく……", tab: "フリーザ", }, ], [], ) return ( ) ``` ### Make Links ```tsx const items = useMemo( () => [ { asChild: true, panel: "クリリンのことか……クリリンのことかーーーっ!!!!!", tab: ( 孫悟空 ), }, { asChild: true, panel: "へっ!きたねぇ花火だ", tab: ( ベジータ ), }, { asChild: true, panel: "私の戦闘力は530000です。ですがもちろんフルパワーであなたと戦う気はありませんからご心配なく……", tab: ( フリーザ ), }, ], [], ) return ( ) ``` ### Lazy Rendering ```tsx const items = useMemo( () => [ { panel: "クリリンのことか……クリリンのことかーーーっ!!!!!", tab: "孫悟空", }, { panel: "へっ!きたねぇ花火だ", tab: "ベジータ", }, { panel: "私の戦闘力は530000です。ですがもちろんフルパワーであなたと戦う気はありませんからご心配なく……", tab: "フリーザ", }, ], [], ) return ( {(lazyBehavior) => ( )} ) ``` ### Dynamic Tabs ```tsx const [index, setIndex] = useState(0) const [items, setItems] = useState([ { id: uuid(), panel: "Tab Content", tab: "Tab" }, { id: uuid(), panel: "Tab Content", tab: "Tab" }, { id: uuid(), panel: "Tab Content", tab: "Tab" }, ]) const onAddTab = () => { const nextItems = [...items, { id: uuid(), panel: "Tab Content", tab: "Tab" }] setItems(nextItems) setIndex(nextItems.length - 1) } const onRemoveTab = (id: string) => { const removeIndex = items.findIndex((item) => item.id === id) const nextItems = items.filter((item) => item.id !== id) setItems(nextItems) if (removeIndex < index) { setIndex(index - 1) } else if (removeIndex === index) { setIndex(Math.min(index, nextItems.length - 1)) } } return ( {items.map(({ id, tab }, index) => { const hasRemove = items.length > 1 return ( {tab} {hasRemove ? ( } role="button" onClick={(ev) => { ev.stopPropagation() onRemoveTab(id!) }} /> ) : null} ) })} {items.map(({ id, panel }, index) => ( {panel} {id} index: {index} id: {id} ))} ) ``` ### Customize Tabs ```tsx 孫悟空 ベジータ フリーザ クリリンのことか……クリリンのことかーーーっ!!!!! へっ!きたねぇ花火だ 私の戦闘力は530000です。ですがもちろんフルパワーであなたと戦う気はありませんからご心配なく…… ``` ### Control ```tsx const [index, onChange] = useState(0) const items = useMemo( () => [ { panel: "クリリンのことか……クリリンのことかーーーっ!!!!!", tab: "孫悟空", }, { panel: "へっ!きたねぇ花火だ", tab: "ベジータ", }, { panel: "私の戦闘力は530000です。ですがもちろんフルパワーであなたと戦う気はありませんからご心配なく……", tab: "フリーザ", }, ], [], ) return ( ) ``` ## Uses Components & Hooks ## Props ### Tabs.Root | Prop | Default | Type | Description | | -------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `as` | - | `As` | The HTML element to render. | | `asChild` | - | `boolean` | Merges its props onto its immediate child. | | `css` | - | `CSSObject \| CSSObject[]` | The CSS object. | | `colorScheme` | - | `"amber" \| "black" \| "blackAlpha" \| "blue" \| "cyan" \| "danger" \| "emerald" \| "error" \| "flashy" \| "fuchsia" ...` | Set color scheme variables. | | `size` | `"md"` | `"lg" \| "md" \| "sm"` | The size of the component. | | `variant` | `"line"` | `"line" \| "outline" \| "plain" \| "subtle"` | The variant of the component. | | `defaultIndex` | - | `number` | The index of the selected tab. | | `index` | - | `number` | The index of the selected tab. | | `items` | - | `TabsItem[]` | If provided, generate tab and panel components based on tabs. | | `lazy` | `false` | `boolean` | If `true`, rendering of the content will be deferred until it is selected. | | `lazyBehavior` | `"unmount"` | `LazyBehavior` | The lazy behavior of content when not active. Only works when `lazy={true}`. - `unmount`: The content is always unmounted. - `keepMounted`: The content is initially unmounted, but stays mounted when selected. | | `manual` | `false` | `boolean` | If `true`, the tabs will be manually activated and display its panel by pressing Space or Enter. If `false`, the tabs will be automatically activated and their panel is displayed when they receive focus. | | `onChange` | - | `(index: number) => void` | The callback invoked when the index changes. | ### Tabs.List | Prop | Default | Type | Description | | ------------- | ------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | | `as` | - | `As` | The HTML element to render. | | `asChild` | - | `boolean` | Merges its props onto its immediate child. | | `css` | - | `CSSObject \| CSSObject[]` | The CSS object. | | `colorScheme` | - | `"amber" \| "black" \| "blackAlpha" \| "blue" \| "cyan" \| "danger" \| "emerald" \| "error" \| "flashy" \| "fuchsia" ...` | Set color scheme variables. | ### Tabs.Panel | Prop | Default | Type | Description | | ------------- | ------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | | `as` | - | `As` | The HTML element to render. | | `asChild` | - | `boolean` | Merges its props onto its immediate child. | | `css` | - | `CSSObject \| CSSObject[]` | The CSS object. | | `colorScheme` | - | `"amber" \| "black" \| "blackAlpha" \| "blue" \| "cyan" \| "danger" \| "emerald" \| "error" \| "flashy" \| "fuchsia" ...` | Set color scheme variables. | | `index` | - | `number` | The index of the tab panel. | ### Tabs.Tab | Prop | Default | Type | Description | | ------------- | ------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | | `as` | - | `As` | The HTML element to render. | | `asChild` | - | `boolean` | Merges its props onto its immediate child. | | `css` | - | `CSSObject \| CSSObject[]` | The CSS object. | | `colorScheme` | - | `"amber" \| "black" \| "blackAlpha" \| "blue" \| "cyan" \| "danger" \| "emerald" \| "error" \| "flashy" \| "fuchsia" ...` | Set color scheme variables. | | `index` | - | `number` | The index of the tab. | ## Accessibility `Tabs` follows the [WAI-ARIA - Tabs Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/) for accessibility. ### Keyboard Navigation | Key | Description | State | | ---------------- | --------------------------------------------------------------------------------------------------------------------- | -------------------------- | | `Tab` | Focuses the active tab when focus moves to the tab list. Moves focus to the tab panel if already within the tab list. | - | | `ArrowLeft` | Focuses the previous tab that is not disabled. If it's the first tab, focuses the last tab that is not disabled. | `orientation="horizontal"` | | `ArrowRight` | Focuses the next tab that is not disabled. If it's the last tab, focuses the first tab that is not disabled. | `orientation="horizontal"` | | `ArrowUp` | Focuses the previous tab that is not disabled. If it's the first tab, focuses the last tab that is not disabled. | `orientation="vertical"` | | `ArrowDown` | Focuses the next tab that is not disabled. If it's the last tab, focuses the first tab that is not disabled. | `orientation="vertical"` | | `Space`, `Enter` | Activates the focused tab. | `manual={true}` | | `Home` | Focuses the first tab that is not disabled. | - | | `End` | Focuses the last tab that is not disabled. | - | ### ARIA Roles and Attributes | Component | Roles and Attributes | Usage | | ------------ | -------------------- | --------------------------------------------------------------------------------------------- | | `Tabs.List` | `role="tablist"` | Indicates that this is a tab list. | | | `aria-orientation` | Sets to `"horizontal"` or `"vertical"` based on `orientation`. The default is `"horizontal"`. | | `Tabs.Tab` | `role="tab"` | Indicates that this is a tab. | | | `aria-selected` | Sets to `"true"` when the tab is selected, `"false"` when not selected. | | | `aria-controls` | Sets the `id` of the associated `Tabs.Panel`. | | `Tabs.Panel` | `role="tabpanel"` | Indicates that this is a tab panel. | | | `aria-labelledby` | Sets the `id` of the associated `Tabs.Tab`. |