Kanzo UI
Hooks

useChartCapacity

How many categorical slots the live theme publishes, read off the cascade and re-read when the theme moves.

capacity 8 of 8 slots — everything past it folds into Other

  • Auth
  • Billing
  • Search
  • Ingest
  • Render
  • Export
  • Notify
  • Sync
  • AuditOther
  • ReplayOther

Ten series against a scheme with eight slots. The colours past capacity are already right without this hook — the theme author writes var(--muted-foreground) into them — but the count is not, and the count is what a legend, a tail-folding rule or a "+N more" row is built on.

Usage

import { useChartCapacity } from "@kanzo-tech/ui";

It is on the root barrel and needs no optional peer: reading a custom property off the cascade is not charting, and a surface that is not a chart may want the same count.

const host = useRef<HTMLDivElement>(null);
const capacity = useChartCapacity(host);

<Swatch color={categoricalColor(i, "var(--muted-foreground)", capacity)} />;

Pass the element the chart lives in. Omit it and the hook reads document.documentElement, which is right until a scoped theme override sits on an ancestor — and then it is quietly wrong.

Slots and capacity are two numbers

CHART_SLOTS is a compile-time 8, because a stylesheet cannot declare a variable number of custom properties. How many of those slots name a real category is the theme's --chart-capacity, and it is usually lower: measured over 24 brand hues, one every 15° at L 0.62 / C 0.15, capacity came back 6–8 (mean 7.50), with 11 of the 24 under 8. A set that carries six distinguishable categories says so rather than inventing two more.

The number travels down the cascade as --chart-capacity, the one declaration in the sheet that is not a colour — a custom property and not a JS constant, because the cascade is the only channel a scoped theme override travels down, and it is the same channel --chart-* itself arrives on. A stylesheet that declares nothing falls back to CHART_SLOTS.

Saying nothing and saying zero are different answers, and the difference is the whole reason this is a number rather than a flag. A theme that authors no --chart-* inherits the eight tokens.css publishes — see themes — so silence means the default set, all eight of it. Zero means this theme declines the channel: one ink, no category carried by colour, and past capacity compile writes var(--muted-foreground). Exactly one shipped theme says zero, and it is monochrome.

Past capacity, fold into Other — never cycle. A ninth series wearing slot 1 claims to be the first one, and identity stops meaning anything. categoricalColor(i, other, capacity) already returns the muted token past the boundary; capacity is how you get the label right too.

Why it is a hook

Reading a custom property requires a DOM, and the server has none. So the hook returns CHART_SLOTS on the first render — server and client agree — then the measured value after mount, and re-measures on every theme tick, because a theme swap changes the answer without changing a prop.

For the one-shot, non-reactive read — inside an effect that already has the element — reach for categoricalCapacity(host) directly.

API Reference

function useChartCapacity(host?: RefObject<Element | null>): number;
ParameterTypeDefault
hostRefObject<Element | null>document.documentElement

Returns

number — how many slots name a real category: --chart-capacity from the live cascade, clamped to CHART_SLOTS. CHART_SLOTS on the first render, and whenever the property is absent or unparseable.

ExportWhat it is
CHART_SLOTS8 — how many --chart-* properties the stylesheet declares
CHART_CAPACITY_PROPERTY"--chart-capacity" — the property this hook reads
categoricalCapacity(host)the same read, once, without the subscription
categoricalColor(i, other?, capacity?)the slot token for series i, or other past capacity

On this page