KQ-966 · ENV/SWITCH

Env Switch

Where the next command lands: the environments share one rail, and the knob travels between them on glide under a useId-prefixed layoutId, while the head washes as the stop changes — a tinted layer cross-fading on a tween, quiet for the first stop, cobalt between, warn for a guarded one. A guarded stop never commits on the first press; it arms, and a confirm row unfolds in flow beneath the rail on glide to a ResizeObserver-measured height, its button focused as it arrives. The stops are a radio group where Arrow keys move and commit unguarded stops, and Escape or Cancel disarms and hands focus back.

KQ-966 · ENV/SWITCH
ledger-apiyard.coldbrook.internal

Env yard · yard.coldbrook.internal · not armed

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/env-switch

Props

ref
React.Ref<HTMLDivElement>
default —
Reaches the root element.
stops
EnvStop[]
default —
The environments, left to right: id, a short name, the host it points at, and an optional guarded flag.
service
string
default —
What is being pointed somewhere; printed in the head.
value / defaultValue
string
default the first stop
Controlled or initial committed stop id.
onValueChange
(id: string) => void
default —
Fires from the press or key that committed a stop.
onArmedChange
(id: string | null) => void
default —
The armed guarded stop, or null — a state, so it also fires on mount.
armLabel
(stop: EnvStop) => string
default "Switch to <stop name>"
Copy on the confirm control.
label
string
default "Environment"
Names the rail for assistive technology.
className
string
default —
Merged onto the root element's classes.