Theming
The supported override surface for re-theming @chassis-ui/react — custom properties, light/dark mode, and the few components with a stylesheet of their own.
@chassis-ui/react owns almost no visual styling of its own — every component applies
@chassis-ui/css class names, the same classes a hand-written page using chassis-css directly
would use. Re-theming this library, for nearly every component, means re-theming
@chassis-ui/css/@chassis-ui/tokens instead. The exceptions are the few components covered
under Component-scoped styles below.
Custom properties
@chassis-ui/tokens compiles a brand's design tokens into --cx-* custom properties — colors,
spacing, radii, typography — that chassis-css's compiled stylesheet declares at :root. These are
the supported theming surface: override any of them directly in an application stylesheet, or set
one inline on a scoping ancestor to theme a subtree differently.
:root {
--cx-primary: #6d28d9;
}The full, up-to-date token list lives in chassis-css's own Design Tokens reference rather than duplicated here, since it's large and actively maintained.
Switching brand or mode
A brand swap can happen at build time or at runtime. At build time, compile a different
@chassis-ui/tokens brand file ahead of chassis-css's own Sass — a chassis-css-level build step
with no @chassis-ui/react involvement. At runtime, since every token is a plain custom property,
override it directly from application code.
Light and dark mode work the same way. chassis-css re-declares its :root-level tokens under
[data-cx-theme="light"]/[data-cx-theme="dark"] attribute selectors — setting that attribute,
typically on <html>, switches modes:
document.documentElement.setAttribute('data-cx-theme', 'dark')@chassis-ui/react doesn't read or set this attribute itself anywhere — mode switching stays
entirely in application code.
Component-scoped styles
Calendar, RangeCalendar, DatePicker, DateRangePicker, TimeField, DataGrid, Divider's label,
Notification's fade, NumberField's step buttons, Progress's indeterminate bar and Table's sort/selection UI have no chassis-css visual equivalent, so
@chassis-ui/react ships its own compiled stylesheet for just those pieces — see
Component-specific styles
for the import. That stylesheet already builds on the --cx-* token surface above wherever
chassis-css has one, so overriding those tokens re-themes these components too.
Not a theming hook
A few things are real, inspectable CSS but aren't a stability contract — they can change shape without a major-version signal, so don't target them directly:
--cx-*properties declared only inside a component-class selector, not at:root. chassis-css's context-color system re-declares many--cx-*names inside selector blocks like.btn/.cardas its own internal implementation — overriding the:roottoken it derives from is the supported path, not the re-declaration itself.data-cx-*attributes other thandata-cx-theme—data-cx-placement,data-cx-inline, and similar are a wire protocol between@chassis-ui/reactand chassis-css's own selectors, not a theming hook.- Internal class names the calendar/datepicker family's own stylesheet uses for its layout —
implementation detail, not a documented public class API. Style through the props those
components expose (
className,size, ...) instead.
A component-scoped --cx-* re-declaration and a :root-level token can share the same name.
Confirm a property is declared at :root in the compiled stylesheet before relying on it —
overriding a name that only exists inside a component selector has no effect from outside.