37 lines
1.2 KiB
TypeScript
37 lines
1.2 KiB
TypeScript
import {
|
|
normalizeColorSchemePreference,
|
|
resolveColorScheme,
|
|
} from "../application/policies/color-scheme.ts";
|
|
import type { ApplicationApi } from "../application/ports/in/application-api.ts";
|
|
|
|
type ColorSchemeBrowser = Readonly<{
|
|
documentElement?: HTMLElement;
|
|
matchMedia?: (query: string) => Pick<MediaQueryList, "matches">;
|
|
}>;
|
|
|
|
/** Applies the persisted public preference before React paints. */
|
|
export function initializeColorScheme(
|
|
preferences: Pick<ApplicationApi["preferences"], "getColorScheme">,
|
|
browser: ColorSchemeBrowser = {},
|
|
) {
|
|
const documentElement = browser.documentElement ?? document.documentElement;
|
|
const matchMedia =
|
|
browser.matchMedia ??
|
|
(typeof window.matchMedia === "function"
|
|
? window.matchMedia.bind(window)
|
|
: () => ({ matches: false }));
|
|
const preference = normalizeColorSchemePreference(
|
|
preferences.getColorScheme(),
|
|
);
|
|
const resolved = resolveColorScheme(
|
|
preference,
|
|
matchMedia("(prefers-color-scheme: dark)").matches,
|
|
);
|
|
|
|
documentElement.dataset.theme = resolved;
|
|
documentElement.dataset.themePreference = preference;
|
|
documentElement.style.colorScheme = resolved;
|
|
|
|
return Object.freeze({ preference, resolved });
|
|
}
|