Inspector Secret

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.

API key••••••••_KEY

Installation

Adds the component and everything it depends on to your project.

npx shadcn add https://ui.beste.co/component/r-base/inspector-secret

New here? Read the installation guide.

Usage

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"
/>

Playground

Turn the props on the right; the snippet under them is what you would write to get what you see.

API key••••••••_KEY
Usage
import { InspectorSecret } from "@/components/beste/component/inspector-secret";

<InspectorSecret
  label="API key"
  className="w-72"
  defaultValue="sk_test_EXAMPLE_NOT_A_REAL_KEY"
/>

Keyboard and gestures

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.

EnterCommit an edit, while editable
RevealShows the whole value and fires onReveal once
CopyCopies the real value, revealed or not

Props

Read from the component's own type, so this cannot drift from what it accepts.

PropTypeDefaultDescription
label*stringLabel rendered on the left, inside the row.
iconLucideIconOptional leading icon shown before the label.
valuestringControlled value. Pair it with `onValueChange` when `editable`.
defaultValuestringInitial value in uncontrolled mode.
onValueChange(value: string) => voidFires on every keystroke, and only exists while `editable`.
onValueCommit(value: string) => voidFires once an edit is finished — the field left, or Enter pressed.
editablebooleanLet 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.
revealablebooleantrueOffer the reveal button.
copyablebooleantrueOffer the copy button. It copies the real value whether or not it is revealed, which is the point of having it.
visibleSuffixnumber4How 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.
placeholderstringGhost text while there is no value.
onReveal() => voidFires 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) => voidFires after a successful copy.
disabledbooleanBlock 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.
namestringName of the field, so an editable secret can take part in a form.
idstringId of the field, for an external `<label htmlFor>`.
classNamestring
aria-labelstringAccessible name. Falls back to `label`.

More Inspector components

View all Inspector
Command Palette

Inspector Shortcut

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.

Applies to every breakpoint.

Inspector Note

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.

Inspector Tabs

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.

Inspector Unit

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.

em

Inspector Scrub

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.

Inspector Action

The row that does something instead of holding something: open a sub-panel, replace an asset, regenerate a key, delete the section. It carries a description, a hint, a busy spinner and a destructive treatment, and renders as a plain anchor when given an href.