Settings row for a destination: the row reads the URL with its scheme stripped and marks whether it leaves the tab, and opens an editor holding an optional page menu, the URL field and the target and nofollow switches.
The import and the props worth knowing about, in one place.
import { InspectorLink } from "@/components/beste/component/inspector-link";
// Uncontrolled
<InspectorLink label="Link" defaultValue={{ href: "https://beste.co", newTab: true }} />
// Controlled. The value is the pieces an anchor takes.
<InspectorLink
label="Button link"
value={link}
onValueChange={setLink}
onValueCommit={(value) => save(value)}
/>
// Destinations inside the site become a menu above the URL field
<InspectorLink
label="Link"
pages={[{ value: "/", label: "Home" }, { value: "/pricing", label: "Pricing" }]}
value={link}
onValueChange={setLink}
/>
<InspectorLink
label="Source"
icon={LinkIcon} // optional leading icon
tone="outline" // "muted" (default) | "outline" | "ghost"
size="sm" // "sm" | "default" | "lg"
allowNofollow // offer the nofollow toggle
placeholder="https://"
emptyLabel="Not linked" // what the row reads with no destination
value={link}
onValueChange={setLink}
/>
// What the value turns into
<a
href={link.href}
target={link.newTab ? "_blank" : undefined}
rel={[link.newTab && "noreferrer", link.nofollow && "nofollow"].filter(Boolean).join(" ") || undefined}
>
Read more
</a>Turn the props on the right; the snippet under them is what you would write to get what you see.
import { InspectorLink } from "@/components/beste/component/inspector-link";
<InspectorLink
label="Link"
className="w-72"
defaultValue={{"href":"https://beste.co/pricing","newTab":true}}
pages={[{"value":"/","label":"Home"},{"value":"/pricing","label":"Pricing"},{"value":"/blog","label":"Blog"}]}
allowNofollow
/>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 | LinkValue | — | Controlled value. Pair it with `onValueChange`. |
defaultValue | LinkValue | — | Initial value in uncontrolled mode. |
onValueChange | (value: LinkValue) => void | — | Fires on every keystroke in the URL field and on every toggle. |
onValueCommit | (value: LinkValue) => void | — | Fires once an edit is finished — the URL field left, a switch flipped, the link removed. Use it for work too expensive to run per keystroke. |
onOpenChange | (open: boolean) => void | — | Fires when the editor opens or closes. |
pages | (string | InspectorLinkPage)[] | — | Destinations inside the site. Passing them adds a menu above the URL field, so the common case is a choice rather than a typed path. |
allowNofollow | boolean | — | Offer the nofollow toggle. |
placeholder | string | — | Ghost text in the URL field. |
emptyLabel | string | "None" | What the row reads while there is no destination. |
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`. |
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 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.
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 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.