Settings row for a border: the row draws one exactly as described beside a summary of it, and opens an editor with the sides as icon toggles and the width, style and colour under them, each one a row of the family.
The import and the props worth knowing about, in one place.
import { InspectorBorder } from "@/components/beste/component/inspector-border";
// Uncontrolled. Opens on all four sides, 1px, dashed.
<InspectorBorder label="Border" />
// An empty `sides` list is no border, so the width never has to carry a zero to
// mean the same thing.
<InspectorBorder label="Border" defaultValue={{ sides: ["bottom"], width: 2, style: "solid" }} />
// Controlled, with a separate commit for expensive work
<InspectorBorder
label="Card border"
value={border}
onValueChange={setBorder}
onValueCommit={(value) => save(value)}
/>
<InspectorBorder
label="Divider"
icon={SquareIcon} // optional leading icon
tone="outline" // "muted" (default) | "outline" | "ghost"
size="sm" // "sm" | "default" | "lg"
maxWidth={8} // widest the border may be, in px
styles={["solid"]} // one entry fixes the style and drops the choice
alpha // carry an alpha channel through the colour
format="oklch" // notation the colour is written back in
value={border}
onValueChange={setBorder}
/>
// What the value turns into. Per side rather than one `border`, since the whole
// point of the row is that the four sides differ.
const side = (name) =>
border.sides?.includes(name) ? `${border.width}px ${border.style} ${border.color}` : undefined;
<div
style={{
borderTop: side("top"),
borderRight: side("right"),
borderBottom: side("bottom"),
borderLeft: side("left"),
}}
/>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. |
value | BorderValue | — | Controlled value. Pair it with `onValueChange`. |
defaultValue | BorderValue | — | Initial value in uncontrolled mode. |
onValueChange | (value: BorderValue) => void | — | Fires on every adjustment, including each keystroke in the width field. |
onValueCommit | (value: BorderValue) => void | — | Fires once an adjustment is finished — a side toggled, a width committed, a colour released. Use it for work too expensive to run per keystroke. |
onOpenChange | (open: boolean) => void | — | Fires when the editor opens or closes. |
maxWidth | number | 12 | Widest the border may be, in px. |
styles | BorderStyle[] | ["solid", "dashed", "dotted"] | Which line styles to offer. Pass one to fix the style and drop the choice from the editor. |
format | "hex" | "oklch" | "rgb" | — | Notation the colour is written back in. |
alpha | boolean | — | Carry an alpha channel through the colour. |
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. |
className | string | — | |
aria-label | string | — | Accessible name. Falls back to `label`. |