All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 5s
Removed unused components: - brainstorm-canvas, brainstorm-create-dialog, invite-dialog, manual-idea-dialog - note-inline-editor, profile-page-header, quota-paywall, label-management-dialog Removed dead lib files: - api-auth.ts, color-harmony-recommendation.ts, label-storage.ts, modern-color-options.ts - hooks/use-card-size-mode.ts Removed dead API routes: - ai/test-chat, ai/test-embeddings, ai/test-tags, admin/randomize-labels Removed unused npm packages: - cmdk, novel, tippy.js, react-force-graph-2d Cleaned dead CSS from globals.css: - acrylic-*, win11-shadow-*, muuri-grid/item, ai-glass, ai-tab-indicator, ai-send-btn, sidebar-view-toggle, memento-sidebar-depth Removed 29 orphan scripts and 3 root orphan files Cleaned dead exports from 8 lib files: - NOTE_TYPE_CONFIG, getPublishableKey, PROVIDER_DEFAULTS, useNotes/useNote/invalidateNote, etc.
84 lines
2.0 KiB
TypeScript
84 lines
2.0 KiB
TypeScript
/**
|
|
* 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.
|
|
*/
|
|
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')
|
|
}
|
|
}
|
|
}
|