Appearance
A theme and density switcher
Themes and density are data attributes on the root element, so switching them is one function call and nothing re-renders. This is the switcher in the kitchen-sink app, as a component:
xml
<contract>
{
"name": "ThemeBar",
"role": "group",
"parts": ["root"],
"description": "Buttons that switch the theme and the density."
}
</contract>
<script>
import { setDensity, setTheme } from '@pixelscriptio/tessera/tokens'
const light = () => setTheme(null)
const dark = () => setTheme('dark')
const comfortable = () => setDensity(null)
const compact = () => setDensity('compact')
</script>
<template>
<div class="root">
<Button tone="neutral" emphasis="outline" size="sm" @press="light">Light</Button>
<Button tone="neutral" emphasis="outline" size="sm" @press="dark">Dark</Button>
<Button tone="neutral" emphasis="outline" size="sm" @press="comfortable">Comfortable</Button>
<Button tone="neutral" emphasis="outline" size="sm" @press="compact">Compact</Button>
</div>
</template>
<style>
.root {
display: flex;
gap: $space.2;
}
</style>setTheme(null) removes the attribute, which returns to the base values. setTheme('dark') sets data-theme="dark".
Following the system, and remembering a choice
A theme file with "$auto": "prefers-color-scheme: dark" also applies under data-theme="auto", which follows the operating system. To remember a user's choice, store it yourself and call setTheme at startup, before the first render so there is no flash:
ts
import { setTheme } from '@pixelscriptio/tessera/tokens'
const saved = localStorage.getItem('theme')
setTheme(saved ?? 'auto')Put this in app/main.ts, above createApp().