feat: architectural grid editor fullPage + slash commands + doc info panel + AI title
This commit is contained in:
83
memento-note/lib/apply-document-theme.ts
Normal file
83
memento-note/lib/apply-document-theme.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Valeurs persistées pour User.theme / localStorage `theme-preference`.
|
||||
* Une seule source de vérité pour le DOM : évite les écarts entre header, settings et hydratation.
|
||||
*/
|
||||
export const THEME_IDS = [
|
||||
'light',
|
||||
'dark',
|
||||
'auto',
|
||||
'sepia',
|
||||
'midnight',
|
||||
'rose',
|
||||
'green',
|
||||
'lavender',
|
||||
'sand',
|
||||
'ocean',
|
||||
'sunset',
|
||||
'blue',
|
||||
] as const
|
||||
|
||||
export type ThemeId = (typeof THEME_IDS)[number]
|
||||
|
||||
const NAMED_PALETTE_IDS: ThemeId[] = [
|
||||
'sepia',
|
||||
'midnight',
|
||||
'rose',
|
||||
'green',
|
||||
'lavender',
|
||||
'sand',
|
||||
'ocean',
|
||||
'sunset',
|
||||
'blue',
|
||||
]
|
||||
|
||||
export function isThemeId(value: string | null | undefined): value is ThemeId {
|
||||
return value !== undefined && value !== null && (THEME_IDS as readonly string[]).includes(value)
|
||||
}
|
||||
|
||||
/** Corrige les anciennes valeurs (ex. formulaire « slate ») vers un thème supporté. */
|
||||
export function normalizeThemeId(raw: string | null | undefined): ThemeId {
|
||||
if (!raw) return 'light'
|
||||
if (raw === 'slate') return 'light'
|
||||
if (isThemeId(raw)) return raw
|
||||
return 'light'
|
||||
}
|
||||
|
||||
/**
|
||||
* Applique le thème sur `<html>` : `class="dark"` et/ou `data-theme`.
|
||||
* - `light` → papier par défaut (`:root`), pas de `data-theme`
|
||||
* - `dark` → sombre global (`.dark`)
|
||||
* - `auto` → `.dark` si prefers-color-scheme: dark
|
||||
* - palettes nommées → `data-theme="<id>"` ; `midnight` force aussi `.dark` (variante sombre du thème)
|
||||
*/
|
||||
export function applyDocumentTheme(theme: string): void {
|
||||
if (typeof document === 'undefined') return
|
||||
|
||||
const t = normalizeThemeId(theme)
|
||||
const root = document.documentElement
|
||||
root.classList.remove('dark')
|
||||
root.removeAttribute('data-theme')
|
||||
|
||||
if (t === 'auto') {
|
||||
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
root.classList.add('dark')
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (t === 'dark') {
|
||||
root.classList.add('dark')
|
||||
return
|
||||
}
|
||||
|
||||
if (t === 'light') {
|
||||
return
|
||||
}
|
||||
|
||||
if ((NAMED_PALETTE_IDS as readonly string[]).includes(t)) {
|
||||
root.setAttribute('data-theme', t)
|
||||
if (t === 'midnight') {
|
||||
root.classList.add('dark')
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user