import { BulletChart } from "@elabs-ai/components-charts";npm install @elabs-ai/components-tokens @elabs-ai/components-ui @elabs-ai/components-chartsPaste it into Claude Code, Cursor, Codex or any other coding agent. Text in [brackets] is yours to fill in.
Add the brand-ui BulletChart chart (from @elabs-ai/components-charts) 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 BulletChart up before writing code: `npx -y @elabs-ai/components-cli docs BulletChart` prints its real props, variants, what it pairs with and what to avoid. 3. If @elabs-ai/components-charts is not installed yet: `pnpm add @elabs-ai/components-tokens @elabs-ai/components-ui @elabs-ai/components-charts` (or `npm install @elabs-ai/components-tokens @elabs-ai/components-ui @elabs-ai/components-charts`). 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.
Use it for
- How do these compare? Progress against a target.
- a single value against a target and 2–3 qualitative bands
Avoid
- more than one value/target pair needs comparing — use a small-multiple row of bullets or a `DumbbellChart`
Examples
Default
`size="md"` with bands + a target — the standard reading, axis included.
Loading
Loading skeleton (RM-183) — shown while `status="loading"`, sized like the real chart.
With Comparative
A second reference (last year) drawn as a small triangle notch, a shape distinct from the target's tick.
Over Target
The value clamps visually at the domain ceiling once it passes the target — the accessible name still states the real number.
No Bands
No `bands` prop — a single neutral track behind the bar.
Lower Is Better
`higherIsBetter={false}` — a lower-is-better measure (e.g. cost). The worst band sits at the HIGH end here, so the shade ramp mirrors: the darkest rung shades the high (worst) end instead of the low end.
Vertical
`orientation="vertical"` — the bar grows upward; the parent box supplies the height.
Small In Card
`size="sm"` (the default) — word-sized, no axis, sitting inline inside a narrow card.
API
BulletChart
| Prop | Type | Description |
|---|---|---|
valuerequired | number | The actual value — drawn as the bar. |
target | number | The target — drawn as a tick, taller and darker than the bar. |
comparative | number | A second reference (e.g. last year) — a small marker, a distinct shape from the target tick. |
bands | BulletBand[] | Qualitative ranges (ascending `to`), drawn as 2–3 neutral steps behind the bar. |
min | number | Scale floor. Default `0` — bars are zero-based; a caller-supplied negative floor is only honored when `value` itself is negative. |
max | number | Scale ceiling. Default: the largest of `value`/`target`/`comparative`/the last band's `to`, "nice"-rounded with 5% headroom. |
orientation | BulletChartOrientation | Bar direction. Default `"horizontal"`. |
size | BulletChartSize | `"sm"` (default) is word-sized with no axis; `"md"` adds a hairline tick axis. |
showAxis | boolean | Show the hairline tick axis. Default `size === "md"`. |
valueFormat | ChartValueFormat | How the value/target/comparative numbers are formatted. Default `"compact"`, one notation shared across the whole scale. |
messages | BulletChartLabels & ChartMessages | This chart's own words (the `messages` group, RM-191): the names interpolated into the auto-generated accessible description (`value`, `target`, `comparative`), and overrides of the catalogue's `charts.*` keys it prints (`charts.bulletChart.*`), for this chart only. The two key sets never collide: a catalogue key always starts with `charts.`. |
labels | BulletChartLabels | @deprecated Use `messages` — the same object, the same keys (RM-191, ADR 0042 A.1). Still read until 7.0.0, with one development warning; when both are set, `messages` wins. |
higherIsBetter | boolean | Whether ASCENDING band values read better (default `true`). Bands are always drawn low→high by position (`to` is ascending), but which END is "worst" depends on the measure: a lower-is-better KPI (e.g. cost) has its worst band at the HIGH end. Flips which side of the shade ramp gets the darkest (worst) rung so the visual always reads poor→good in the metric's own good direction, never just left→right. |
palette | ChartPalette | Colour ramp for the measure bar (RM-186): it takes the palette's first colour. Unset: `--chart-1`, as before. |
accessibleLabel | string | Accessible name for the chart region. AT announces this when the container receives focus or is read in flow. Example: "Monthly revenue bar chart" |
accessibleDescription | string | Supplemental description (series names, value ranges, last values, etc.). Rendered as a visually-hidden `<span>` associated via `aria-describedby`. Example: "Series: Revenue, Expenses. Range: 0–25,000." |
plotHeight | Responsive<ChartPlotHeight> | Height of the plot: pixels, or `{ aspect }` as width divided by height. Set `{ base, medium, narrow }` to vary it by breakpoint. |
margin | number | Partial<Margin> | Space around the plot, in pixels: one number for every side, or per side. |
status | ChartStatus | Show the loading skeleton until the data is ready. |
locale | string | BCP 47 locale the numbers are formatted in. |
currency | string | ISO 4217 currency code for currency values. |
maxFractionDigits | number | Most digits printed after the decimal point. |