One palette, every component
Each component ships a default look and needs no configuration. When you want your own
palette, set the --gbs-* variables once, on :root, and every installed component follows —
the DataGrid included.
:root {
--gbs-accent: #7c3aed;
--gbs-accent-soft: #f3e8ff;
--gbs-radius: 10px;
--gbs-font-size: 14px;
}That is the whole API for theming the library. Everything below is for the cases where one palette is not enough.
How a value is resolved
Every component variable falls through the same chain, stopping at the first one that is set:
- The component's own variable —
--in-accent,--dg-accent,--ck-borderand so on. Set this to change one component, or one instance of it. - The shared variable —
--gbs-accent. This is the one you normally set. - The DataGrid's variable —
--dg-accent, when the grid's stylesheet is loaded. Kept so that projects which themed the grid before these shared variables existed still work. - The built-in default — a
light-dark()pair, so it follows the page's color scheme.
In CSS that chain looks like this, which is what you will see if you open any styles.css:
.in-root {
--in-accent: var(--gbs-accent, var(--dg-accent, light-dark(#2563eb, #60a5fa)));
}The shared variables
Defaults are written light / dark.
Surfaces and text
| Variable | Default | Used for |
|---|---|---|
--gbs-bg | #ffffff / #0b0b0e | Component background. |
--gbs-fg | #18181b / #f4f4f5 | Body text. |
--gbs-muted | #71717a / #a1a1aa | Hints, counters, secondary text. |
--gbs-subtle | #f4f4f5 / #1c1c20 | Quiet fills, such as a secondary button. |
--gbs-hover | #f4f4f5 / #1f1f23 | Hover background on buttons and menu items. |
--gbs-input-bg | #ffffff / #121216 | The inside of a field. |
--gbs-readonly-bg | #fafafa / #0e0e12 | A field that cannot be edited. |
--gbs-header-bg | #fafafa / #111114 | Grid header, modal footer. |
--gbs-header-fg | #3f3f46 / #d4d4d8 | Grid header text. |
Borders and shape
| Variable | Default | Used for |
|---|---|---|
--gbs-border | #e4e4e7 / #27272a | Outer borders. |
--gbs-border-subtle | #f0f0f2 / #1c1c20 | Row separators and other quiet lines. |
--gbs-border-control | #a1a1aa / #52525b | The outline of a checkbox or radio, which needs more contrast than a panel edge. |
--gbs-radius | 8px | Corner radius. |
--gbs-font-size | 13px | Base size; everything else is relative to it. |
--gbs-shadow | 0 10px 30px -8px … | Popovers and menus. |
--gbs-backdrop | rgb(9 9 11 / 0.45) / rgb(0 0 0 / 0.65) | Behind a modal or dialog. |
Accent and status
| Variable | Default | Used for |
|---|---|---|
--gbs-accent | #2563eb / #60a5fa | Selected, checked, active. |
--gbs-accent-fg | #ffffff / #0b1220 | Text on an accent fill. |
--gbs-accent-soft | #eff6ff / #172554 | Tinted backgrounds. |
--gbs-accent-strong | #1d4ed8 / #bfdbfe | The pressed state of an accent fill. |
--gbs-focus | #2563eb / #60a5fa | Focus rings. |
--gbs-danger | #dc2626 / #f87171 | Errors and destructive actions. |
--gbs-danger-fg | #ffffff / #1c0606 | Text on a danger fill. |
--gbs-success | #15803d / #4ade80 | Completed uploads, success toasts. |
--gbs-warning | #d97706 / #fbbf24 | Warnings. |
--gbs-info | falls back to --gbs-accent | Informational dialogs and toasts. |
Grid rows
Only the DataGrid uses these.
| Variable | Default | Used for |
|---|---|---|
--gbs-row-alt | #fcfcfd / #0e0e12 | Striped rows. |
--gbs-row-hover | #f4f4f5 / #18181c | Hovered row. |
--gbs-row-selected | #eef4ff / #14213d | Selected row. |
--gbs-row-selected-hover | #e2ecff / #1a2a4d | Selected and hovered. |
--gbs-cell-px | 12px | Horizontal cell padding. |
--gbs-pin-shadow | rgb(0 0 0 / 0.08) / rgb(0 0 0 / 0.5) | Edge of a pinned column. |
Dark mode
Defaults are light-dark() pairs, so they follow the page's color-scheme with no extra work.
Set it once:
:root {
color-scheme: light dark;
}To force a scheme regardless of the system setting, put class="dark" or data-theme="dark"
(or "light") on an ancestor such as <html>. Components respond to both.
If you set your own colors, give both schemes or your dark mode will keep the light values:
:root {
--gbs-accent: light-dark(#7c3aed, #c4b5fd);
}Theming one section
The variables inherit, so scoping a palette to part of a page is just a matter of where you set it:
.admin-area {
--gbs-accent: #0f766e;
--gbs-radius: 4px;
}Everything inside .admin-area uses the teal accent; the rest of the page does not.
Theming one component
Set the component's own variable instead of the shared one — it wins over --gbs-*:
.danger-zone .bt-root {
--bt-bg: #b91c1c;
}Or inline, for a single instance:
<Input style={{ "--in-radius": "999px" } as CSSProperties} />Each component's page lists its own variables.
With Tailwind
All component rules live in the CSS components layer, so a utility class passed through
className or classNames beats them without !important:
<Button className="rounded-full px-6" />Use utilities for one-off adjustments and --gbs-* for the palette. If your design tokens are
already Tailwind theme variables, point the two at each other once:
:root {
--gbs-accent: var(--color-violet-600);
--gbs-danger: var(--color-rose-600);
}Before you ship a palette
Check contrast on the pairs that carry meaning: --gbs-fg on --gbs-bg, --gbs-muted on
--gbs-bg, and --gbs-accent-fg on --gbs-accent. The defaults meet WCAG AA in both
schemes; a custom accent is the usual way that gets lost, most often on small text such as
hints and counters.