From 87848cc69753057738a3bcca6ec5c25896001245 Mon Sep 17 00:00:00 2001 From: Jake Jarvis Date: Wed, 9 Mar 2022 14:07:06 -0500 Subject: [PATCH] just some refactoring --- components/ContactForm/ContactForm.tsx | 3 +- components/Footer/Footer.tsx | 6 +- components/MenuItem/MenuItem.tsx | 6 +- hooks/use-theme.tsx | 257 ++++++++--------- lib/{ => helpers}/build-feed.ts | 2 +- lib/helpers/mdx-components.ts | 24 ++ lib/{ => helpers}/parse-notes.ts | 6 +- lib/mdx-components.ts | 24 -- lib/styles/fonts/comic-neue.ts | 29 -- lib/styles/fonts/inter.ts | 49 ---- lib/styles/fonts/roboto-mono.ts | 84 ------ lib/styles/helpers/fonts/comic-neue.ts | 27 ++ lib/styles/helpers/fonts/inter.ts | 49 ++++ lib/styles/helpers/fonts/roboto-mono.ts | 84 ++++++ lib/styles/helpers/typography.ts | 9 + lib/styles/stitches.config.ts | 25 +- package.json | 10 +- pages/_document.tsx | 22 +- pages/api/hits.ts | 2 +- pages/feed.atom.ts | 2 +- pages/feed.xml.ts | 2 +- pages/notes/[slug].tsx | 4 +- pages/notes/index.tsx | 2 +- pages/sitemap.xml.ts | 2 +- types/note.d.ts | 2 +- yarn.lock | 359 ++++++++++++------------ 26 files changed, 533 insertions(+), 558 deletions(-) rename lib/{ => helpers}/build-feed.ts (98%) create mode 100644 lib/helpers/mdx-components.ts rename lib/{ => helpers}/parse-notes.ts (96%) delete mode 100644 lib/mdx-components.ts delete mode 100644 lib/styles/fonts/comic-neue.ts delete mode 100644 lib/styles/fonts/inter.ts delete mode 100644 lib/styles/fonts/roboto-mono.ts create mode 100644 lib/styles/helpers/fonts/comic-neue.ts create mode 100644 lib/styles/helpers/fonts/inter.ts create mode 100644 lib/styles/helpers/fonts/roboto-mono.ts create mode 100644 lib/styles/helpers/typography.ts diff --git a/components/ContactForm/ContactForm.tsx b/components/ContactForm/ContactForm.tsx index 68798ca8..55939d03 100644 --- a/components/ContactForm/ContactForm.tsx +++ b/components/ContactForm/ContactForm.tsx @@ -12,11 +12,10 @@ const InputStyles = css({ width: "100%", padding: "0.8em", margin: "0.6em 0", - border: "2px solid", + border: "2px solid $light", borderRadius: "$rounded", color: "$text", backgroundColor: "$superDuperLight", - borderColor: "$light", // light-dark theme switch fading transition: "background 0.25s ease", diff --git a/components/Footer/Footer.tsx b/components/Footer/Footer.tsx index 6ba4ccc7..5ecb7300 100644 --- a/components/Footer/Footer.tsx +++ b/components/Footer/Footer.tsx @@ -49,11 +49,7 @@ const NextjsLink = styled(Link, { const ViewSourceLink = styled(Link, { paddingBottom: "2px", - borderBottom: "1px solid", - borderColor: "$light", - - // light-dark theme switch fading - transition: "border 0.25s ease", + borderBottom: "1px solid $light", "&:hover": { borderColor: "$kindaLight", diff --git a/components/MenuItem/MenuItem.tsx b/components/MenuItem/MenuItem.tsx index 7fc9b845..99ea1193 100644 --- a/components/MenuItem/MenuItem.tsx +++ b/components/MenuItem/MenuItem.tsx @@ -12,14 +12,12 @@ const Link = styled("a", { current: { true: { marginBottom: "-0.2em", - borderBottom: "0.2em solid", - borderColor: "$linkUnderline", + borderBottom: "0.2em solid $linkUnderline", }, false: { "&:hover": { marginBottom: "-0.2em", - borderBottom: "0.2em solid", - borderColor: "$kindaLight", + borderBottom: "0.2em solid $kindaLight", }, }, }, diff --git a/hooks/use-theme.tsx b/hooks/use-theme.tsx index 6ea561c1..be0f52eb 100644 --- a/hooks/use-theme.tsx +++ b/hooks/use-theme.tsx @@ -1,28 +1,23 @@ -// forked & modified from pacocoursey/next-themes as of: +// forked & modified from pacocoursey/next-themes as of v0.0.15: // https://github.com/pacocoursey/next-themes/tree/b5c2bad50de2d61ad7b52a9c5cdc801a78507d7a import { createContext, useCallback, useContext, useEffect, useState, useRef, memo } from "react"; import NextHead from "next/head"; import type { PropsWithChildren } from "react"; -interface UseThemeProps { - /** List of all available theme names */ - themes: string[]; - /** Active theme name */ - theme?: string; - /** If the active theme is "system", this returns whether the system preference resolved to "dark" or "light". Otherwise, identical to `theme` */ - resolvedTheme?: string; - /** Forced theme name for the current page */ - forcedTheme?: string; - /** Update the theme */ - setTheme: (theme: string) => void; +// https://web.dev/prefers-color-scheme/#the-prefers-color-scheme-media-query +const MEDIA = "(prefers-color-scheme: dark)"; + +// default to a simple light or dark binary option +const colorSchemes = ["light", "dark"]; + +interface AttributeValuesMap { + [themeName: string]: string; } export interface ThemeProviderProps { /** List of all available theme names */ themes?: string[]; - /** Forced theme name for the current page */ - forcedTheme?: string; /** Whether to indicate to browsers which color scheme is used (dark or light) for built-in UI like inputs and buttons */ enableColorScheme?: boolean; /** Key used to store theme setting in localStorage */ @@ -32,9 +27,44 @@ export interface ThemeProviderProps { /** HTML attribute modified based on the active theme. Accepts `class` and `data-*` (meaning any data attribute, `data-mode`, `data-color`, etc.) */ attribute?: string | "class"; /** Mapping of theme name to HTML attribute value. Object where key is the theme name and value is the attribute value */ - value?: ValueObject; + value?: AttributeValuesMap; } +export interface UseThemeProps { + /** List of all available theme names */ + themes: string[]; + /** Active theme name */ + theme?: string; + /** If the active theme is "system", this returns whether the system preference resolved to "dark" or "light". Otherwise, identical to `theme` */ + resolvedTheme?: string; + /** Update the theme */ + setTheme: (theme: string) => void; +} + +// get the current theme *after* being set by this script +const getTheme = (key: string, fallback?: string) => { + if (typeof window === "undefined") return undefined; + + let theme; + try { + theme = localStorage.getItem(key) || undefined; + } catch (e) {} // eslint-disable-line no-empty + + return theme || fallback; +}; + +// get the user's prefered theme as set via their OS/browser settings +const getSystemTheme = (e?: MediaQueryList) => { + if (!e) { + e = window.matchMedia(MEDIA); + } + + const isDark = e.matches; + const systemTheme = isDark ? "dark" : "light"; + return systemTheme; +}; + +// useTheme() function to get current theme state from pages/components/etc. const ThemeContext = createContext({ // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars setTheme: (_) => {}, @@ -42,15 +72,71 @@ const ThemeContext = createContext({ }); export const useTheme = () => useContext(ThemeContext); -const colorSchemes = ["light", "dark"]; -const MEDIA = "(prefers-color-scheme: dark)"; +// the script tag injected manually into `` by provider below +const ThemeScript = memo(function ThemeScript({ + storageKey, + attribute, + defaultTheme, + value, + attrs, +}: { + storageKey: string; + attribute?: string; + defaultTheme: string; + value?: AttributeValuesMap; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + attrs: any; +}) { + const setDocumentVar = (() => { + if (attribute === "class") { + const removeClasses = `d.remove(${attrs.map((t: string) => `"${t}"`).join(",")})`; -interface ValueObject { - [themeName: string]: string; -} + // `d` is the class list of the `` tag + return `var d=document.documentElement.classList;${removeClasses};`; + } else { + // `d` is the entire document, used to set custom attribute of the `` tag (probably `data-*`) + return `var d=document.documentElement;`; + } + })(); + const updateDOM = (name: string, literal?: boolean) => { + name = value?.[name] || name; + const val = literal ? name : `"${name}"`; + + // mirrors above logic from setDocumentVar() + if (attribute === "class") { + return `d.add(${val})`; + } else { + return `d.setAttribute("${attribute}", ${val})`; + } + }; + + // is the default theme still `system`? (it should be...) + const defaultSystem = defaultTheme === "system"; + + // 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 `` attributes even more. + return ( + +