Skip to content

Commit

Permalink
Merge pull request #160 from ensdomains/dark-theme-in-docs
Browse files Browse the repository at this point in the history
feat: dark theme support in docs
  • Loading branch information
talentlessguy authored Oct 2, 2024
2 parents a0eb920 + 6799a07 commit 2baca13
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,22 @@ const ThemeContext = React.createContext<ThemeContextValue | null>(null)

type Props = {
defaultMode?: Mode
onThemeChange?: (mode: Mode) => void
}

export const ThemeProvider: React.FC<React.PropsWithChildren<Props>> = ({
defaultMode = 'light',
onThemeChange,
children,
}) => {
const [mode, setMode] = React.useState<Mode>(defaultMode)

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 <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>
}

Expand Down
41 changes: 23 additions & 18 deletions docs/src/components/SideBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down Expand Up @@ -63,6 +63,7 @@ const Divider = () => (
export const SideBar = ({ open, links }: { open: boolean, links: Links }) => {
const router = useRouter()
const { setMode, mode } = useTheme()

return (
<Box
display="flex"
Expand All @@ -81,23 +82,27 @@ export const SideBar = ({ open, links }: { open: boolean, links: Links }) => {
>
<ScrollBox width="full" hideDividers>
<Box padding="4" display="flex" flexDirection="column" gap="4">
<Field
label={(
<Box height="6.5" display="flex" alignItems="center">
{mode === 'light' ? 'Light Theme' : 'Dark Theme'}
</Box>
)}
inline
>
<ThemeToggle
size="extraSmall"
checked={mode === 'light'}
onChange={(e) => {
const newValue = e.target.checked ? 'light' : 'dark'
if (newValue !== mode) setMode(newValue)
}}
/>
</Field>
{typeof window !== 'undefined' && (
<Field
label={(
<Box height="6.5" display="flex" alignItems="center">
{mode === 'light' ? 'Light Theme' : 'Dark Theme'}
</Box>
)}
inline
>
<ThemeToggle
size="extraSmall"
checked={mode === 'light'}
onChange={(e) => {
const newValue = e.target.checked ? 'light' : 'dark'
if (newValue !== mode) {
setMode(newValue)
}
}}
/>
</Field>
)}
<Divider />
<Box>
<Heading icon={<StarSVG />}>Getting Started</Heading>
Expand Down
16 changes: 15 additions & 1 deletion docs/src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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

Expand All @@ -18,7 +27,12 @@ const App = ({ Component, pageProps }: AppProps) => {
{/* <Head /> */}
{/* Prevent theme flash */}
<MDXProvider components={MDX}>
<ThemeProvider>{getLayout(<Component {...pageProps} />)}</ThemeProvider>
<ThemeProvider
onThemeChange={mode => window.__setPreferredTheme(mode)}
defaultMode={typeof window !== 'undefined' ? window.__theme : 'light'}
>
{getLayout(<Component {...pageProps} />)}
</ThemeProvider>
</MDXProvider>
</>
)
Expand Down
45 changes: 45 additions & 0 deletions docs/src/pages/_document.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Html>
<Head />
<body>
<script
dangerouslySetInnerHTML={{
__html: `(function () {
function setTheme(newTheme) {
document.documentElement.setAttribute('data-theme', newTheme);
window.__theme = newTheme;
window.__onThemeChange(newTheme);
}
window.__onThemeChange = function () {};
window.__setPreferredTheme = function (newTheme) {
setTheme(newTheme);
try {
localStorage.setItem("theme", JSON.stringify(window.__theme));
} catch (err) {}
};

const darkQuery = window.matchMedia("(prefers-color-scheme: dark)");
darkQuery.addListener(function (event) {
window.__setPreferredTheme(event.matches ? "dark" : "light");
});

let preferredTheme;
try {
preferredTheme = JSON.parse(localStorage.getItem("theme"));
} catch (err) {}

setTheme(preferredTheme || (darkQuery.matches ? "dark" : "light"));
})();
`,
}}
/>
<Main />
<NextScript />
</body>
</Html>
)
}

0 comments on commit 2baca13

Please sign in to comment.