Skip to main content

TokenSpotlight

Display

A row of token chips (concept §4.5, §5a "Scroll choreography 5"): hovering or focusing one sets data-token-spotlight on <html> and marks every element on the page that resolves to the same colour with data-token-consumer (never an inline style), so a stylesheet can draw the highlight.

import { TokenSpotlight } from "@elabs-ai/components-ui";
Install
npm install @elabs-ai/components-tokens @elabs-ai/components-ui

Skipping the @source line is the most common first failure: Tailwind does not scan node_modules, so every component renders unstyled. The one-time wiring

Prompt for your coding agent

Paste it into Claude Code, Cursor, Codex or any other coding agent. Text in [brackets] is yours to fill in.

Add the brand-ui TokenSpotlight component (from @elabs-ai/components-ui) to this project.

1. Read https://elabs-ai.com/llms.txt first: it maps every package and the rules. If you can use MCP servers, connect https://elabs-ai.com/mcp and use its search, docs and tokens tools. If not, run the same lookups in the terminal: `npx -y @elabs-ai/components-cli search "<what you need>"` and `npx -y @elabs-ai/components-cli docs <Component>`.
2. Look TokenSpotlight up before writing code: `npx -y @elabs-ai/components-cli docs TokenSpotlight` prints its real props, variants, what it pairs with and what to avoid.
3. If @elabs-ai/components-ui is not installed yet: `pnpm add @elabs-ai/components-tokens @elabs-ai/components-ui` (or `npm install @elabs-ai/components-tokens @elabs-ai/components-ui`). If this is the first brand-ui package in the project, wire it once: import `@elabs-ai/components-tokens/styles.css` plus the `themes/light.css` and `themes/dark.css` stylesheets in the CSS entry, add one Tailwind `@source` line per installed @elabs-ai package (Tailwind does not scan node_modules, so without it everything renders unstyled), and wrap the app root in `ThemeProvider` from `@elabs-ai/components-tokens`.
4. Use it here: [the screen or file, and what it should show]
5. Rules: use only @elabs-ai/components-* components and the semantic tokens — no raw colours, no raw font sizes, no arbitrary Tailwind values. Look up each component's real props with the docs tool before you use it; never guess a prop.
6. Done means: the typecheck passes, `npx -y @elabs-ai/components-cli audit src --strict` reports nothing, and you have opened the app and looked at every screen you touched in the light and the dark theme.

Examples

6 live examples

Hover Highlights Consumers

Hovering a chip sets `data-token-spotlight` on `<html>` and marks its consumers; moving off clears both.

Keyboard Focus

Keyboard focus on a chip does the same as hover — the spotlight is never mouse-only.

Reduced Motion

Under reduced motion the outline still appears — CSS `animation: none` (`token-spotlight.css`) just removes the pulse. Asserted on the computed style directly (`animationName`), never on `document.getAnimations()`: an unrelated `transition-colors` on the outlined element is a real `CSSTransition` that legitimately runs for a few ms right after the attribute flips, and is not the pulse this story is about.

Only Real Consumers

Only elements that visibly PAINT the token are marked: a border counts only on a side with a width (every element carries `border-color: var(--border)` at width 0 from the base layer), and the text colour counts only on an element with its own text — not on a wrapper that merely inherits it. SVG shapes are reported as their `<svg>`.

Resolved Values

Each chip shows the token’s resolved value in a readable form: colours as a rounded `oklch(L C H)` whatever colour space the CSS build emitted (never `lab()`), lengths such as `--radius` as px (never a raw `calc()`). Values are re-read when `data-theme` or `data-decoration` changes on `<html>`.

API

TokenSpotlight

PropTypeDescription
tokensrequiredreadonly TokenSpotlightToken[]Chips to render, in order.
onSpotlight(token: string | null) => voidFires with the token on hover/focus, and `null` when the spotlight clears.
scanLimitnumberUpper bound on elements a scan pass examines. Default {@link TOKEN_SPOTLIGHT_SCAN_LIMIT}.
maxMarksnumberOpt-in upper bound on elements MARKED as consumers, unlike {@link scanLimit} (which only bounds elements EXAMINED). Unset by default — no cap. A token like `--foreground` or `--border` can visibly mark hundreds of elements on a real page; set `maxMarks` when that flood is a problem for your host page (#616).
labelsPartial<TokenSpotlightLabels>

Also accepts: Omit< React.HTMLAttributes<HTMLDivElement>, "onSelect" >