Configuration
Learn how to configure theme switching, icons registry, zoneless change detection, and SSR hydration safety.
Application Setup
BeigeUI components are fully standalone with ChangeDetectionStrategy.OnPush. No root module is required:
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideBeTheme } from '@saarcmaststech/beige-ui';
import { appRoutes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(appRoutes),
// Applies the persisted theme during app init (avoids a flash).
provideBeTheme({
mode: 'system', // 'light' | 'dark' | 'system'
palette: 'beige', // preset id, or { base: '#3b82f6' }
radius: 'default', // 'sharp' | 'compact' | 'default' | 'relaxed' | 'pill'
density: 'comfortable', // 'compact' | 'comfortable' | 'spacious'
storageKey: 'my-app-theme' // null disables localStorage persistence
})
]
};Dark Mode & Theme Switching
BeigeUI ships an injectable BeThemeService. It writes the design tokens onto the root <html> element, resolves 'system' against prefers-color-scheme (and keeps tracking OS changes), and persists the choice to localStorage. Every DOM and storage access is guarded for SSR.
import { Component, inject } from '@angular/core';
import { BeThemeService } from '@saarcmaststech/beige-ui';
@Component({
selector: 'app-theme-toggle',
standalone: true,
template: `
<button (click)="theme.toggle()">
{{ theme.isDark() ? 'Light' : 'Dark' }} mode
</button>
`
})
export class ThemeToggleComponent {
readonly theme = inject(BeThemeService);
// theme.setMode('system') -> follows prefers-color-scheme (live)
// theme.isDark() -> resolved boolean signal
// Toggling sets [data-theme="dark"] on <html> and persists to localStorage.
}Brand Palette, Radius & Density
The same service drives runtime theming: apply a built-in preset, generate a full palette from a single brand hex, or switch the global corner-radius and spacing-density scales. Use provideBeThemeConfig() for defaults without eager initialization.
import { inject } from '@angular/core';
import { BeThemeService } from '@saarcmaststech/beige-ui';
const theme = inject(BeThemeService);
// 1. A built-in brand preset
theme.setPalette('ocean');
// 2. Any brand hex — the --beige-400/500/600 ramp and the
// --beige-color-primary* states are generated via color-mix()
theme.setBrandColor('#7c3aed');
// 3. Global shape + spacing scale (remaps --beige-radius-* / --beige-spacing-*)
theme.setRadius('relaxed');
theme.setDensity('compact');
// Copy the resulting token block for a static stylesheet:
console.log(theme.generatedCss());Theme Options Reference
Every option can be set at bootstrap with provideBeTheme() (which also applies the saved theme before the first render) or provideBeThemeConfig() (defaults only; the service is created on first injection). Each one is also a signal on BeThemeService with a matching set* method, for example theme.radius() and theme.setRadius('pill').
| Option | Type | Default | Values |
|---|---|---|---|
mode | 'light' | 'dark' | 'system' | 'system' | Colour mode. system follows prefers-color-scheme and keeps tracking OS changes. |
palette | preset id | { base } | 'beige' | Brand palette: beige, amber, terracotta, sage, forest, ocean, rose, slate, or { base: '#hex' } to generate one. |
surfacePreset | preset id | 'warm-cream' | Page, card, border and text surfaces: warm-cream, cool-slate, pure-gray, parchment, true-black, soft-moss. |
customSurfaces | object | all null | Overrides for page, card, subtle, border and textPrimary on top of the preset. |
radius | scale | 'default' | sharp, compact, default, relaxed, pill (remaps --beige-radius-*). |
density | scale | 'comfortable' | compact, comfortable, spacious (remaps --beige-spacing-* and --beige-padding-*). |
fontFamily | preset id | 'system' | system, inter, jakarta, outfit, lora, mono. Only system needs no web font; see below. |
fontSize | scale | 'default' | Scales the whole --beige-font-size-* type scale: compact (×0.9375), default (×1), large (×1.0625). See Density & Spacing. |
shadow | scale | 'subtle' | flat, subtle, deep (remaps --beige-shadow-*). |
motion | scale | 'smooth' | fast, smooth, none (remaps --beige-transition-*; none disables transitions). |
storageKey | string | null | 'beige-ui-theme' | localStorage key for the saved theme. null turns persistence off. Changes made in another window or iframe are picked up automatically. |
darkSelector | 'attribute' | 'class' | 'attribute' | How dark mode is applied to <html>: [data-theme="dark"] or .dark. |
const theme = inject(BeThemeService);
theme.setMode('dark'); // 'light' | 'dark' | 'system'
theme.setPalette('forest'); // or theme.setBrandColor('#7c3aed')
theme.setSurfacePreset('cool-slate');
theme.setCustomSurfaceColor('page', '#faf7f2'); // null clears one override
theme.resetCustomSurfaces();
theme.setFontFamily('inter'); // load the font's stylesheet yourself
theme.setFontSize('large');
theme.setShadow('deep');
theme.setMotion('none'); // disables transitions
theme.reset(); // back to the configured defaultsDark Mode Selector
By default dark mode sets data-theme="dark" on <html>. If another tool already keys off a .dark class, such as Tailwind's dark: variant, set darkSelector: 'class' and both will switch together. BeigeUI's styles respond to either.
import { provideBeTheme } from '@saarcmaststech/beige-ui';
// <html class="dark"> instead of <html data-theme="dark">
providers: [provideBeTheme({ darkSelector: 'class' })]Fonts & Using Tokens Without the Service
setFontFamily() only sets --beige-font-family; BeigeUI does not load web fonts. The system preset needs nothing, but for inter, jakarta, outfit, lora or mono add the font's stylesheet (for example from Google Fonts) yourself.
The service does nothing but write --beige-* custom properties, so you can skip it and set the same tokens in CSS. theme.generatedCss() prints the current choices as a ready-made block, and the Styling guide lists the tokens.
Icon Registry Setup
BeigeUI provides built-in feather/lucide icons and an injectable BeIconRegistry service to register custom SVGs:
import { inject } from '@angular/core';
import { BeIconRegistry } from '@saarcmaststech/beige-ui';
export class App {
private readonly iconRegistry = inject(BeIconRegistry);
constructor() {
// Register custom SVGs or extend existing icons
this.iconRegistry.registerIcon('custom-star', '<svg>...</svg>');
}
}SSR & Hydration Safety
All BeigeUI components avoid direct browser global access (e.g. window, document) during initialization. Overlays and DOM measurements are executed through afterNextRender() or guarded with isPlatformBrowser() for seamless Angular Server-Side Rendering (SSR).
