Skip to content
npm

Theming & design tokens ​

All visuals derive from CSS custom properties (design tokens): color scales, fonts, radii. Theming = overriding tokens.

Token families ​

FamilyTokensUsed for
Primary--nvb-color-primary-050 … 950brand, focus, active states
Neutral--nvb-color-neutral-000 … 950surfaces, borders, text
Risk / Warning / Caution--nvb-color-risk-*, --nvb-color-warning-*destructive & warning states
Success / Info--nvb-color-success-*, --nvb-color-info-*positive & informational states
Typography--nvb-font-family-basebase font stack
Charts--nvb-chart-single, --nvb-chart-1 … 8, --nvb-chart-otherchart colors (see below)

Values are oklch(...) colors on an 050-950 scale (050 lightest). Components mix tokens with color-mix(), so overriding a scale re-colors everything consistently.

Where the tokens live ​

Every name carries the nvb- prefix, and the declarations sit on .nvb-root and on the runtime's shadow host, never on :root. Both parts matter for a host application.

The prefix keeps our palette out of yours. A design system that stores its colors as HSL channel triplets for Tailwind writes --color-neutral-300: 214 32% 91%, and a library declaring that same name as an oklch color would win inside the view. Any host rule that still applied there would then compute hsl(oklch(...)), which is not a color at all, so the declaration would fall back to currentColor and inputs would come out with thick black borders. Prefixed names cannot collide, so both palettes stay intact.

Not putting them on :root keeps the reverse true: importing our stylesheet cannot change how the rest of your application looks.

--nvb-surface is the one token meant for the host rather than for us. .nvb-root paints its own background so a light theme stays readable on a dark page, and setting --nvb-surface: transparent turns that off when the view already sits on a surface you control.

Chart colors ​

A bar, line or area chart has one series and draws it in --nvb-chart-single, which is your primary color by default. Pie and donut slices take --nvb-chart-1 to --nvb-chart-8 in order, and the folded Other slice --nvb-chart-other. The default eight are a palette checked for color blind readers in both modes, and their order is part of that: neighbours were picked to stay apart. To match your brand, override the values but keep a similar spread of hues, and give the dark mode its own steps through setCustomTheme if you change them.

Light / dark mode ​

html
<ngx-view-builder-designer [theme]="'dark'" ... />
<ngx-view-builder-runtime  [theme]="theme()" ... />

or api.setThemeMode('dark'). Creators can also set a default in Form settings.

A panel used as a page section with Section colours: Dark takes the dark palette for itself only, inside a light view. It does this by matching the .nvb-section-theme-dark class in the same token block as the dark theme, so your dark overrides from setCustomTheme apply there too.

Overriding tokens ​

Quick overrides, a flat map applied on top of the active theme:

ts
api.setCssVariables({
  '--nvb-color-primary-500': 'oklch(64% 0.19 145)',   // brand green
  '--nvb-font-family-base': "'Inter', sans-serif",
});

or declaratively: [cssVariables]="{ '--nvb-color-primary-500': '...' }", or runtimeSettings.cssVariables at bootstrap.

These refine the theme, they do not replace it. Only the variables you pass change, and everything else keeps coming from the active light or dark theme. So one brand color in dark mode leaves the rest of the dark palette alone, and when the mode switches the same overrides are applied again on top of the new theme. If you want a different set per mode, that is what setCustomTheme below is for.

Full custom theme, with per-mode token sets:

ts
api.setCustomTheme({
  shared: { '--nvb-font-family-base': "'Inter', sans-serif" },
  light:  { '--nvb-color-primary-500': 'oklch(64% 0.19 145)' },
  dark:   { '--nvb-color-primary-500': 'oklch(72% 0.17 145)' },
  mergeWithDefaults: true,     // start from the built-in theme
});

runtimeSettings.customTheme accepts the same object at bootstrap.

Custom elements & theming ​

Write custom element styles against the tokens and they follow every theme automatically:

css
.note {
  background: color-mix(in oklab, var(--nvb-color-info-100) 24%, var(--nvb-color-neutral-000));
  border: 1px solid var(--nvb-color-neutral-300);
  color: var(--nvb-color-neutral-900);
}

Never hardcode hex colors in element components; dark mode will break.

onThemeModeChanged, onCustomThemeChanged, onCssVariablesChanged fire on every change, which is handy for syncing the host app's own chrome.

For per-view CSS (rather than tokens), see Custom CSS.