Segmented control
A segmented control is a short row of options where exactly one is on. It swaps a panel, picks a value or filters a view at once.
Swap a panel
Use kind="tabs" when the options switch what is shown below. The panel names its tab with aria-labelledby.
Show code
<KbSegmented label="Editor view" kind="tabs" value={mode} onChange={setMode} options={options} />Pick a value
Use kind="radio" for a setting with two to four values.
Show code
<KbSegmented label="Access" kind="radio" value={access} onChange={setAccess} options={options} />Filter a view
Use kind="toggle" (the default) when the options narrow a list. Each option is a pressed button.
Show code
<KbSegmented label="Show" value={filter} onChange={setFilter} options={options} />When to use
- Use it for two to four short options that are always all visible.
- Keep labels to one or two words, in sentence case.
- The pressed option is tinted, not gold. Gold stays for the one primary action.
- For a longer or open-ended set of filters that can combine, use chips. For page-level navigation, use tabs.
Import
import { KbSegmented } from "@/components/ui/KbSegmented";
<KbSegmented label="Editor view" kind="tabs" value={mode} onChange={setMode} options={[{ value: "write", label: "Write" }, { value: "preview", label: "Preview" }]} />Props
| Prop | Type | Default | What it does |
|---|---|---|---|
label | string | None | The accessible name of the group. |
kind | "tabs" | "radio" | "toggle" | toggle | Sets the role: tablist, radiogroup or a group of pressed buttons. |
value | string | None | The value of the option that is on. |
options | { value, label, ariaLabel?, title?, disabled?, id?, controls?, keyShortcuts?, kibeeId? }[] | None | The options, in order. |
onChange | (value) => void | None | Called with the value of the option pressed. |
size | "sm" | "md" | md | Small is 24px tall. |
Keyboard and screen readers
- Each option is a real button with the state its role needs: aria-selected for tabs, aria-checked for radio, aria-pressed for toggle.
- The group has an accessible name from label.
- The option that is on is shown by tint and weight as well as colour.
- Text on every state passes 4.5:1; focus shows the shared ring.