OccupancyList
Which agents are on which resource.
Part of
@aora-bot/surfaces, not@aora-bot/react:pnpm add @aora-bot/surfaces @aora-bot/react, and import@aora-bot/surfaces/styles.cssafter the React stylesheet.
- Repository, main
- Browser session
- Staging database+3
- MicrophoneNot in use
Faces, not names
The question this list answers is "is anything touching that right now", and a row of characters answers it at a glance where a column of names has to be read. Names are still there — on hover and to a screen reader — so the marks are a summary, not a replacement. An empty row renders as "not in use" rather than as a gap, because a gap looks like a loading failure.
Overflow is a count rather than a scroll. Four faces and "+7" is a true statement about a busy resource; a row that grows with its occupants makes the list jump every time one arrives. maxVisible sets the cut.
One engine for forty rows
Every OccupancyMark is a StagedMark, so the list needs a MarkStageProvider above it. A resource list is exactly the page that has forty marks on it, most in the same state at the same time, and that is the case the stage collapses to a single animation. lineWeight is the one prop that opts a mark out of sharing: the weight is baked into the source geometry, so a mirror cannot vary it.
Each row's state
state on a row applies to its marks — working unless the host knows better. A browser session is searching; a voice channel is dictating. The row-level default keeps a list of otherwise identical resources reading as one kind of activity.
API
| Prop | Type | Default | Description |
|---|---|---|---|
rows* | readonly OccupancyRow[] | — | — |
className | string | — | — |
face | "cute" | "eyes" | "line" | — | — |
lineWeight | number | — | — |
maxVisible | number | 4 | Marks shown before the overflow count. |
nose | "slant" | "angular" | "hook" | "long" | "curve" | "bow" | null | — | — |
onSelect | ((agent: AgentLike, row: OccupancyRow) => void) | — | — |
sizePx | number | 22 | — |
style | CSSProperties | — | — |
OccupancyMark
| Prop | Type | Default | Description |
|---|---|---|---|
agent* | AgentLike | — | — |
className | string | — | — |
face | "cute" | "eyes" | "line" | — | — |
lineWeight | number | — | Heavier or lighter line. Setting this opts out of the shared stage. The stage can carry a line weight — it is part of the appearance key, so a heavier pen gets its own source — but a weight set on one row of a list is a one-off by nature, and minting a whole engine to be mirrored once is worse than just running it here. |
nose | "slant" | "angular" | "hook" | "long" | "curve" | "bow" | null | — | — |
onSelect | ((agent: AgentLike) => void) | — | Makes the mark a button. Without it the mark is presentational. |
sizePx | number | 22 | — |
state | "idle" | "sleeping" | "drowsy" | "bored" | "waking" | "powering-down" | "listening" | "thinking" | "searching" | "reading" | "writing" | "working" | "loading" | "progress" | "radar" | "orbit" | "dictating" | "uploading" | "sending" | "receiving" | "messaging" | "waiting" | "spawning" | "composing" | "dragging" | "happy" | "excited" | "laughing" | "playful" | "proud" | "celebrate" | "bouncing" | "shy" | "sad" | "angry" | "confused" | "suspicious" | "surprised" | "scared" | "curious" | "humming" | "alerting" | "notifying" | "refusing" | 'working' | — |
style | CSSProperties | — | — |