From 6799a07a39623eb213b261ddf3b72900b47c62c5 Mon Sep 17 00:00:00 2001 From: v1rtl Date: Fri, 27 Sep 2024 16:05:14 +0300 Subject: [PATCH] feat: dark theme support in docs --- .../atoms/ThemeProvider/ThemeProvider.tsx | 9 ++-- docs/src/components/SideBar.tsx | 41 +++++++++-------- docs/src/pages/_app.tsx | 16 ++++++- docs/src/pages/_document.tsx | 45 +++++++++++++++++++ 4 files changed, 88 insertions(+), 23 deletions(-) create mode 100644 docs/src/pages/_document.tsx diff --git a/components/src/components/atoms/ThemeProvider/ThemeProvider.tsx b/components/src/components/atoms/ThemeProvider/ThemeProvider.tsx index fddd2cc0..62238d3b 100644 --- a/components/src/components/atoms/ThemeProvider/ThemeProvider.tsx +++ b/components/src/components/atoms/ThemeProvider/ThemeProvider.tsx @@ -11,9 +11,12 @@ const ThemeContext = React.createContext(null) type Props = { defaultMode?: Mode + onThemeChange?: (mode: Mode) => void } + export const ThemeProvider: React.FC> = ({ defaultMode = 'light', + onThemeChange, children, }) => { const [mode, setMode] = React.useState(defaultMode) @@ -21,11 +24,9 @@ export const ThemeProvider: React.FC> = ({ const value = React.useMemo(() => ({ mode, setMode }), [mode]) React.useEffect(() => { - const root = document.querySelector(':root') - if (root) { - root.setAttribute('data-theme', mode) - } + if (onThemeChange) onThemeChange(mode) }, [mode]) + return {children} } diff --git a/docs/src/components/SideBar.tsx b/docs/src/components/SideBar.tsx index ae82e134..84127b0a 100644 --- a/docs/src/components/SideBar.tsx +++ b/docs/src/components/SideBar.tsx @@ -12,7 +12,7 @@ import { useTheme, } from '@ensdomains/thorin' import { Link } from './Link' -import type { PropsWithChildren } from 'react' +import { type PropsWithChildren } from 'react' import { useRouter } from 'next/router' type Link = { name: string, route: string } @@ -63,6 +63,7 @@ const Divider = () => ( export const SideBar = ({ open, links }: { open: boolean, links: Links }) => { const router = useRouter() const { setMode, mode } = useTheme() + return ( { > - - {mode === 'light' ? 'Light Theme' : 'Dark Theme'} - - )} - inline - > - { - const newValue = e.target.checked ? 'light' : 'dark' - if (newValue !== mode) setMode(newValue) - }} - /> - + {typeof window !== 'undefined' && ( + + {mode === 'light' ? 'Light Theme' : 'Dark Theme'} + + )} + inline + > + { + const newValue = e.target.checked ? 'light' : 'dark' + if (newValue !== mode) { + setMode(newValue) + } + }} + /> + + )} }>Getting Started diff --git a/docs/src/pages/_app.tsx b/docs/src/pages/_app.tsx index 48db18b7..736873f5 100644 --- a/docs/src/pages/_app.tsx +++ b/docs/src/pages/_app.tsx @@ -2,6 +2,7 @@ import * as React from 'react' import type { AppProps } from 'next/app' import { MDXProvider } from '@mdx-js/react' +import type { Mode } from '@ensdomains/thorin' import { ThemeProvider } from '@ensdomains/thorin' import '@ensdomains/thorin/dist/style.css' import { MDX } from '~/components' @@ -10,6 +11,14 @@ import '~/styles/globalStyles.css' import '../styles/styles.css' import type { GetLayout, NextComponentType } from 'next' +declare global { + interface Window { + __theme: Mode + __setPreferredTheme: (theme: Mode) => void + __onThemeChange: (theme: Mode) => void + } +} + const App = ({ Component, pageProps }: AppProps) => { const getLayout = (Component as NextComponentType & { getLayout: GetLayout }).getLayout || getDocsLayout @@ -18,7 +27,12 @@ const App = ({ Component, pageProps }: AppProps) => { {/* */} {/* Prevent theme flash */} - {getLayout()} + window.__setPreferredTheme(mode)} + defaultMode={typeof window !== 'undefined' ? window.__theme : 'light'} + > + {getLayout()} + ) diff --git a/docs/src/pages/_document.tsx b/docs/src/pages/_document.tsx new file mode 100644 index 00000000..d594ab9c --- /dev/null +++ b/docs/src/pages/_document.tsx @@ -0,0 +1,45 @@ +/* eslint-disable @eslint-react/dom/no-dangerously-set-innerhtml */ +import { Html, Head, Main, NextScript } from 'next/document' + +export default function Document() { + return ( + + + +