Skip to content
bref / ui

Svelte components, simply.

Star

Theme

An opt-in theme setup with light, dark and system modes, semantic palette variables, a global reset and the Material Symbols font. ThemeModeToggle sets color-scheme metadata for your own mode control.

Usage

Current mode: light. This control and the navbar control share the same mode.

check_circle
Svelte
<script lang="ts">
	import { Select, Theme, ThemeModeToggle } from 'bref-ui';
	import type { ThemeMode, ThemeProps, Palette, Color } from 'bref-ui/types';
	let mode = $state<ThemeMode>('auto');
	const modes = [
		{ id: 'auto', label: 'System' },
		{ id: 'light', label: 'Light' },
		{ id: 'dark', label: 'Dark' }
	];
</script>

<Theme>
	<ThemeModeToggle {mode} />
	<label for="theme-mode">Theme</label>
	<Select
		id="theme-mode"
		items={modes}
		bind:value={() => mode, (next) => (mode = next as ThemeMode)}
	/>
</Theme>

Playground

Try a shared palette or separate light and dark colors. Changes apply to the whole demo site while this page is open.

Live preview

check_circle

Readable text and semantic colors follow the shared theme.

Contrast — light: text 15.76:1, primary filled 5.78:1; dark: text 15.13:1, primary filled 8.22:1. Ratios cover normal text and the primary filled button at rest; check other variants and interaction states separately.

Settings

Theme mode
Palette
View generated code
Svelte
<script>
	import { Theme, ThemeModeToggle, Icon, Button } from 'bref-ui';
</script>

<Theme>
	<ThemeModeToggle mode="light" />
	<Icon name="check_circle" color="success" label="Complete" size="large" />
	<Button variant="neutral" color="primary" label="neutral" />
	<Button variant="soft" color="primary" label="soft" />
	<Button variant="filled" color="primary" label="filled" />
	<p>Readable text and semantic colors follow the shared theme.</p>
</Theme>

Props

Component props
PropTypeRequiredDefaultDescription
Theme: palettePalette | { dark: Palette; light: Palette }No{}Optional hex colors for the nine roles; a single palette applies to both modes. Invalid hex values throw.
Theme: childrenSnippetNoOmittedApplication content.
ThemeModeToggle: modeThemeModeNoautolight, dark or auto (system preference).

Choosing a mode

Use the navbar theme control to test every example in light, dark or system mode. System follows the browser preference.

ThemeModeToggle renders color-scheme metadata and has no visible control. Pass a reactive mode from an application Select or Button. Theme accepts a children snippet; neither theme component forwards native attributes or exposes an element binding.

Applications can also set data-theme="light" , data-theme="dark" or data-theme="auto" on a container to select its palette.

Palette

The active palette includes foreground and background colors, accents and semantic status colors.

--color-primary
--color-secondary
--color-foreground
--color-background
--color-muted
--color-info
--color-success
--color-warning
--color-error

Customization

Pass palette to the application-root Theme. Omitted roles retain defaults. Existing CSS overrides still apply; verify contrast for custom colors.

Svelte
<Theme palette={{ primary: '#875000' }} />
<Theme palette={{ light: { primary: '#875000' }, dark: { primary: '#e8bb75' } }} />

Override light and dark variables such as --color-primary-light and --color-primary-dark on :root or a themed container, or override an active color alias on a specific component. Verify final foreground/background contrast.

Theme applies a global reset and loads Material Symbols. Components do not import it automatically.

Body text uses the --font-sans system sans fallback without loading a text font. Set --font-text to use your own font, as this gallery does, or customize --font-sans . Theme does not set font weight or smoothing.

Theme composes internal colors, surfaces, fonts and styles components. Surface and Button share the surface paint recipe. Use the typed helper from bref-ui on native HTML; copied sources include it at theme/surface.ts .

Svelte
<Button color="primary" label="Default primary" onClick={save} />
<Button
	color="primary"
	label="Local color override"
	onClick={save}
	style="--color-primary: var(--color-secondary);"
/>