Skip to content

Registry: add a chart item #227

Description

@fponticelli

The registry now covers every shadcn/ui component except chart, form (see the sibling issue), and two composition-only items. chart is the largest remaining gap and the only one that needs a dependency decision, so it is filed rather than built.

What upstream is

shadcn's chart.tsx is a thin wrapper over Recharts: a ChartContainer that injects CSS variables from a ChartConfig (--color-<key> per series), plus ChartTooltip, ChartTooltipContent, ChartLegend and ChartLegendContent. There is no chart drawing code of its own — the value is entirely the theming bridge and the tooltip/legend recipes.

Why it is not a straight port

The registry's standing rule is that recipes are shadcn's, ported verbatim, and every item is source you own with no runtime dependency beyond @llui/dom + @llui/components. chart breaks that in a way none of the other 82 items do:

  • It needs a charting library. Recharts is React-only, so a port has to pick a different one (or draw SVG directly), and at that point the class recipes are the only thing left of upstream — the component's actual behaviour would be an LLui invention wearing a shadcn name.
  • There is no LLui machine to skin. Every other skin sits on a @llui/components machine that owns state, keyboard and ARIA. A chart has real interaction (hover, focus, keyboard traversal of series, an accessible table fallback) and none of it exists yet.

So this is two decisions, not one:

  1. Draw with what? Options, roughly in increasing cost: hand-rolled SVG for a small set of chart types (line, area, bar, pie) — no dependency, full control, most work; a framework-agnostic library that returns DOM/SVG; or a foreign() seam around an existing library, as @llui/lexical does for Lexical.
  2. Is there a chart MACHINE? If charts get keyboard traversal and an accessible fallback — and they should — that belongs in @llui/components, not in a copied recipe.

Suggested scope for a first pass

Deliberately narrow, to get the theming bridge landed without committing to a charting engine:

  • ChartContainer + the ChartConfig--color-<key> bridge, which is the genuinely portable part and is what makes a chart match the app's theme in both light and dark.
  • ChartTooltipContent / ChartLegendContent recipes, ported verbatim — they are ordinary surfaces and need no library.
  • A demo section drawing one chart type with plain SVG, to prove the bridge.

That gives consumers the theming and the surfaces, and leaves the engine choice open.

Definition of done

  • Decision recorded on the drawing approach (an ADR under docs/adr/)
  • registry/llui/ui/chart.ts with the container + tooltip/legend recipes
  • Registered in registry.json, copied into examples/registry-demo, and RENDERED there — the sync test requires the copy, and rendering is what has caught every skin bug so far
  • Passes scripts/test/registry-attrs.test.ts (a recipe may not name an attribute its machine never publishes) and the Tailwind dead-class guard
  • Accessibility: whatever is drawn needs a text alternative; a chart that is only an <svg> is unreadable to a screen reader

Notes

scripts/test/registry-attrs.test.ts has a MACHINE_OF map with a vacuity check — a new skin with no machine must be listed there with [], or the test fails rather than silently skipping it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    components@llui/components packageneeds-triageMaintainer needs to evaluatenew-componentProposal for a new headless component

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions