Skip to content

Commit

Permalink
feat: theme toggle
Browse files Browse the repository at this point in the history
  • Loading branch information
jxom committed Nov 9, 2023
1 parent 474c134 commit e744320
Show file tree
Hide file tree
Showing 11 changed files with 97 additions and 34 deletions.
32 changes: 31 additions & 1 deletion src/app/components/DesktopTopNav.css.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import { style } from '@vanilla-extract/css'
import { primitiveColorVars, topNavVars, viewportVars } from '../styles/vars.css.js'
import {
borderRadiusVars,
primitiveColorVars,
spaceVars,
topNavVars,
viewportVars,
} from '../styles/vars.css.js'

export const root = style({
alignItems: 'center',
backgroundColor: `color-mix(in srgb, ${primitiveColorVars.background} 98%, transparent)`,
display: 'flex',
justifyContent: 'space-between',
padding: `0 ${topNavVars.horizontalPadding}`,
height: topNavVars.height,
'@media': {
[viewportVars['max-1080px']]: {
Expand All @@ -11,6 +21,22 @@ export const root = style({
},
})

export const button = style(
{
borderRadius: borderRadiusVars[4],
padding: spaceVars[8],
selectors: {
'&:hover': {
backgroundColor: primitiveColorVars.background3,
},
'&:hover:active': {
backgroundColor: primitiveColorVars.background2,
},
},
},
'button',
)

export const curtain = style(
{
background: `linear-gradient(${primitiveColorVars.background}, transparent 70%)`,
Expand All @@ -25,3 +51,7 @@ export const curtain = style(
},
'curtain',
)

export const item = style({ alignItems: 'center', display: 'flex', height: '100%' }, 'item')

export const section = style({ alignItems: 'center', display: 'flex', height: '100%' }, 'section')
24 changes: 21 additions & 3 deletions src/app/components/DesktopTopNav.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
import { curtain, root } from './DesktopTopNav.css.js'
import { useTheme } from '../hooks/useTheme.js'
import * as styles from './DesktopTopNav.css.js'
import { Icon } from './Icon.js'

DesktopTopNav.Curtain = Curtain

export function DesktopTopNav() {
return <div className={root} />
const { toggle, theme } = useTheme()
return (
<div className={styles.root}>
<div className={styles.section} />
<div className={styles.section}>
<div className={styles.item}>
<button className={styles.button} onClick={toggle} type="button">
{theme === 'dark' ? (
<Icon size="18px" label="Light" src="/.vocs/icons/sun.svg" />
) : (
<Icon size="18px" label="Dark" src="/.vocs/icons/moon.svg" />
)}
</button>
</div>
</div>
</div>
)
}

export function Curtain() {
return <div className={curtain} />
return <div className={styles.curtain} />
}
3 changes: 2 additions & 1 deletion src/app/components/PageLayout.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ export const gutterTop = style(
zIndex: zIndexVars.gutterTop,
'@media': {
[viewportVars['min-1080px']]: {
marginLeft: leftGutterWidthVar,
paddingLeft: leftGutterWidthVar,
paddingRight: `calc(${leftGutterWidthVar} - ${sidebarVars.width})`,
position: 'fixed',
top: 0,
},
Expand Down
8 changes: 3 additions & 5 deletions src/app/components/mdx/Code.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,13 @@ import { root as Pre } from './Pre.css.js'

export const root = style({
selectors: {
[`:not(${Pre})>&`]: {
borderRadius: borderRadiusVars['4'],
fontSize: fontSizeVars.code,
padding: `${spaceVars['3']} ${spaceVars['6']}`,
},
[`:not(${Pre})>&`]: {
backgroundColor: semanticColorVars.codeInlineBackground,
border: `1px solid ${semanticColorVars.codeInlineBorder}`,
borderRadius: borderRadiusVars['4'],
color: semanticColorVars.codeInlineText,
fontSize: fontSizeVars.code,
padding: `${spaceVars['3']} ${spaceVars['6']}`,
},
[`${Anchor}>&`]: {
color: semanticColorVars.link,
Expand Down
18 changes: 0 additions & 18 deletions src/app/hooks/useApplyCssTransition.ts

This file was deleted.

26 changes: 26 additions & 0 deletions src/app/hooks/useTheme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useEffect, useState } from 'react'

export function useTheme() {
const [theme, setTheme] = useState(() => {
if (typeof window === 'undefined') return 'dark'
if (localStorage.getItem('vocs.theme')) {
const storedTheme = localStorage.getItem('vocs.theme')
if (storedTheme) return storedTheme
}
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
})

useEffect(() => {
localStorage.setItem('vocs.theme', theme)

if (theme === 'dark') document.documentElement.classList.add('dark')
else document.documentElement.classList.remove('dark')
}, [theme])

return {
theme,
toggle() {
setTheme((theme) => (theme === 'light' ? 'dark' : 'light'))
},
}
}
4 changes: 4 additions & 0 deletions src/app/public/.vocs/icons/moon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/app/public/.vocs/icons/sun.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 0 additions & 2 deletions src/app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { ScrollRestoration } from 'react-router-dom'
import { Root as ConsumerRoot } from 'virtual:root'

import { FrontmatterHead } from './components/FrontmatterHead.js'
import { useApplyCssTransition } from './hooks/useApplyCssTransition.js'
import type { Module } from './types.js'

export function Root({
Expand All @@ -18,7 +17,6 @@ export function Root({
frontmatter: Module['frontmatter']
path: string
}) {
useApplyCssTransition()
return (
<>
{head && <Helmet>{head}</Helmet>}
Expand Down
8 changes: 5 additions & 3 deletions src/app/styles/vars.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -425,9 +425,9 @@ export const zIndexVars = createGlobalThemeContract(
createGlobalTheme(':root', zIndexVars, {
backdrop: '69420',
drawer: '69421',
gutterRight: '3',
gutterLeft: '3',
gutterTop: '2',
gutterRight: '2',
gutterLeft: '4',
gutterTop: '3',
popover: '69422',
surface: '1',
})
Expand Down Expand Up @@ -474,12 +474,14 @@ createGlobalTheme(':root', sidebarVars, {
export const topNavVars = createGlobalThemeContract(
{
height: 'height',
horizontalPadding: 'horizontalPadding',
curtainHeight: 'curtainHeight',
},
getVarName('topNav'),
)
createGlobalTheme(':root', topNavVars, {
height: '60px',
horizontalPadding: contentVars.horizontalPadding,
curtainHeight: '40px',
})

Expand Down
2 changes: 1 addition & 1 deletion src/app/utils/initializeTheme.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)')

const storedTheme = localStorage.getItem('vocs.theme')
const theme = storedTheme || darkModeMediaQuery.matches ? 'dark' : 'light'
const theme = storedTheme || (darkModeMediaQuery.matches ? 'dark' : 'light')

if (theme === 'dark') document.documentElement.classList.add('dark')

Expand Down

0 comments on commit e744320

Please sign in to comment.