Stage position list

Reviews supplied named stage positions with an explicit coordinate frame, per-axis units, inclusion state and controlled selection, reorder and removal requests.

Stage positions

Coordinate frame: Recorded stage (stage-01)

Selected: Overview (field-01)

  1. X (µm)
    0
    Y (µm)
    -12.5
    Z (µm)
    Not supplied

    Included in plan

Review a position list

Microscopy / Local plan

Slide 042 positions
Choose a record, include it in the plan, or change its order. Coordinates remain supplied records; no instrument is connected.

Coordinate frame: Recorded stage frame (stage-01)

Selected: Overview (field-01)

  1. X (µm)
    0
    Y (µm)
    -12.5
    Z (µm)
    0

    Included in plan

  2. X (µm)
    120.25
    Y (µm)
    36
    Z (µm)
    Not supplied

    Excluded from plan

  3. X (µm)
    -48
    Y (µm)
    0
    Z (µm)
    2.5

    Included in plan

Use it for

  • Reviewing a microscopy stage-position plan with explicit frame identity, supplied coordinates and per-axis units.
  • Selection requires value and onValueChange; there is no uncontrolled selection. Inclusion, order and removal are controlled requests. The host supplies accepted records; no optimistic edits or instrument commands occur.
  • Names may repeat; immutable unique IDs distinguish rows and actions. At most 128 positions are rendered. Invalid identifiers or excess records produce an explicit unavailable state.
  • Missing coordinates show Not supplied; nonfinite coordinates show Unavailable. Zero, negative zero and signed finite values retain their supplied representation. Missing frame or units stay explicit.
  • readOnly locks record edits while inspection selection remains available. pending locks edits to a record and swaps across it. disabled uses a native fieldset and locks every control.
  • An optional name submits the selected record ID; form associates the selection with an external form. Coordinates and inclusion records remain host-owned data. Controlled values survive native form reset.

Not for

  • Moving a stage, calculating travel, transforming coordinate frames or converting physical units.
  • Treating selection as an instrument position, missing coordinates as zero, or an edit request as an accepted plan.
  • Large position inventories that need pagination or virtualization; use a bounded window instead.

Three ways in. They share one source, so the pixels match whichever you pick.

1. Import the package

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.

2. Vendor the source

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.

3. Through shadcn

npx shadcn add https://vlak.dev/r/stage-position-list.json

The same registry item, installed by shadcn's CLI.

CSS only

<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); }}
  />;
}

StagePositionList

Supplied stage coordinates and controlled plan edits. No stage motion or coordinate conversion occurs.

PropTypeDefaultDescription
labelrequiredReactNode
coordinateFramerequiredStageCoordinateFrame | null
unitsrequiredStagePositionUnits
positionsrequiredreadonly StagePosition[]
valuestring | nullnullControlled 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[]) => voidRequests an order of existing identifiers without changing records.
onRemove(id: string) => void
descriptionReactNode
readOnlybooleanfalsePrevents record edits; inspection selection remains available.

Also accepts Omit<FieldsetHTMLAttributes<HTMLFieldSetElement>, "defaultValue">.

KeysDoes
Tab, Shift+TabMoves between the native radio group, inclusion checkboxes and enabled move/remove buttons.
Arrow keysChanges the focused native radio selection and requests its record ID; the host controls the accepted selection.
SpaceSelects a focused radio or requests a focused inclusion checkbox change.
Enter, SpaceActivates 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>
.rs-stage-position-list.rs-stage-position-list-legend.rs-stage-position-list-copy.rs-stage-position-list-items.rs-stage-position-list-row.rs-stage-position-list-selected.rs-stage-position-list-head.rs-stage-position-list-identity.rs-stage-position-list-coordinates.rs-stage-position-list-coordinate.rs-stage-position-list-axis.rs-stage-position-list-number.rs-stage-position-list-actions.rs-stage-position-list-action.rs-stage-position-list-status