OrbitField
Nodes on orbits, useful for a small system diagram rather than decoration.
@luc/ui/motionLive preview
Rings tilt into a plane and rotate; the same field flattens to a static diagram under reduced motion.
<OrbitField label="Model pipeline" tilt={58} perspective={900}>
<OrbitFieldRing radius={92} duration={18}>
<OrbitFieldNode>Ingest</OrbitFieldNode>
<OrbitFieldNode>Store</OrbitFieldNode>
</OrbitFieldRing>
<OrbitFieldCore>API</OrbitFieldCore>
</OrbitField>Usage
import { OrbitField } from "@luc/ui/motion";<OrbitField label="Model pipeline" tilt={58} perspective={900}>
<OrbitFieldRing radius={92} duration={18}>
<OrbitFieldNode>Ingest</OrbitFieldNode>
<OrbitFieldNode>Store</OrbitFieldNode>
</OrbitFieldRing>
<OrbitFieldCore>API</OrbitFieldCore>
</OrbitField>API
| Export | Kind | Signature |
|---|---|---|
OrbitField | 5 documented props | ({ className, children, label, tilt, perspective, speed, paused, style, ...props }: OrbitFieldProps) => import("@types/react").JSX.Element |
OrbitFieldCore | export | ({ className, children, ...props }: React.ComponentPropsWithRef<"div">) => import("@types/react").JSX.Element |
OrbitFieldNode | 4 documented props | ({ className, children, angle, onSelect, active, label, ...props }: OrbitFieldNodeProps) => import("@types/react").JSX.Element |
OrbitFieldRing | 6 documented props | ({ className, children, radius, duration, direction, dashed, trackless, restOnHover, style, ...props }: OrbitFieldRingProps) => import("@types/react").JSX.Element |
OrbitField props
Type: OrbitFieldProps
Values the compiler reads from the declaration.
| Prop | Type | Default | Notes |
|---|---|---|---|
label? | string | undefined | — | Accessible name. Omit it and the field is decorative to a screen reader. |
paused? | boolean | undefined | — | Stop every ring without removing the composition. |
perspective? | number | undefined | — | `perspective()` distance, in px. Smaller = a steeper plane. |
speed? | number | undefined | — | Seconds-per-turn multiplier applied to every ring. `1` is the ring default. |
tilt? | number | undefined | — | Lean of the orbital plane, in degrees. `0` is a flat, top-down view. |
OrbitFieldNode props
Type: OrbitFieldNodeProps
Values the compiler reads from the declaration.
| Prop | Type | Default | Notes |
|---|---|---|---|
active? | boolean | undefined | — | Marks the node as the chosen one, for both styling and `aria-pressed`. |
angle? | number | undefined | — | Seat angle, in degrees, counter-clockwise from 3 o'clock. |
label? | string | undefined | — | Accessible name for an interactive node. Defaults to no label. |
onSelect? | (() => void) | undefined | — | Selecting is opt-in: pass a handler and the node becomes a real button. |
OrbitFieldRing props
Type: OrbitFieldRingProps
Values the compiler reads from the declaration.
| Prop | Type | Default | Notes |
|---|---|---|---|
dashed? | boolean | undefined | — | Draw the track as a dashed hairline — a second ring reads as a second tier. |
direction? | "reverse" | "forward" | undefined | — | |
duration? | number | undefined | — | Seconds for one full turn. Larger is calmer. |
radius? | number | undefined | — | Radius as a percentage of the field's **width**. `50` is the largest ring that still fits inside the square; `34` is a comfortable inner tier. Values above 50 deliberately overflo… |
restOnHover? | boolean | undefined | — | Stop the ring while a pointer rests on it or focus is inside one of its seats. On by default: a control that will not hold still is not usable. |
trackless? | boolean | undefined | — | Hide the visible track while keeping the ring's geometry. |
Accessibility
The accessibility contract is the one the primitive underneath the component already honours — the platform element for a control, or the ARIA pattern the component implements — and the Showcase's own pages are scanned for violations with axe.
What happens on the server, and when hydration changes it.
Family
Spatial
Depth, layering and geometry — motion that reads as physical space.
Related