Inspector Attributes

About this component

Inspector Attributes

The pairs nobody could have put in the panel in advance: data-* hooks, an ARIA relationship, a custom property, an og: name. Two text fields per line and nothing else, with no reordering and no per-row editor. Duplicate names are marked rather than refused, since an edit passes through one on its way.

Usage

The import and the props worth knowing about, in one place.

import {
  InspectorAttributes,
  attributesToRecord,
} from "@/components/beste/component/inspector-attributes";

<InspectorAttributes
  label="Attributes"
  defaultValue={[{ key: "data-analytics-id", value: "hero-cta" }]}
  // Pressable chips under the pairs: one press adds the name with an empty value,
  // and a name already in the list drops out of the row
  suggestions={["data-testid", "data-analytics-id", "aria-describedby", "rel"]}
/>

<InspectorAttributes
  label="Meta tags"
  value={attributes}                 // [{ key, value }]
  onValueChange={setAttributes}
  onOpenChange={(open) => console.log("editor open:", open)}
  keyPlaceholder="property"
  valuePlaceholder="content"
  max={12}
  tone="outline"                     // "muted" (default) | "outline" | "ghost"
  size="sm"                          // "sm" | "default" | "lg"
/>

// The pairs as the object they are for. Empty names are dropped: a half-typed
// line is not an attribute yet.
<div {...attributesToRecord(attributes)} />

Playground

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

Usage
import { InspectorAttributes } from "@/components/beste/component/inspector-attributes";

<InspectorAttributes
  label="Attributes"
  className="w-72"
  defaultValue={[{"key":"data-analytics-id","value":"hero-cta"},{"key":"aria-describedby","value":"hero-note"}]}
  suggestions={["data-testid","data-analytics-id","aria-describedby","rel"]}
/>

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.

Enter / SpaceOpen the editor from the row
TabWalks name, value, remove, then the next line
Typing a nameDrops anything that cannot be in one, spaces included

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.
valueAttribute[]Controlled value. Pair it with `onValueChange`.
defaultValueAttribute[]Initial value in uncontrolled mode.
onValueChange(value: Attribute[]) => void
onOpenChange(open: boolean) => voidFires when the editor opens or closes.
keyPlaceholderstringGhost text for the two fields.
valuePlaceholderstring
suggestionsstring[]Names worth offering, shown as pressable chips under the pairs: one press adds that name with an empty value. Names already in the list drop out of the row, so it also says what is left. They stay suggestions rather than becoming a menu of allowed names — the point of this row is the names nobody anticipated.
maxnumberCeiling on how many pairs there may be.
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.
classNamestring
aria-labelstringAccessible name. Falls back to `label`.

More Inspector components

View all Inspector

Inspector Variants

The choice that has to be seen to be made: a template, a layout, a chart type. Each option is a picture, normally a rendered screenshot passed as a URL, or markup for the choices no photograph would show. The row is the trigger, the grid is width-matched to it, and the captions under the pictures can be dropped for a set whose pictures say everything.

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.

px

Inspector Dimensions

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.

Inspector Icon

Settings row that names the chosen icon and shows it on the right; pressing the row opens a searchable palette below it, width-matched to the row, with clearing offered at the foot of it. The icon set is passed in, so the row never bundles an icon library of its own.

Inspector Aspect

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.

Inspector Input

Settings row with a label on the left and a plain text field on the right, sharing the family's pill: the whole row is the label, so pressing anywhere puts the caret in the field.