Files
PilotVault/Web App/web/src/theme.js
T
tajniak81andClaude Opus 4.8 afc6952eda Initial commit: PilotVault multi-service project
Add API Server (Go/PocketBase), Web App (Go BFF + Vue), Fly App
(Flutter/DJI MSDK), Adobe Plugin, and Docker/Docker AIO deployment
configs. Design assets and build artifacts are gitignored.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 11:43:33 +02:00

74 lines
2.0 KiB
JavaScript

// Theme store — light is the PilotVault default. The user picks a *mode*
// (light | dark | system); `theme` is the resolved value (light | dark) that
// actually drives [data-theme] on <html>. The pre-paint script in index.html
// resolves the same way to avoid a flash before hydration.
import { ref } from 'vue'
const KEY = 'pv_theme'
// Concrete ground colors (--bg-app per theme), set inline on <html> so the
// viewport canvas repaints reliably when the theme flips (Chromium quirk).
const GROUND = { light: '#EEF0F3', dark: '#0B1730' }
const media = typeof window !== 'undefined' && window.matchMedia
? window.matchMedia('(prefers-color-scheme: dark)')
: null
function systemTheme() {
return media && media.matches ? 'dark' : 'light'
}
function initialMode() {
try {
return localStorage.getItem(KEY) || 'light'
} catch {
return 'light'
}
}
function resolve(mode) {
return mode === 'system' ? systemTheme() : mode
}
function paint(resolved) {
const html = document.documentElement
html.setAttribute('data-theme', resolved)
html.style.backgroundColor = GROUND[resolved] || GROUND.light
}
// The user's chosen mode, and the concrete resolved theme.
export const themeMode = ref(initialMode())
export const theme = ref(resolve(themeMode.value))
export function setThemeMode(mode) {
themeMode.value = mode
const resolved = resolve(mode)
theme.value = resolved
paint(resolved)
try {
localStorage.setItem(KEY, mode)
} catch {
/* ignore */
}
}
// Back-compat alias used by older call sites.
export const applyTheme = setThemeMode
// Simple light/dark flip for the header toggle. From "system" it commits to the
// opposite of whatever is currently showing.
export function toggleTheme() {
setThemeMode(theme.value === 'dark' ? 'light' : 'dark')
}
// Follow the OS while in "system" mode.
if (media) {
media.addEventListener('change', () => {
if (themeMode.value === 'system') {
const resolved = systemTheme()
theme.value = resolved
paint(resolved)
}
})
}