Width and height on one row, with the lock between them: while it is closed, editing one scales the other by the ratio the pair had when the lock closed. Both fields are as wide as the largest number they can hold, so typing never shifts the row.
Adds the component and everything it depends on to your project.
npx shadcn add https://ui.beste.co/component/r-base/inspector-dimensionsNew here? Read the installation guide.
The import and the props worth knowing about, in one place.
import { InspectorDimensions } from "@/components/beste/component/inspector-dimensions";
<InspectorDimensions label="Size" defaultValue={{ width: 1280, height: 720 }} defaultLocked />
<InspectorDimensions
label="Canvas"
value={size} // { width, height }
onValueChange={setSize} // every accepted edit
onValueCommit={(next) => console.log("settled on", next)} // Enter or blur
locked={locked} // controlled lock; pair it with onLockedChange
onLockedChange={setLocked}
min={16}
max={4096}
step={8} // arrows step by this, Shift by ten of them
precision={0} // decimals kept, which matters because a locked edit divides
suffix="px" // printed once, after the pair
name="canvas" // fields submit as canvas-width and canvas-height
tone="outline" // "muted" (default) | "outline" | "ghost"
size="sm" // "sm" | "default" | "lg"
/>
// A pair whose numbers are genuinely unrelated
<InspectorDimensions label="Grid" lockable={false} defaultValue={{ width: 12, height: 6 }} suffix="" />Turn the props on the right; the snippet under them is what you would write to get what you see.
import { InspectorDimensions } from "@/components/beste/component/inspector-dimensions";
<InspectorDimensions
label="Size"
className="w-72"
defaultValue={{"width":1280,"height":720}}
defaultLocked
precision={0}
/>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.
| Up / Down | Step the focused number |
|---|---|
| Shift + Up / Down | Step it by ten |
| Enter | Accept what was typed |
| Escape | Throw away what was typed and put the value back |
| Lock | Ties the two together at the ratio they have when it closes |
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 | Dimensions | — | Controlled value. Pair it with `onValueChange`. |
defaultValue | Dimensions | — | Initial value in uncontrolled mode. |
onValueChange | (value: Dimensions) => void | — | Fires on every accepted edit. |
onValueCommit | (value: Dimensions) => void | — | Fires once an edit is finished — the field left, or Enter pressed. |
min | number | 0 to 9999, in steps of 1 | Range both numbers answer to. |
max | number | — | |
step | number | — | |
precision | number | 2 | How many decimals a value keeps, which matters here because a locked edit divides. |
suffix | string | "px" | Unit printed after the pair, once, since both numbers are in it. |
locked | boolean | — | Whether the two are tied together. Pair it with `onLockedChange`. While they are, editing one scales the other by the ratio they had when the lock closed. |
defaultLocked | boolean | — | Initial lock state in uncontrolled mode. |
onLockedChange | (locked: boolean) => void | — | |
lockable | boolean | — | Take the lock away, for a pair whose numbers are genuinely unrelated. |
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 of the fields, so the pair can take part in a form. |
className | string | — | |
aria-label | string | — | Accessible name. Falls back to `label`. |
Settings row for a ratio: the row prints it and draws it, and opens an editor with the ratios worth a name plus both sides always editable. It is kept as two numbers rather than as their quotient, since 16:9 is what a reader recognises.
Settings row for a span rather than a value: two thumbs on the row itself, the band between them filling it, and both ends of the pair read out on the right. Ticks, tones and thumb states follow inspector-slider exactly, appearing on hover.
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.
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 for a list too long to read: pressing it opens a width-matched list with a search field, the keyboard walking the results while focus stays in the field. Options carry groups, descriptions, swatches and search keywords, and `multiple` turns the row into a counted multi-select.