Review a position list
Microscopy / Local plan
Reviews supplied named stage positions with an explicit coordinate frame, per-axis units, inclusion state and controlled selection, reorder and removal requests.
Microscopy / Local plan
Three ways in. They share one source, so the pixels match whichever you pick.
npm install @noorddev/vlak-react
// once, next to your app's root
import "@noorddev/vlak-react/css";
import { StagePositionList } from "@noorddev/vlak-react";Precompiled React and one stylesheet. No compiler to configure. Per-component imports work too: @noorddev/vlak-react/components/stage-position-list.
npx @noorddev/vlak-cli add stage-position-list
The StyleX leaf lands in components/vlak/ with its dependencies, for your own compiler to own. See StyleX.
npx shadcn add https://vlak.dev/r/stage-position-list.json
The same registry item, installed by shadcn's CLI.
<link rel="stylesheet" href="node_modules/@noorddev/vlak/css/vlak.css" />
No React. Link vlak.css and use the markup and classes below.
import { useState } from "react";
import { StagePositionList } from "@noorddev/vlak-react";
import type { StagePosition } from "@noorddev/vlak-react";
export function PositionPlan() {
const [positions, setPositions] = useState<readonly StagePosition[]>([
{ id: "field-01", name: "Overview", x: 0, y: -12.5, z: null, enabled: true },
{ id: "field-02", name: "Edge detail", x: 120.25, y: 36, z: 0, enabled: false },
]);
const [selected, setSelected] = useState<string | null>(null);
return <StagePositionList
label="Slide positions"
coordinateFrame={{ id: "stage-01", label: "Recorded stage" }}
units={{ x: "µm", y: "µm", z: "µm" }}
positions={positions}
value={selected}
onValueChange={setSelected}
onEnabledChange={(id, enabled) => setPositions(current => current.map(position => position.id === id ? { ...position, enabled } : position))}
onOrderChange={ids => setPositions(current => ids.map(id => current.find(position => position.id === id)!))}
onRemove={id => { setPositions(current => current.filter(position => position.id !== id)); if (selected === id) setSelected(null); }}
/>;
}Supplied stage coordinates and controlled plan edits. No stage motion or coordinate conversion occurs.
| Prop | Type | Default | Description |
|---|---|---|---|
labelrequired | ReactNode | ||
coordinateFramerequired | StageCoordinateFrame | null | ||
unitsrequired | StagePositionUnits | ||
positionsrequired | readonly StagePosition[] | ||
value | string | null | null | Controlled selected record identifier; pair with onValueChange for inspection. Missing or unknown identifiers never select a fallback. |
onValueChange | (id: string) => void | ||
onEnabledChange | (id: string, enabled: boolean) => void | ||
onOrderChange | (ids: readonly string[]) => void | Requests an order of existing identifiers without changing records. | |
onRemove | (id: string) => void | ||
description | ReactNode | ||
readOnly | boolean | false | Prevents record edits; inspection selection remains available. |
Also accepts Omit<FieldsetHTMLAttributes<HTMLFieldSetElement>, "defaultValue">.
| Keys | Does |
|---|---|
| Tab, Shift+Tab | Moves between the native radio group, inclusion checkboxes and enabled move/remove buttons. |
| Arrow keys | Changes the focused native radio selection and requests its record ID; the host controls the accepted selection. |
| Space | Selects a focused radio or requests a focused inclusion checkbox change. |
| Enter, Space | Activates a move or remove button. Reorder focus follows the same ID; accepted removal focuses an adjacent surviving row or the empty fieldset without stealing focus from elsewhere. |
<fieldset class="rs-stage-position-list"><legend class="rs-stage-position-list-legend">Slide positions</legend><p class="rs-stage-position-list-copy">Coordinate frame: Recorded stage (stage-01)</p><ol class="rs-stage-position-list-items"><li class="rs-stage-position-list-row"><p class="rs-stage-position-list-identity">Overview (field-01)</p><dl class="rs-stage-position-list-coordinates"><div class="rs-stage-position-list-coordinate"><dt class="rs-stage-position-list-axis">X (µm)</dt><dd class="rs-stage-position-list-number">0</dd></div><div class="rs-stage-position-list-coordinate"><dt class="rs-stage-position-list-axis">Y (µm)</dt><dd class="rs-stage-position-list-number">-12.5</dd></div><div class="rs-stage-position-list-coordinate"><dt class="rs-stage-position-list-axis">Z (µm)</dt><dd class="rs-stage-position-list-number">Not supplied</dd></div></dl><p class="rs-stage-position-list-copy">Included in plan</p></li></ol></fieldset>