import { VariantExplorer } from "@elabs-ai/components-process";npm install @elabs-ai/components-tokens @elabs-ai/components-ui @elabs-ai/components-processPaste it into Claude Code, Cursor, Codex or any other coding agent. Text in [brackets] is yours to fill in.
Add the brand-ui VariantExplorer component (from @elabs-ai/components-process) 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 VariantExplorer up before writing code: `npx -y @elabs-ai/components-cli docs VariantExplorer` prints its real props, variants, what it pairs with and what to avoid. 3. If @elabs-ai/components-process is not installed yet: `pnpm add @elabs-ai/components-tokens @elabs-ai/components-ui @elabs-ai/components-process` (or `npm install @elabs-ai/components-tokens @elabs-ai/components-ui @elabs-ai/components-process`). 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
Dna Strip
"Variant DNA": two-letter chips so long sequences fit; full names stay in the accessible name. A loan-application log with more than eleven activities, so the rarer activities share the hatched "other" swatch.
Swatch Strip
`sequenceDisplay="swatch"`: every step is one identity block with no text — the densest strip, for a rail too narrow for codes. Hover a block for its activity; the strip's accessible name still lists the full sequence.
Coverage Slider
The coverage slider selects the fewest paths that cover the target share of cases.
With Selection
Two variants already selected; keyboard selection with arrows and Space.
Table View
The accessible table twin — the same numbers as the list, as a real table.
Loading
Waiting for variants.
Empty
A filter left no cases.
Two Thousand Variants
2 000 variants. The play test scrolls the list and asserts the number of mounted rows stays bounded — the virtualization that keeps scrolling smooth. It does not time frames, which is too noisy to gate CI on.
API
VariantExplorer
| Prop | Type | Description |
|---|---|---|
variantsrequired | Variant[] | Variants in `extractVariants` order (count descending). |
colorScalerequired | ActivityColorScale | The shared colour scale — hand `ProcessMap` the same instance. |
selectionStates | ProcessSelectionStates | Tri-state per variant id; an absent key means `"associated"`. |
onSelectrequired | (variantIds: string[], mode: VariantSelectMode) => void | Fires with the ids to select and how to apply them. The explorer never filters. |
onFilterIntent | (intent: FilterIntent) => void | When given, a button emits `{ kind: "variant", ids }` for the selected variants. |
columns | VariantExplorerColumn[] | Numeric columns to show. @default ["cases", "coverage", "medianDuration"] |
coverageTarget | number | Initial coverage target, `0..1`. When given, a slider selects the smallest prefix of variants whose cumulative share reaches the target (mode `"replace"`). |
abbreviate | boolean | "Variant DNA" strip: two-character codes instead of full activity labels. |
sequenceDisplay | "text" | "swatch" | `"swatch"`: each step is one identity block with no text — the densest strip, for a narrow rail. The strip keeps its accessible name and every block its `title`. @default "text" |
tableView | boolean | Render the accessible table twin instead of the list. @default false |
loading | boolean | No variants yet. Renders the loading panel rather than an empty list. |
labels | Partial<VariantExplorerLabels> | Override any user-visible string. |