33 lines
947 B
TypeScript
33 lines
947 B
TypeScript
|
|
import React from "react"
|
||
|
|
import { usePreference } from "@workspace/preferences"
|
||
|
|
|
||
|
|
import type { ThemeMode } from "./preferences"
|
||
|
|
import type { ThemeScheme } from "./theme"
|
||
|
|
|
||
|
|
const systemThemeQuery = "(prefers-color-scheme: dark)"
|
||
|
|
|
||
|
|
function subscribeToSystemTheme(listener: VoidFunction) {
|
||
|
|
const mediaQuery = window.matchMedia(systemThemeQuery)
|
||
|
|
mediaQuery.addEventListener("change", listener)
|
||
|
|
return () => mediaQuery.removeEventListener("change", listener)
|
||
|
|
}
|
||
|
|
|
||
|
|
function getSystemTheme(): ThemeScheme {
|
||
|
|
return window.matchMedia(systemThemeQuery).matches ? "dark" : "light"
|
||
|
|
}
|
||
|
|
|
||
|
|
function getServerSystemTheme(): ThemeScheme {
|
||
|
|
return "light"
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useResolvedTheme(): ThemeScheme {
|
||
|
|
const themeMode: ThemeMode = usePreference("theme-mode")[0]
|
||
|
|
const systemTheme = React.useSyncExternalStore(
|
||
|
|
subscribeToSystemTheme,
|
||
|
|
getSystemTheme,
|
||
|
|
getServerSystemTheme
|
||
|
|
)
|
||
|
|
|
||
|
|
return themeMode === "system" ? systemTheme : themeMode
|
||
|
|
}
|