A value shown without being readable over a shoulder: an API key, a token, a signing secret. Hidden, it keeps its last few characters legible, since that tail is how one key is told from another; copy works whether or not it is revealed, and revealing fires a callback for panels that keep a log of it.
The import and the props worth knowing about, in one place.
import { InspectorSecret } from "@/components/beste/component/inspector-secret";
// Issued elsewhere: shown and copied, not typed
<InspectorSecret label="API key" value={key} />
<InspectorSecret
label="Webhook secret"
value={secret}
visibleSuffix={6} // characters left legible while hidden
onReveal={() => console.log("secret revealed")}
onCopy={() => console.log("secret copied")}
revealable // on by default
copyable // on by default
tone="outline" // "muted" (default) | "outline" | "ghost"
size="sm" // "sm" | "default" | "lg"
/>
// Typed by the reader: the field is a real password input while it is hidden
<InspectorSecret
label="SMTP password"
editable
value={password}
onValueChange={setPassword}
onValueCommit={(next) => console.log("saved", next.length, "characters")}
placeholder="Not set"
name="smtp-password"
/>Turn the props on the right; the snippet under them is what you would write to get what you see.
import { InspectorSecret } from "@/components/beste/component/inspector-secret";
<InspectorSecret
label="API key"
className="w-72"
defaultValue="sk_test_EXAMPLE_NOT_A_REAL_KEY"
/>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.
| Enter | Commit an edit, while editable |
|---|---|
| Reveal | Shows the whole value and fires onReveal once |
| Copy | Copies the real value, revealed or not |
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 | string | — | Controlled value. Pair it with `onValueChange` when `editable`. |
defaultValue | string | — | Initial value in uncontrolled mode. |
onValueChange | (value: string) => void | — | Fires on every keystroke, and only exists while `editable`. |
onValueCommit | (value: string) => void | — | Fires once an edit is finished — the field left, or Enter pressed. |
editable | boolean | — | Let the secret be typed. Off by default: most of these are issued elsewhere and the row is there to show and copy one, not to invite an edit. |
revealable | boolean | true | Offer the reveal button. |
copyable | boolean | true | Offer the copy button. It copies the real value whether or not it is revealed, which is the point of having it. |
visibleSuffix | number | 4 | How many characters stay legible at the end while it is hidden. A key is recognised by its tail, and a row of dots that says nothing means opening the dashboard to find out which key this is. |
placeholder | string | — | Ghost text while there is no value. |
onReveal | () => void | — | Fires when the secret is revealed. A panel that keeps a log of who looked at what has to be told, and this is the only moment it happens. |
onCopy | (value: string) => void | — | Fires after a successful copy. |
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 field, so an editable secret can take part in a form. |
id | string | — | Id of the field, for an external `<label htmlFor>`. |
className | string | — | |
aria-label | string | — | Accessible name. Falls back to `label`. |
Settings row that records a key combination: press it, press the keys, and the row keeps them as kbd chips printed in the platform's own glyphs. Mod stands for Cmd on a Mac and Ctrl everywhere else, so one stored value is right on both.
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.
The line of prose that belongs between rows: what a setting is for, why one is switched off, what a value will cost. Four tones, each with its own mark, and the same text size as the rows around it.
A number and the unit that gives it meaning, in one row: px, rem, a percentage, or a keyword like auto that is the whole value on its own. Each unit may bring its own range, so a percentage stops at 100 while pixels do not.
A number with no ends, dragged from the row itself: for the values that have no maximum worth naming, like a z-index, an X offset or a letter-spacing. The drag is relative rather than positional, so pressing anywhere is safe, and a soft range gives the bar something to draw against that the value is free to leave. Only the reported number is quantized, so the pointer never fights the grid.
The row that reports rather than asks: a measurement the work produced, shown in the family's surface so it can sit among the settings that caused it. Threshold bands colour the bar and the number without the caller recomputing them, and it is a meter rather than a progress bar, which is how it is announced.