All components (204)
Tabs
Navigation · Tabs · .amset-tabs
What it is and when to use it
Several views of the same object in the same place, one at a time: the description, the measurements and the reviews of a product; the details, the invoices and the notices of a customer.
When to use it
- When the content is split into three to six sections of the same size and whoever is looking needs only one at a time.
counteron a tab to say how many things are inside without having to open it ("Invoices 12").disabledon a tab (or its key indisabledKeys) for a section that exists but cannot be viewed (no permissions): it looks dimmed and the keyboard skips it.variant="pill"when they go inside a card or a bar, where one more line competes with the borders;orientation="vertical"to put them in a column next to the panel.keyboardActivation="manual"when opening a tab is costly (a query to the server): the arrow keys only move focus and it is chosen with Enter or Space.
When not to
- If each section is a page with its own address: that is navigation,
SideNavorTopBar. - To change how the same list looks (list or grid, day or week):
SegmentedGroup. - A tab without
contenthas no panel: it is a filter or a mode of the same screen, drawn by whoever mounts the component. It is still a tab (arrows, focus, selected) but carries noaria-controls. - If several sections need to be seen at once or compared:
AccordionwithallowsMultipleExpanded.
Keyboard: Tab reaches the active tab; the left and right arrow keys (up and down in a column) change tab, skip the disabled ones and wrap around on reaching the end. Home and End go to the first and the last. In a right-to-left language the arrow keys of the row are reversed. Another Tab enters the panel. If the tabs do not fit in the width, the strip scrolls sideways without a bar: the mouse wheel moves it, and focus brings into view the tab it reaches.
Accessibility: it is a tablist with a name (label) and each panel is linked to its tab with aria-labelledby. Only the panel of the active tab is mounted. With line the active one is marked with color, underline and weight; with pill, filled: never with color alone.
Fine-tuning: CSS variables --amset-tabs-*: -font, -gap, -list-gap, -padding-block, -padding-inline, -radius. The size moves the padding and the font size; the variant, how the chosen one is marked.
What it looks like
Three items, €148.20.
<Tabs
label="Order details"
tabs={[
{ key: 'summary', label: 'Summary', content: <Resumen /> },
{ key: 'envio', label: 'Shipping', counter: 2, content: <Envio /> },
{ key: 'factura', label: 'Invoice', content: <Factura /> },
]}
/>Props
Import it with import { Tabs } from '@amset/ui'. Required props are marked.
| Prop | Type | What it does |
|---|---|---|
labelrequired | string | What is announced on reaching the tab group. |
tabsrequired | readonly Tab[] | — |
className | string | — |
defaultSelectedKey | string | number | — |
disabled | boolean | The entire group is out of play: the chosen value is still visible, but cannot be changed. |
disabledKeys | Iterable<string | number> | — |
keyboardActivation | "manual" | "automatic" | `automatic` (the default) chooses when the arrow moves; `manual` only moves focus and choosing is done with Enter or Space. Manual is for when opening a tab is costly: a server query per arrow press is not done. |
onSelectionChange | (key: string | number) => void | — |
orientation | "horizontal" | "vertical" | In a row (default) or in a column, beside the panel. |
selectedKey | string | number | Which one is chosen. If passed, the state is kept by whoever uses the component. |
size | "sm" | "md" | "lg" | The font size and the padding of each tab. |
variant | TabsVariant | How the chosen one is marked: `line` underlines it (the default) and `pill` fills it. The pill one is for when the tabs sit inside a card or a bar, where one more line competes with the borders. |
It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.
CSS variables
These CSS variables are how you adapt it. Declare them on the component's selector, not on :root: the stylesheet redeclares them in the rule itself, and a declaration on the same element always wins.
| Variable | Default |
|---|---|
--amset-tabs-gap | var(--amset-space-4) |
--amset-tabs-list-gap | var(--amset-space-1) |
--amset-tabs-padding-block | var(--amset-space-2) |
--amset-tabs-padding-inline | var(--amset-space-3) |
--amset-tabs-font | var(--amset-text-base) |
--amset-tabs-radius | var(--amset-radius) |
How to change it
.amset-tabs {
--amset-tabs-gap: ...;
--amset-tabs-list-gap: ...;
}In the test bench
Every state and variant, to try one at a time, on its page at ui.amset.tech:
