Centralised theming wrapper for BareDom web components. Wrap any subtree with <x-theme> to apply a consistent design token palette to all descendant components.
All BareDom components are theme-aware out of the box. Each component references the 50 design tokens defined by x-theme via var(--x-token, fallback) — they work identically with or without a theme wrapper.
Every component demo page includes a theme preset picker for live preview.
<x-theme preset="ocean">
<x-button>Themed button</x-button>
<x-alert text="Themed alert"></x-alert>
</x-theme>| Attribute | Type | Default | Description |
|---|---|---|---|
preset |
string | "default" |
Name of a built-in or custom preset. |
| Property | Type | Reflects | Description |
|---|---|---|---|
.preset |
string | yes | Gets/sets the preset attribute. |
None.
| Slot | Description |
|---|---|
| (default) | All child content. Tokens cascade into children. |
These tokens are set by x-theme on its :host and inherited by all descendant components via CSS custom property inheritance through shadow DOM.
| Token | Description |
|---|---|
--x-color-primary |
Primary brand color |
--x-color-primary-hover |
Primary hover state |
--x-color-primary-active |
Primary active/pressed state |
--x-color-secondary |
Secondary accent color |
--x-color-secondary-hover |
Secondary hover state |
--x-color-secondary-active |
Secondary active state |
--x-color-tertiary |
Tertiary/subtle accent |
--x-color-tertiary-hover |
Tertiary hover state |
--x-color-tertiary-active |
Tertiary active state |
--x-color-surface |
Card/panel background |
--x-color-surface-hover |
Surface hover state |
--x-color-surface-active |
Surface active/pressed state |
--x-color-bg |
Page-level background |
--x-color-text |
Primary text color |
--x-color-text-muted |
Secondary/muted text |
--x-color-border |
Default border color |
--x-color-focus-ring |
Focus indicator color |
--x-color-danger |
Destructive/error actions |
--x-color-success |
Success/positive states |
--x-color-warning |
Warning/caution states |
| Token | Default |
|---|---|
--x-font-family |
system-ui, -apple-system, sans-serif |
--x-font-family-mono |
ui-monospace, 'SF Mono', monospace |
--x-font-size-xs |
0.75rem |
--x-font-size-sm |
0.875rem |
--x-font-size-base |
1rem |
--x-font-size-lg |
1.125rem |
--x-font-weight-normal |
400 |
--x-font-weight-medium |
500 |
--x-font-weight-semibold |
600 |
--x-line-height-normal |
1.5 |
| Token | Default |
|---|---|
--x-radius-sm |
0.375rem |
--x-radius-md |
0.75rem |
--x-radius-lg |
1rem |
--x-radius-full |
9999px |
--x-border-width |
1px |
| Token | Default |
|---|---|
--x-space-xs |
0.25rem |
--x-space-sm |
0.5rem |
--x-space-md |
0.75rem |
--x-space-lg |
1rem |
--x-space-xl |
1.5rem |
| Token | Description |
|---|---|
--x-shadow-sm |
Subtle shadow |
--x-shadow-md |
Medium elevation |
--x-shadow-lg |
High elevation |
| Token | Default |
|---|---|
--x-z-dropdown |
1000 |
--x-z-modal |
1100 |
--x-z-toast |
1200 |
| Token | Default |
|---|---|
--x-opacity-disabled |
0.5 |
--x-opacity-placeholder |
0.6 |
| Token | Default |
|---|---|
--x-transition-duration |
140ms |
--x-transition-easing |
cubic-bezier(0.2,0,0,1) |
| Preset | Description | Notable Overrides |
|---|---|---|
default |
Blue/slate palette matching existing component defaults. | — |
ocean |
Teal/cyan, cool aquatic tones. | — |
forest |
Green/earth, warm natural tones. | — |
sunset |
Orange/red, warm vibrant tones. | — |
neo-brutalist |
High-contrast black/white, zero border-radius, offset shadows. | border-width:2px, font-weight-semibold:700, space-md:1rem |
aurora |
Soft purple/teal/pink with semi-transparent surfaces. | opacity-disabled:0.45 |
mono-ai |
Monochrome + neon cyan accent, monospace font. | line-height-normal:1.4 |
warm-mineral |
Earthy terracotta/sand/clay, digital naturalism. | — |
All presets define both light and dark mode token values. Dark mode is activated automatically via @media (prefers-color-scheme: dark).
Override any token directly on the element:
<x-theme preset="default" style="--x-color-primary: #e11d48;">
<x-button>Custom accent</x-button>
</x-theme>Register a reusable named preset via JavaScript:
import { registerPreset } from '@vanelsas/baredom/x-theme';
registerPreset("acme-brand", {
light: {
"--x-color-primary": "#e11d48",
"--x-color-secondary": "#7c3aed",
"--x-color-surface": "#fefefe"
},
dark: {
"--x-color-primary": "#fb7185",
"--x-color-secondary": "#a78bfa",
"--x-color-surface": "#1a1a2e"
}
});Then use it like any built-in preset:
<x-theme preset="acme-brand">...</x-theme>Partial presets are supported. Any tokens not specified fall back to the default preset values.
<x-theme preset="ocean">
<x-sidebar>...</x-sidebar>
</x-theme>
<x-theme preset="sunset">
<main>...</main>
</x-theme>Inner <x-theme> elements override outer ones via CSS custom property inheritance:
<x-theme preset="ocean">
<x-button>Ocean button</x-button>
<x-theme preset="sunset">
<x-button>Sunset button (overrides ocean)</x-button>
</x-theme>
</x-theme>x-themeusesdisplay: contentsand adds no visual or interactive elements.- All theme tokens respect
@media (prefers-color-scheme: dark)for dark mode support. - The
neo-brutalistpreset provides high contrast suitable for accessibility needs.
x-theme is a pure theming scope. It uses shadow DOM with only a <style> element and a <slot>. It has no visual rendering of its own and does not affect layout (display: contents).