Components / ThinkingOrb

ThinkingOrb

The glyph on a live agent line — Elle's working status, where a pulsing green dot used to sit. Each state is a distinct animation, so the orb says WHAT is happening (searching, composing, connecting) rather than merely that something is. It is a status indicator, not a loader: for indeterminate loading use Spinner, and for the next page of a list use InfiniteLoader.

import { ThinkingOrb } from '@layers/ui/thinking-orb'

Rendered stock

House rules

  • Render ONE per live surface. A trace of steps takes static icons on its rows and a single orb on the one line that is actually live — a canvas per row scales the cost with the length of the work.
  • Hold ONE state for the whole span of work. Re-picking the state as the underlying activity changes was tried and rejected (founder, 2026-08-03): the states are different figures, not variations of one, so switching between them mid-turn reads as a glitch rather than as information. Let the orb mean "still working" and let the copy beside it say what.
  • It follows that the state is a per-surface choice, not a per-event one — web-v2 pins `LIVE_ORB_STATE`. Differentiate work with the row icons, which hold still because each row owns its own.
  • Two sizes: `20` for an inline text line, `64` at chat-avatar scale. They are separately tuned designs (their own dot counts, radii and speeds), not one design scaled — do not pass an arbitrary number.
  • Monochrome by design: ink on a transparent canvas, resolved light/dark from the nearest `.dark` or `data-theme` ancestor. The live semantic is carried by MOTION, not by hue — this replaced a green pulsing dot, and a colour-coded "live" is exactly what it replaced.
  • Beside a label that already announces the status, pass `aria-hidden` — the component then drops its own `role="img"`, so the row is not announced twice. Standing alone it labels itself per state.
  • Sits in a fixed-width glyph gutter wherever it shares a stack with other rows, so every label starts on one vertical line regardless of which glyph a row shows.
  • Vendored from `thinking-orbs` (MIT) with the theme observer and rAF loop rewritten to be shared page-wide. Read `packages/ui/src/thinking-orb/VENDOR.md` before editing anything under `thinking-orb/engine`.

See also