Skip to content
TopClass UI

Theming

Light, dark and your own mode from one small CSS block, without touching a component.

The knobs

A knob is one custom property that many classes read. Change it once, every component follows.

Knob, Default, What it moves
KnobDefaultWhat it moves
--tc-radius0.5remEvery corner radius: control, box and chip
--tc-density1Every control height and its padding
--tc-motion1Every transition, and 0 under prefers-reduced-motion
--tc-list-rows7How many rows a list shows before it scrolls
--tc-ring-width2pxThe focus ring
--tc-line-width1pxEvery border

A mode is one block

There is no theme object and no provider prop for color. A mode is a CSS block selected by data-theme.

topclassui/tokens.css
[data-theme='ocean'] {
  --tc-primary-solid: var(--color-cyan-700);
  --tc-primary-on-solid: var(--color-white);
  /* cyan-800 not cyan-700: the whole ocean soft ramp fails at cyan-700. */
  --tc-primary-on-soft: var(--color-cyan-800);
  --tc-primary-hover: var(--color-cyan-800);
  --tc-primary-active: var(--color-cyan-900);
  --tc-radius: 9999px;
}

The ocean mode in full. It changes one tone and one knob.

Scoping a theme to a section

data-theme works on any element, not only the root. Set it on a panel and everything inside recomputes, including the soft tints and the focus ring.

<section data-theme="dark" className="bg-page text-body">
  {/* every component in here is dark, including
      its focus ring and its soft tints */}
</section>
In the page mode
Inside data-theme="ocean"

What is deliberately not themeable

The type scale, the spacing scale and the component anatomy are fixed, so two components always line up in a row.

If a knob you need is missing, open an issue. Overriding a token in your own CSS works, but nothing then checks its contrast.
NextRight to left