Inspector Position

Settings row for a point on a surface: the row names the nine spots CSS names and shows the rest as two percentages, and opens a square pad the point is dragged around, with the thirds drawn on it and a pull towards them.

Installation

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

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

New here? Read the installation guide.

Usage

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

import { InspectorPosition } from "@/components/beste/component/inspector-position";

// Uncontrolled. The value is two percentages from the top left corner.
<InspectorPosition label="Focal Point" defaultValue={{ x: 50, y: 30 }} />

// Controlled, with a separate commit for expensive work
<InspectorPosition
  label="Focal Point"
  value={point}
  onValueChange={setPoint}
  onValueCommit={(value) => save(value)}
/>

// Pass the picture and the pad stops being a diagram of the surface
<InspectorPosition
  label="Focal Point"
  preview={`url(${image})`}
  value={point}
  onValueChange={setPoint}
/>

<InspectorPosition
  label="Origin"
  icon={CrosshairIcon}   // optional leading icon
  tone="outline"         // "muted" (default) | "outline" | "ghost"
  size="sm"              // "sm" | "default" | "lg"
  snap={false}           // stop pulling towards the thirds
  step={5}               // percent a key press moves; Shift moves ten of them
  name="origin"          // submits as origin-x and origin-y
  value={point}
  onValueChange={setPoint}
/>

// What the value turns into
<div style={{ objectPosition: `${point.x}% ${point.y}%` }} />
<div style={{ backgroundPosition: `${point.x}% ${point.y}%` }} />
<div style={{ transformOrigin: `${point.x}% ${point.y}%` }} />

// A radial gradient's centre, which is the one thing inspector-gradient cannot say
const background = `radial-gradient(circle at ${point.x}% ${point.y}%, #6366f1, #0ea5e9)`;

Playground

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

Usage
import { InspectorPosition } from "@/components/beste/component/inspector-position";

<InspectorPosition
  label="Focal Point"
  className="w-72"
  defaultValue={{"x":50,"y":30}}
/>

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.

Arrow keysOne step on the focused axis.
Shift + ArrowTen steps.
Home / EndSend the axis to 0% or 100%.
Page UpCentre the axis at 50%.
Drag on the padMoves the point; `snap` pulls it towards the thirds and the centre.

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.
valuePositionValueControlled value. Pair it with `onValueChange`.
defaultValuePositionValueInitial value in uncontrolled mode. Defaults to the centre.
onValueChange(value: PositionValue) => voidFires on every frame of a drag, and on every key press.
onValueCommit(value: PositionValue) => voidFires once a change is finished — the pad released, a key released, a named spot pressed. Use it for work too expensive to run per frame.
onOpenChange(open: boolean) => voidFires when the editor opens or closes.
snapbooleantruePull the point onto the thirds when it comes within a few percent of them. Hold Shift while dragging to place it exactly instead.
stepnumber1Smallest increment a key press moves, in percent.
previewstringWhat the pad shows behind the point. Any CSS image: pass the picture being positioned and the pad becomes the thing itself rather than a diagram of it.
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 underlying range inputs, so the row can take part in a form. The two axes submit as `{name}-x` and `{name}-y`.
classNamestring
aria-labelstringAccessible name. Falls back to `label`.

More Inspector components

View all Inspector
135°

Inspector Angle

Settings row for a direction: a dial you drag round, reading in degrees the way CSS does (zero up, growing clockwise), with a range input underneath carrying the keyboard and the form.

Inspector Spacing

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.

Inspector Border

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.

Dark Mode

Inspector Segmented

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.

Inspector Range

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.

Inspector Filters

Settings row for a CSS filter stack, all ten functions of it: the row shows the whole stack applied to something, and opens an editor holding the nine numeric filters as rows of the family plus a drop shadow section, over a preview large enough to judge.