/** * 界面偏好,存在 localStorage 里。 * * 密度:工具栏和导航是只显示图标,还是图标加文字。 * 默认是「完整」——这个工具是隔一阵子才动一次的,纯图标对偶尔来一次的人不友好; * 想要紧凑的人自己去设置里切。 * * 主题:跟随系统、浅色、深色。默认跟随系统。 */ import { ref, watch } from 'vue' export type Density = 'full' | 'compact' const KEY = 'patchbay.density' const stored = localStorage.getItem(KEY) export const density = ref(stored === 'compact' ? 'compact' : 'full') watch(density, (value) => { localStorage.setItem(KEY, value) }) export function toggleDensity(): void { density.value = density.value === 'full' ? 'compact' : 'full' } export type Theme = 'system' | 'light' | 'dark' const THEME_KEY = 'patchbay.theme' const storedTheme = localStorage.getItem(THEME_KEY) export const theme = ref( storedTheme === 'light' || storedTheme === 'dark' ? storedTheme : 'system', ) // 显式选了浅色或深色就在 上标出来:tokens.css 里 :root[data-theme=…] 的权重 // 高于 :root 和媒体查询里的 :root,压过系统偏好。跟随系统则不加标记,交回给媒体查询, // 这样系统主题切换时界面仍然跟着变。 watch( theme, (value) => { localStorage.setItem(THEME_KEY, value) if (value === 'system') document.documentElement.removeAttribute('data-theme') else document.documentElement.setAttribute('data-theme', value) }, { immediate: true }, )