Settings block for a snippet: a monospaced field with a language chip and a line count, Tab indenting instead of leaving, and a fixed height so a pasted stylesheet cannot push the rest of the drawer out of reach. Collapsible, since a snippet is the tallest thing in a drawer and the least often touched; folded, it measures exactly what a row measures and still reports its line count.
Adds the component and everything it depends on to your project.
npx shadcn add https://ui.beste.co/component/r-base/inspector-codeNew here? Read the installation guide.
The import and the props worth knowing about, in one place.
import { InspectorCode } from "@/components/beste/component/inspector-code";
// Uncontrolled
<InspectorCode label="Custom CSS" language="css" defaultValue=".hero { letter-spacing: -0.02em; }" />
// Folded away when it is not being edited. Closed, the block measures exactly what a
// row of the family measures, and its header still says how many lines are in there.
<InspectorCode
label="Custom CSS"
language="css"
collapsible
defaultOpen={false}
onOpenChange={(open) => console.log("open:", open)}
/>
// Controlled, with a separate commit for expensive work
<InspectorCode
label="Custom CSS"
language="css"
value={css}
onValueChange={setCss}
onValueCommit={(value) => compile(value)}
/>
<InspectorCode
label="Transition SVG"
icon={CodeIcon} // optional leading icon
tone="outline" // "muted" (default) | "outline" | "ghost"
size="sm" // "sm" | "default" | "lg"
language="svg"
rows={10} // lines it opens at; it scrolls past this rather than growing
wrap // let long lines wrap instead of scrolling sideways
maxLength={4000}
placeholder="<svg viewBox=..."
value={svg}
onValueChange={setSvg}
/>
// Read but not edit
<InspectorCode label="Generated" language="json" value={JSON.stringify(config, null, 2)} readOnly />
// The language chip is a sign, not a parser: nothing here validates against it.
// Tab indents by two spaces and Escape leaves the field, so the keyboard is never
// actually trapped.Turn the props on the right; the snippet under them is what you would write to get what you see.
import { InspectorCode } from "@/components/beste/component/inspector-code";
<InspectorCode
label="Custom CSS"
className="w-72"
language="css"
collapsible
defaultValue=".hero {
letter-spacing: -0.02em;
}"
placeholder="/* Anything valid here reaches the page */"
/>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 | Inserts an indent instead of leaving the field, which is what a code box has to do. |
|---|---|
| Escape | Blurs the field, so the drawer around it gets the keyboard back. |
| The header | Folds the block away while collapsible, leaving the label and the line count. |
Read from the component's own type, so this cannot drift from what it accepts.
| Prop | Type | Default | Description |
|---|---|---|---|
label* | string | — | Label rendered above the field, inside the block. |
icon | LucideIcon | — | Optional leading icon shown before the label. |
value | string | — | Controlled value. Pair it with `onValueChange`. |
defaultValue | string | — | Initial value in uncontrolled mode. |
onValueChange | (value: string) => void | — | Fires on every keystroke. |
onValueCommit | (value: string) => void | — | Fires once the edit is finished — leaving the field — and only when the value actually changed. Use it for work too expensive to run per keystroke. |
language | string | — | What this is, shown as a chip beside the label: `css`, `html`, `svg`, `json`. It is a sign, not a parser — nothing here validates against it. |
placeholder | string | — | Ghost text shown while the field is empty. |
rows | number | 6 | Lines the field opens at. It scrolls past this rather than growing, because a pasted stylesheet would otherwise push the whole drawer out of reach. |
collapsible | boolean | — | Let the block be folded away, leaving its header. A snippet is the tallest thing in a drawer and usually the least often touched, so the panel around it is mostly a scroll past something nobody is editing. |
open | boolean | — | Controlled open state. Pair it with `onOpenChange`. |
defaultOpen | boolean | true | Whether it starts open in uncontrolled mode. |
onOpenChange | (open: boolean) => void | — | |
wrap | boolean | — | Let long lines wrap instead of scrolling sideways. |
maxLength | number | — | Longest the value may be. |
disabled | boolean | — | Block interaction and dim the block. |
readOnly | boolean | — | Show the code but refuse edits. |
tone | "muted" | "outline" | "ghost" | "muted" | Surface treatment: filled (default), hairline outline, or bare until focus. |
size | "sm" | "default" | "lg" | "default" | Padding preset. |
name | string | — | Name of the field, so the block can take part in a form. |
id | string | — | Id of the field. One is generated when it is not given. |
className | string | — | |
aria-label | string | — | Accessible name. Falls back to the visible label. |
The family's block row: the same surface and tones, but the label sits above a multi-line field whose height comes from the text, with a character count whenever there is a limit to see. Collapsible, so a paragraph written once can be folded down to the height of a row without leaving the form.
Settings block for a list of short strings: tags are typed one after another and wrap under the label, a comma or a paste splits several at once, and Backspace on an empty field reaches back into the list. Collapsible, so a long list folds down to the height of a row with the count still on it.
The container the rows go in: a named, collapsible section that says what it is currently set to while it is closed, with an optional reset in its header. A drawer of twenty settings becomes a drawer of five groups.
Settings row for the four edges of a box: the row carries a CSS-shorthand summary, and opens a cross where each field sits on the edge it sets, tied together or not.
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 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.