2026-10-03 11:29:31 +02:00
|
|
|
// Applies PageSettings to the page. It picks the daisyUI theme from Styles/theme.css and sets the hue and chroma
|
|
|
|
|
// variables that theme derives every colour from. It loads in <head> right after css/app.css and applies the
|
|
|
|
|
// settings saved in localStorage before the first paint. Once Blazor runs, CascadingState calls neoTheme.apply
|
2026-10-03 12:43:07 +02:00
|
|
|
// through AppStatusService.ApplyTheme whenever the settings change, and the theme controls ask neoTheme.isDark
|
|
|
|
|
// (AppStatusService.IsDarkTheme) which variant they are editing.
|
2026-10-03 11:29:31 +02:00
|
|
|
(() => {
|
|
|
|
|
const root = document.documentElement
|
|
|
|
|
let current = null
|
|
|
|
|
|
|
|
|
|
// The same precedence the old CascadingState <style> block had:
|
|
|
|
|
// - System theming leaves data-theme off, so daisyUI's prefersdark rule decides.
|
|
|
|
|
// - Otherwise dark grey, then light grey, then dark mode, then light.
|
|
|
|
|
// - Either grey flag drops the chroma to 0.
|
|
|
|
|
const apply = (settings) => {
|
|
|
|
|
current = settings || {}
|
|
|
|
|
const system = current.preferSystemTheming ?? true
|
|
|
|
|
const darkGray = current.themeIsDarkGray ?? false
|
|
|
|
|
const lightGray = current.themeIsLightGray ?? true
|
|
|
|
|
const dark = current.themeIsDarkMode ?? false
|
|
|
|
|
|
|
|
|
|
const theme = system ? null : darkGray ? "neo-dark" : lightGray ? "neo-light" : dark ? "neo-dark" : "neo-light"
|
|
|
|
|
if (theme)
|
|
|
|
|
root.setAttribute("data-theme", theme)
|
|
|
|
|
else
|
|
|
|
|
root.removeAttribute("data-theme")
|
|
|
|
|
|
|
|
|
|
root.style.setProperty("--neo-hue-light", current.lightThemeIndexColour ?? 25)
|
|
|
|
|
root.style.setProperty("--neo-hue-dark", current.darkThemeIndexColour ?? 215)
|
|
|
|
|
root.style.setProperty("--neo-chroma", darkGray || lightGray ? 0 : 1)
|
|
|
|
|
|
|
|
|
|
// daisyUI paints the root with base-100, so its computed background is the resolved theme colour.
|
|
|
|
|
let meta = document.querySelector('meta[name="theme-color"]')
|
|
|
|
|
if (!meta) {
|
|
|
|
|
meta = document.createElement("meta")
|
|
|
|
|
meta.name = "theme-color"
|
|
|
|
|
document.head.appendChild(meta)
|
|
|
|
|
}
|
|
|
|
|
meta.content = getComputedStyle(root).backgroundColor
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const cache = JSON.parse(localStorage.getItem("PublicCacheData") || "null")
|
|
|
|
|
apply(cache && cache.pageSettings)
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error("theme.js", e)
|
|
|
|
|
apply(null)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// With system theming the OS can switch between light and dark at any time.
|
|
|
|
|
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => apply(current))
|
|
|
|
|
|
2026-10-03 12:43:07 +02:00
|
|
|
// Whether the dark variant is showing, chosen or taken from the OS.
|
|
|
|
|
const isDark = () => root.getAttribute("data-theme") === "neo-dark" ||
|
|
|
|
|
(!root.hasAttribute("data-theme") && window.matchMedia("(prefers-color-scheme: dark)").matches)
|
|
|
|
|
|
|
|
|
|
window.neoTheme = { apply, isDark }
|
2026-10-03 11:29:31 +02:00
|
|
|
})()
|