Files
Momento/memento-note/components/theme-initializer.tsx
Antigravity a77f3ffb6e
Some checks failed
CI / Lint, Unit Tests & Build (push) Failing after 1m15s
CI / Deploy production (on server) (push) Has been skipped
fix: batch priorités — thème, scroll, wizard, agents, slides, charts, packs
Anti-flash dark (color-scheme + applyDocumentTheme), scroll pages publiques,
prompts wizard/slides moins génériques, cron agents rattrapage nextRun null,
slides carnet via notebookId, graphiques à 2 crédits + hint, audit dashboard,
packs Stripe marqués non configurés sans price ID.
2026-07-16 20:48:55 +00:00

80 lines
2.8 KiB
TypeScript

'use client'
import { useLayoutEffect } from 'react'
import { applyDocumentTheme, normalizeThemeId, persistThemePreference } from '@/lib/apply-document-theme'
interface ThemeInitializerProps {
theme?: string
fontSize?: string
fontFamily?: string
accentColor?: string
}
export function ThemeInitializer({ theme, fontSize, fontFamily, accentColor }: ThemeInitializerProps) {
// useLayoutEffect : avant le paint (useEffect = trop tard = flash clair)
useLayoutEffect(() => {
const root = document.documentElement
const applyFontSize = (s?: string) => {
const size = s || 'medium'
const fontSizeMap: Record<string, string> = {
small: '14px',
medium: '16px',
large: '18px',
'extra-large': '20px',
}
const fontSizeFactorMap: Record<string, number> = {
small: 0.95,
medium: 1.0,
large: 1.1,
'extra-large': 1.25,
}
root.style.setProperty('--user-font-size', fontSizeMap[size] || '16px')
root.style.setProperty('--user-font-size-factor', (fontSizeFactorMap[size] || 1).toString())
}
// Préférence locale prioritaire (jamais écrasée par un rendu serveur « light »)
const localTheme = localStorage.getItem('theme-preference')
const effectiveTheme = normalizeThemeId(localTheme || theme || 'light')
// Appliquer le thème AVANT paint (cookie + class dark atomique)
applyDocumentTheme(effectiveTheme)
persistThemePreference(effectiveTheme)
// color-scheme navigateur (inputs, scrollbars) — évite flash chrome clair
try {
const dark =
effectiveTheme === 'dark' ||
effectiveTheme === 'midnight' ||
(effectiveTheme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches)
root.style.colorScheme = dark ? 'dark' : 'light'
} catch {
/* ignore */
}
applyFontSize(fontSize)
const localFontFamily = localStorage.getItem('font-family')
const effectiveFontFamily = localFontFamily || fontFamily || 'inter'
root.classList.remove('font-system', 'font-playfair', 'font-jetbrains')
if (effectiveFontFamily === 'system') root.classList.add('font-system')
if (effectiveFontFamily === 'playfair') root.classList.add('font-playfair')
if (effectiveFontFamily === 'jetbrains') root.classList.add('font-jetbrains')
if (!localFontFamily && fontFamily) {
localStorage.setItem('font-family', fontFamily)
}
const localAccent = localStorage.getItem('accent-color')
const effectiveAccent = localAccent || accentColor || '#A47148'
root.style.setProperty('--color-brand-accent', effectiveAccent)
if (!localAccent && accentColor) {
localStorage.setItem('accent-color', accentColor)
}
}, [theme, fontSize, fontFamily, accentColor])
return null
}