From ecfcc38db0686d90ef60cde88e0c704925121bc8 Mon Sep 17 00:00:00 2001 From: Siddharth Kshetrapal Date: Wed, 16 Feb 2022 18:18:45 +0100 Subject: [PATCH 1/6] wip commit --- src/ThemeProvider.tsx | 53 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/src/ThemeProvider.tsx b/src/ThemeProvider.tsx index 1c314ff4052..fe74774b128 100644 --- a/src/ThemeProvider.tsx +++ b/src/ThemeProvider.tsx @@ -47,21 +47,65 @@ export const ThemeProvider: React.FC = ({children, ...props} // Initialize state const theme = props.theme ?? fallbackTheme ?? defaultTheme + + const resolvedColorModePassthrough = React.useRef( + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore of course this doesn't exist on window it's a custom variable + typeof window !== 'undefined' ? window.__PRIMER_RESOLVED_SERVER_COLOR_MODE : undefined + ) + const [colorMode, setColorMode] = React.useState(props.colorMode ?? fallbackColorMode ?? defaultColorMode) const [dayScheme, setDayScheme] = React.useState(props.dayScheme ?? fallbackDayScheme ?? defaultDayScheme) const [nightScheme, setNightScheme] = React.useState(props.nightScheme ?? fallbackNightScheme ?? defaultNightScheme) const systemColorMode = useSystemColorMode() - const resolvedColorMode = resolveColorMode(colorMode, systemColorMode) + const resolvedColorMode = resolvedColorModePassthrough.current || resolveColorMode(colorMode, systemColorMode) const colorScheme = chooseColorScheme(resolvedColorMode, dayScheme, nightScheme) const {resolvedTheme, resolvedColorScheme} = React.useMemo( () => applyColorScheme(theme, colorScheme), [theme, colorScheme] ) + // eslint-disable-next-line no-console + console.log({ + colorMode, + resolvedColorMode: resolveColorMode(colorMode, systemColorMode), + resolvedColorModePassthrough: resolvedColorModePassthrough.current + }) + + // this effect will only run on client + React.useEffect( + function updateColorModeAfterServerPassthorugh() { + const resolvedColorModeOnClient = resolveColorMode(colorMode, systemColorMode) + + if (resolvedColorModePassthrough.current) { + // eslint-disable-next-line no-console + console.log('effect running', { + resolvedColorModeOnClient, + resolvedColorModePassthrough: resolvedColorModePassthrough.current + }) + + // if the resolved color mode passed on from the server is not the resolved color mode on client, change it! + if (resolvedColorModePassthrough.current !== resolvedColorModeOnClient) { + window.setTimeout(() => { + // eslint-disable-next-line no-console + console.log('fixing color mode') + // override colorMode to whatever is resolved on the client to get a re-render + setColorMode(resolvedColorModeOnClient) + // immediately after that, set the colorMode to what the user passed to respond to system color mode changes + setColorMode(colorMode) + }) + } + + resolvedColorModePassthrough.current = null + } + }, + [colorMode, systemColorMode] + ) // Update state if props change + // Update state if props change React.useEffect(() => { setColorMode(props.colorMode ?? fallbackColorMode ?? defaultColorMode) - }, [props.colorMode, fallbackColorMode]) + }, [props.colorMode, resolvedColorMode, fallbackColorMode]) React.useEffect(() => { setDayScheme(props.dayScheme ?? fallbackDayScheme ?? defaultDayScheme) @@ -86,7 +130,10 @@ export const ThemeProvider: React.FC = ({children, ...props} setNightScheme }} > - {children} + + {children} +