diff --git a/src/ThemeProvider.tsx b/src/ThemeProvider.tsx new file mode 100644 index 0000000..189cc1c --- /dev/null +++ b/src/ThemeProvider.tsx @@ -0,0 +1,44 @@ +import { state, useStateObservable } from "@react-rxjs/core" +import { + createContext, + FC, + PropsWithChildren, + useContext, + useLayoutEffect, +} from "react" +import { fromEvent, map } from "rxjs" + +const getCurrentMedia = (): "light" | "dark" => + window.matchMedia + ? window.matchMedia("(prefers-color-scheme: dark)") + ? "dark" + : "light" + : "dark" + +const defaultTheme = getCurrentMedia() + +const ThemeContext = createContext<"light" | "dark">(defaultTheme) + +export const useTheme = () => useContext(ThemeContext) + +const theme$ = state( + fromEvent( + window.matchMedia("(prefers-color-scheme: dark)"), + "change", + ).pipe(map((evt) => (evt.matches ? "dark" : "light"))), + defaultTheme, +) + +export const ThemeProvider: FC = ({ children }) => { + const theme = useStateObservable(theme$) + + useLayoutEffect(() => { + if (theme === "dark") { + document.body.classList.add("dark") + } else { + document.body.classList.remove("dark") + } + }, [theme]) + + return {children} +} diff --git a/src/codec-components/ViewCodec/CStruct.tsx b/src/codec-components/ViewCodec/CStruct.tsx index 293988b..d659fe6 100644 --- a/src/codec-components/ViewCodec/CStruct.tsx +++ b/src/codec-components/ViewCodec/CStruct.tsx @@ -110,7 +110,7 @@ export const CStruct: ViewStruct = ({