Theme Customizer
VdThemeCustomizer lets users personalize the theme in real time — palette, primary color, neutral scale, border radius, and font family — all on top of the default Open Color palette. Every control writes through the shared useThemePreference() singleton, so it stays in sync with the Theme Switcher and persists to localStorage. Color mode itself lives in the switcher; see the Theme Customizer walkthrough for the full story.
Live Demo
This is a real <VdThemeCustomizer>. It renders its own paint-roller trigger (click it) and teleports the panel under it — every change applies to this page immediately:
The buttons dogfood the exposed open() / toggle() methods; the switch flips the show-palette prop (watch the Palette section appear / disappear inside the panel).
Usage
Drop the component anywhere — it brings its own trigger and panel:
<script setup lang="ts">
import { VdThemeCustomizer } from "@vanduo-oss/vd3";
</script>
<template>
<!-- Renders its own trigger button + teleported panel -->
<VdThemeCustomizer :show-palette="true" />
</template> Mount it once (typically in your navbar). Any other button can open it by dispatching the vd:open-customizer window event.
Panel Sections
- Palette: Open Color (default) or Fibonacci (golden-angle) — shown when
show-paletteis true - Primary Color: 18 color options
- Neutral Color: 6 scales (Charcoal, Slate, Gray, Zinc, Neutral, Stone)
- Border Radius: 5 presets (0, 0.125, 0.25, 0.375, 0.5)
- Font Family: 5 options (JetBrains Mono, System Default, Ubuntu, Lato, Open Sans)
- Reset: restore every field to defaults
Color mode (light / dark / system) is owned by VdThemeSwitcher; both share the same singleton.
Available Primary Colors
Available Neutral Colors
Neutral colors affect backgrounds, borders, and text throughout the framework.
Programmatic Control
Open/close a specific instance, or any mounted one:
import { ref } from "vue";
import { VdThemeCustomizer } from "@vanduo-oss/vd3";
const customizer = ref<InstanceType<typeof VdThemeCustomizer>>();
// Drive a specific instance via its exposed methods:
customizer.value?.open();
customizer.value?.close();
customizer.value?.toggle();
// …or open any mounted instance from anywhere via the window event
// (e.g. a navbar button):
window.dispatchEvent(new CustomEvent("vd:open-customizer"));Theme Singleton API
The customizer is a thin UI over useThemePreference() — you can read or drive the same state directly:
import { useThemePreference } from "@vanduo-oss/vd3";
const theme = useThemePreference();
// Reactive current state (six fields):
theme.state.palette; theme.state.primary; theme.state.neutral;
theme.state.radius; theme.state.font; theme.state.theme;
// Setters — each persists to localStorage + applies to <html>:
theme.setPalette("fibonacci");
theme.setPrimary("violet");
theme.setNeutral("slate");
theme.setRadius("0.375");
theme.setFont("open-sans");
theme.setTheme("dark");
// Reset every field to the defaults:
theme.reset();API Reference
Props
| Prop | Type | Description |
|---|---|---|
showPalette | boolean | Render the palette-selection section (Open Color / Fibonacci). Default true. |
Exposed (template ref)
| Member | Description |
|---|---|
open() | Open the customizer panel. |
close() | Close the customizer panel. |
toggle() | Toggle the customizer panel. |
Window Event
| Event | Description |
|---|---|
vd:open-customizer | A mounted VdThemeCustomizer opens its panel when this window event is dispatched — wire it to a navbar trigger. |
CSS API
| Class / Attribute | Description | Type |
|---|---|---|
.vd-theme-customizer | Root wrapper; gains .is-open while the panel is open. | Class |
.vd-theme-customizer-trigger | The built-in paint-roller trigger button (also carries data-theme-customizer-trigger). | Class |
.vd-theme-customizer-overlay | Teleported backdrop; .is-active while open. | Class |
.vd-theme-customizer-panel | Teleported panel <aside role="dialog">; .is-open while open. | Class |
data-primary / data-neutral | Applied to <html>. Remap the --vd-primary-* / --vd-gray-* CSS variables. | State Attribute |
data-radius / data-font | Applied to <html>. Set --vd-radius-scale and the font stack (data-font removed for system). | State Attribute |
data-palette | Applied to <html>. Selects the Open Color or Fibonacci palette. | State Attribute |
localStorage Keys
| Key | Default | Description |
|---|---|---|
vanduo-palette | open-color | Active palette (Open Color / Fibonacci) |
vanduo-primary-color | black / amber | Primary brand color (auto default per scheme) |
vanduo-neutral-color | charcoal | Neutral / gray scale |
vanduo-radius | 0.5 | Border radius scale |
vanduo-font-preference | ubuntu | Font family |
vanduo-theme-preference | system | Color mode (shared with VdThemeSwitcher) |
Coordination with VdThemeSwitcher
Both components read and write the same useThemePreference() singleton, so they never clobber each other:
- Picking a color/neutral/radius/font in the customizer leaves the switcher's mode untouched
- Switching mode in the switcher re-derives the auto-default primary but never overwrites a color you chose
- Every field is shared via
localStorage