Settings row holding a set of pills that are each on or off, so any number of them can be on at once: what inspector-segmented is for one choice out of several, this is for several choices at once, and what inspector-switch is for a single flag, this is for a handful that belong together.
Adds the component and everything it depends on to your project.
npx shadcn add https://ui.beste.co/component/r-base/inspector-togglesNew here? Read the installation guide.
The import and the props worth knowing about, in one place.
import { InspectorToggles } from "@/components/beste/component/inspector-toggles";
// Which sides get a border. Four pills only fit as icons.
<InspectorToggles
label="Borders"
options={[
{ value: "left", icon: PanelLeftIcon },
{ value: "right", icon: PanelRightIcon },
{ value: "top", icon: PanelTopIcon },
{ value: "bottom", icon: PanelBottomIcon },
]}
value={sides}
onValueChange={setSides}
/>
// Plain strings when the value is the text
<InspectorToggles label="Weekend" options={["Sat", "Sun"]} defaultValue={["Sat"]} />
// A floor and a ceiling on how many may be on
<InspectorToggles
label="Corners"
min={1} // the last one on stops answering instead of vanishing
max={2} // the ones still off dim once the ceiling is reached
options={["TL", "TR", "BR", "BL"]}
value={corners}
onValueChange={setCorners}
/>
<InspectorToggles
label="Effects"
icon={SparklesIcon} // optional leading icon
tone="outline" // "muted" (default) | "outline" | "ghost"
size="sm" // "sm" | "default" | "lg"
options={[
{ value: "blur", label: "Blur" },
{ value: "grain", label: "Grain" },
{ value: "glow", label: "Glow", disabled: true },
]}
value={effects}
onValueChange={setEffects}
/>
// The pills are checkboxes sharing one name, so the row submits with a form
<InspectorToggles label="Days" name="days" options={["Mon", "Tue", "Wed"]} />
// Values come back in the order the options declare them, not the order pressed
<InspectorToggles
label="Sides"
options={["left", "right", "top", "bottom"]}
onValueChange={(value) => console.log(value)} // ["left", "top"], never ["top", "left"]
/>Turn the props on the right; the snippet under them is what you would write to get what you see.
import { InspectorToggles } from "@/components/beste/component/inspector-toggles";
<InspectorToggles
label="Weekend"
options={["Mon","Tue","Wed","Thu"]}
defaultValue={["Mon","Wed"]}
/>Every one of these is in the component already. They are listed because a props table cannot mention a gesture, so nothing else on this page can tell you they exist.
| Tab | Move between the pills — they are separate checkboxes, not one control with an inner cursor. |
|---|---|
| Space | Turn the focused pill on or off. |
Read from the component's own type, so this cannot drift from what it accepts.
| Prop | Type | Default | Description |
|---|---|---|---|
label* | string | — | Label rendered on the left, inside the row. |
icon | LucideIcon | — | Optional leading icon shown before the label. |
options | (string | InspectorTogglesOption)[] | — | The toggles. Plain strings are enough when the value is the text. Past three or four with words, give them icons instead: the row is one line tall and a set of pills is only useful while it fits on it. |
value | string[] | — | Controlled value. Pair it with `onValueChange`. |
defaultValue | string[] | — | Initial value in uncontrolled mode. |
onValueChange | (value: string[]) => void | — | Fires on every toggle, with the values in the order `options` gives them — never in the order they were pressed, so the array can be compared and stored as-is. |
min | number | 0 | Fewest toggles that may be on. The last one on stops answering rather than disappearing, since a pill that vanishes at the boundary is worse than one that plainly refuses. |
max | number | — | Most toggles that may be on. Once reached, the ones still off dim, which is the only way a reader can tell why pressing them does nothing. |
disabled | boolean | — | Block interaction and dim the row. |
tone | "muted" | "outline" | "ghost" | "muted" | Surface treatment: filled (default), hairline outline, or bare until hover. |
size | "sm" | "default" | "lg" | "default" | Row height preset. |
name | string | — | Name shared by the underlying checkboxes, so the row can take part in a form. |
className | string | — | |
aria-label | string | — | Accessible name for the group. Falls back to `label`. |
Settings row whose choices sit side by side on the right, with a marker that slides between them: the readable alternative to a switch when the two states deserve names, and the compact one to a select at three or four options.
Settings row with a label on the left and a switch on the right, sharing the family's pill: the label takes the row's spare width, so a press almost anywhere toggles it.
Settings row that pairs a label with its current choice inside one pill, opening a width-matched dropdown below: option icons, colour swatches, descriptions and grouped sections, on top of the accessible shadcn select.
The strip that splits a settings panel into two or three questions instead of one long scroll. It is the strip and nothing else: what the tabs switch between stays in the panel's own markup, beside the state that decides it. The pill slides between equal columns, arrow keys both move and select, and a tab can carry a count of what has changed under it.