diff --git a/components/Layout/Layout.tsx b/components/Layout/Layout.tsx index 2868003e..8fc811b2 100644 --- a/components/Layout/Layout.tsx +++ b/components/Layout/Layout.tsx @@ -1,9 +1,7 @@ -import Head from "next/head"; import Header from "../Header"; import Footer from "../Footer"; import { SkipToContentLink, SkipToContentTarget } from "../SkipToContent"; -import useTheme from "../../hooks/useTheme"; -import { styled, theme, darkTheme } from "../../lib/styles/stitches.config"; +import { styled, theme } from "../../lib/styles/stitches.config"; import type { ComponentPropsWithoutRef } from "react"; const Flex = styled("div", { @@ -39,18 +37,8 @@ export type LayoutProps = ComponentPropsWithoutRef & { }; const Layout = ({ container = true, children, ...rest }: LayoutProps) => { - const { activeTheme } = useTheme(); - return ( <> - - - - diff --git a/components/ThemeScript/ThemeScript.tsx b/components/ThemeScript/ThemeScript.tsx deleted file mode 100644 index eb5cd7b6..00000000 --- a/components/ThemeScript/ThemeScript.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { memo } from "react"; -import { minify } from "uglify-js"; -import type { MinifyOutput } from "uglify-js"; - -import { restoreTheme as clientFn } from "./client.js"; - -export type ThemeScriptProps = { - themeClassNames: { - [themeName: string]: string; - }; - themeStorageKey: string; -}; - -// eslint-disable-next-line react/display-name -const ThemeScript = memo(({ themeClassNames, themeStorageKey }) => { - const minified = (() => { - // since the client function will end up being injected as a static hard-coded string, we need to determine all of - // the dynamic values within it *before* generating the final script. - const source = String(clientFn) - .replaceAll("__MEDIA_QUERY__", "(prefers-color-scheme: dark)") - .replaceAll("__STORAGE_KEY__", themeStorageKey) - .replaceAll("__CLASS_NAMES__", Object.values(themeClassNames).join('","')); - - // turn the raw function into an iife - const unminified = `(${source})()`; - - // minify the final code. this approach is a bit janky but is ONLY used at build time, so there's essentially no - // risk of breaking the entire site and/or accidentally bundling uglify-js clientside (bad). - let minified: MinifyOutput | undefined; - try { - minified = minify(unminified, { - toplevel: true, - compress: { - negate_iife: false, - }, - parse: { - bare_returns: true, - }, - }); - } catch (error) { - // fail somewhat silenty by returning the unminified version - console.warn("Failed to minify inline theme script:", error); - return unminified; - } - - // same as the catch block above, but in some cases (not really sure when), minify() doesn't throw an actual error - // and instead just returns undefined and an "error" string, so we need to check for both. - if (!minified || minified.error) { - console.warn("Failed to minify inline theme script. uglify-js output:", minified.error); - return unminified; - } - - return minified.code; - })(); - - // the script tag injected manually into `` in _document.tsx to prevent FARTing: - // https://css-tricks.com/flash-of-inaccurate-color-theme-fart/ - // even though it's the proper method, using next/script with `strategy="beforeInteractive"` still causes flash of - // white on load. injecting a normal script tag lets us prioritize setting the `` class even more urgently. - // TODO: using next/script *might* be possible after https://github.com/vercel/next.js/pull/36364 is merged. - return ( - + + {children} + + ); }; // debugging help pls diff --git a/lib/styles/stitches.config.ts b/lib/styles/stitches.config.ts index 89897ea7..9b691124 100644 --- a/lib/styles/stitches.config.ts +++ b/lib/styles/stitches.config.ts @@ -153,11 +153,8 @@ export const globalStyles = globalCss( } ); -// theme classnames are generated dynamically by stitches, so have ThemeProvider pull them from there -export const themeClassNames = { +// theme classnames are generated dynamically by stitches, so have ThemeProvider pull them from here +export const classNames = { light: theme.className, dark: darkTheme.className, }; - -// local storage key -export const themeStorageKey = "theme"; diff --git a/package.json b/package.json index 95d366d2..327ef8cb 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "devDependencies": { "@jakejarvis/eslint-config": "^3.1.0", "@types/comma-number": "^2.1.2", - "@types/node": "^20.11.17", + "@types/node": "^20.11.18", "@types/novnc__novnc": "^1.3.4", "@types/prop-types": "^15.7.11", "@types/react": "^18.2.55", diff --git a/pages/_app.tsx b/pages/_app.tsx index c839453e..464293ad 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -6,7 +6,7 @@ import { ThemeProvider } from "../contexts/ThemeContext"; import Layout from "../components/Layout"; import * as config from "../lib/config"; import { defaultSeo, socialProfileJsonLd } from "../lib/config/seo"; -import { globalStyles, themeClassNames } from "../lib/styles/stitches.config"; +import { globalStyles, classNames } from "../lib/styles/stitches.config"; import type { ReactElement, ReactNode } from "react"; import type { NextPage } from "next"; import type { AppProps as NextAppProps } from "next/app"; @@ -72,7 +72,7 @@ const App = ({ Component, pageProps }: AppProps) => { /> - {getLayout()} + {getLayout()} ); }; diff --git a/pages/_document.tsx b/pages/_document.tsx index d49331ad..9b4651a2 100644 --- a/pages/_document.tsx +++ b/pages/_document.tsx @@ -1,16 +1,12 @@ import { Html, Head, Main, NextScript } from "next/document"; -import ThemeScript from "../components/ThemeScript"; -import { getCssText, themeClassNames, themeStorageKey } from "../lib/styles/stitches.config"; +import { getCssText, theme } from "../lib/styles/stitches.config"; import * as config from "../lib/config"; // https://nextjs.org/docs/advanced-features/custom-document const Document = () => { return ( - + - {/* inject this script (generated at build-time) to prioritize setting/restoring the user's theme. */} - -