useTheme()
useTheme() provides a complete theme management system (the theme is decided by theme.mode in swift.config.json):
- Persists the theme value to
localStorageand restores it automatically on page refresh. - Writes the current theme to the
html[data-theme]attribute so global CSS can switch style variables with[data-theme='dark']selectors. - In
automode, reads the system preference (prefers-color-scheme) and applies light or dark accordingly;resolvedThemegives the actual current light/dark (autoalso resolves tolight/dark). - Only
theme.mode: 'toggle'lets users switch (toggleTheme/setThemetake effect); insystem/dark/lightmodes the theme is locked by the mode and both are no-ops.
useTheme()is registered unconditionally and safe to call in anytheme.mode— outside toggle mode the switch methods are no-ops (the theme is locked by the mode).
Basic Usage
toggleTheme tri-state cycle (real theme)
加载中...
setTheme direct switch
加载中...
<script setup lang="ts">
const { theme, setTheme, toggleTheme } = useTheme()
</script>
<template>
<!-- Display current theme -->
<span>Current theme: {{ theme }}</span>
<!-- Cycle through themes -->
<button @click="toggleTheme">
{{ theme === 'dark' ? 'Switch to Light' : 'Switch to Dark' }}
</button>
<!-- Set a specific theme -->
<button @click="setTheme('light')">Light</button>
<button @click="setTheme('dark')">Dark</button>
<button @click="setTheme('auto')">Follow System</button>
</template>
Watch Theme Changes
const { theme } = useTheme()
watch(theme, (newTheme) => {
console.log('Theme changed to', newTheme)
})
CSS Integration
data-theme + semantic tokens
加载中...
The framework controls global theme variables via the html[data-theme] attribute. Define CSS variables for each theme in app/assets/css/:
:root {
--background: #ffffff;
--foreground: #1f2937;
}
[data-theme='dark'] {
--background: #0f172a;
--foreground: #f1f5f9;
}
Return Values
| Name | Type | Description |
|---|---|---|
theme | Ref<'light' | 'dark' | 'auto'> | The user-chosen theme state. Initial value derived from mode (system→auto / dark→dark / light→light / toggle→default) |
resolvedTheme | ComputedRef<'light' | 'dark'> | Actual current light/dark (auto resolves to the system preference). Switch logos / illustrations off this |
mode | 'system' | 'toggle' | 'dark' | 'light' | The site's theme mode (readonly, from the theme.mode config) |
toggleStates | 2 | 3 | Switcher form (readonly). 3 = tri-state cycle / 2 = two-state |
setTheme | (t: 'light' | 'dark' | 'auto') => void | Set a specific theme, persisting to localStorage and updating html[data-theme]. Toggle mode only |
toggleTheme | () => void | Cycle themes. Toggle mode only; tri-state auto→light→dark→auto (can return to auto) / two-state light↔dark |
Notes
useTheme()state is globally shared — multiple calls return the same reactive reference; no state inconsistency to worry about.toggleTheme/setThemeonly take effect intheme.mode: 'toggle'; in other modes they are no-ops (the theme is locked by the mode, not user-changeable).- When you don't want to write your own switch button, use the framework's built-in
SwThemeSwitch— it self-gates and renders only in toggle mode. - On initialization the saved theme is read from
localStorage(toggle mode only); when none is saved, the initial value is derived from the mode.