Adapt theme to app directory
This commit is contained in:
@@ -0,0 +1,88 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import * as React from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import createCache from '@emotion/cache'
|
||||||
|
import {useServerInsertedHTML} from 'next/navigation'
|
||||||
|
import {CacheProvider as DefaultCacheProvider} from '@emotion/react'
|
||||||
|
|
||||||
|
export default function NextAppDirEmotionCacheProvider(props) {
|
||||||
|
const {options, CacheProvider = DefaultCacheProvider, children} = props
|
||||||
|
|
||||||
|
const [registry] = React.useState(() => {
|
||||||
|
const cache = createCache(options)
|
||||||
|
cache.compat = true
|
||||||
|
const prevInsert = cache.insert
|
||||||
|
let inserted = []
|
||||||
|
cache.insert = (...args) => {
|
||||||
|
const [selector, serialized] = args
|
||||||
|
if (cache.inserted[serialized.name] === undefined) {
|
||||||
|
inserted.push({
|
||||||
|
name: serialized.name,
|
||||||
|
isGlobal: selector === '',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return prevInsert(...args)
|
||||||
|
}
|
||||||
|
|
||||||
|
const flush = () => {
|
||||||
|
const prevInserted = inserted
|
||||||
|
inserted = []
|
||||||
|
return prevInserted
|
||||||
|
}
|
||||||
|
|
||||||
|
return {cache, flush}
|
||||||
|
})
|
||||||
|
|
||||||
|
useServerInsertedHTML(() => {
|
||||||
|
const inserted = registry.flush()
|
||||||
|
if (inserted.length === 0) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
let styles = ''
|
||||||
|
let dataEmotionAttribute = registry.cache.key
|
||||||
|
|
||||||
|
const globals = []
|
||||||
|
|
||||||
|
for (const {name, isGlobal} of inserted) {
|
||||||
|
const style = registry.cache.inserted[name]
|
||||||
|
|
||||||
|
if (typeof style !== 'boolean') {
|
||||||
|
if (isGlobal) {
|
||||||
|
globals.push({name, style})
|
||||||
|
} else {
|
||||||
|
styles += style
|
||||||
|
dataEmotionAttribute += ` ${name}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{globals.map(({name, style}) => (
|
||||||
|
<style
|
||||||
|
key={name}
|
||||||
|
dangerouslySetInnerHTML={{__html: style}}
|
||||||
|
data-emotion={`${registry.cache.key}-global ${name}`}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
{styles !== '' && (
|
||||||
|
<style
|
||||||
|
dangerouslySetInnerHTML={{__html: styles}}
|
||||||
|
data-emotion={dataEmotionAttribute}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
return <CacheProvider value={registry.cache}>{children}</CacheProvider>
|
||||||
|
}
|
||||||
|
|
||||||
|
NextAppDirEmotionCacheProvider.propTypes = {
|
||||||
|
options: PropTypes.object.isRequired,
|
||||||
|
CacheProvider: PropTypes.func,
|
||||||
|
children: PropTypes.node.isRequired
|
||||||
|
}
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import {useState, useMemo, useEffect, createContext} from 'react'
|
||||||
|
import {createTheme, ThemeProvider} from '@mui/material/styles'
|
||||||
|
import CssBaseline from '@mui/material/CssBaseline'
|
||||||
|
|
||||||
|
import {grey, green, red, yellow} from '@mui/material/colors'
|
||||||
|
|
||||||
|
import '@fontsource/roboto/300.css'
|
||||||
|
import '@fontsource/roboto/400.css'
|
||||||
|
import '@fontsource/roboto/500.css'
|
||||||
|
import '@fontsource/roboto/700.css'
|
||||||
|
import '../styles/nprogress.css'
|
||||||
|
|
||||||
|
import ChanjeTem from '../components/chanje-tem'
|
||||||
|
import NextAppDirEmotionCacheProvider from './emotion-cache-provider'
|
||||||
|
|
||||||
|
export const ColorModeContext = createContext({toggleColorMode: () => {}})
|
||||||
|
|
||||||
|
const getDesignTokens = mode => ({
|
||||||
|
palette: {
|
||||||
|
mode,
|
||||||
|
...(mode === 'light'
|
||||||
|
? {
|
||||||
|
primary: green,
|
||||||
|
secondary: red,
|
||||||
|
divider: green[200],
|
||||||
|
info: {
|
||||||
|
main: grey[900]
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
primary: grey[900],
|
||||||
|
secondary: grey[800],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
primary: {
|
||||||
|
main: yellow[500],
|
||||||
|
contrastText: '#000'
|
||||||
|
},
|
||||||
|
secondary: red,
|
||||||
|
info: {
|
||||||
|
main: '#fff'
|
||||||
|
},
|
||||||
|
divider: green[700],
|
||||||
|
background: {
|
||||||
|
default: '#082211',
|
||||||
|
paper: '#082211',
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
primary: '#fff',
|
||||||
|
secondary: grey[100],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export default function ThemeRegistry(props) {
|
||||||
|
const [mode, setMode] = useState('light')
|
||||||
|
const colorMode = useMemo(
|
||||||
|
() => ({
|
||||||
|
toggleColorMode: () => {
|
||||||
|
setMode(prevMode =>
|
||||||
|
prevMode === 'light' ? 'dark' : 'light',
|
||||||
|
)
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
const theme = useMemo(() => createTheme(getDesignTokens(mode)), [mode])
|
||||||
|
|
||||||
|
const {children} = props
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const vyeLokalMod = localStorage.getItem('oki-dark')
|
||||||
|
const lokalMod = localStorage.getItem('oki-tem')
|
||||||
|
if (lokalMod === 'dark' || (vyeLokalMod && vyeLokalMod === 'true')) {
|
||||||
|
setMode('dark')
|
||||||
|
} else {
|
||||||
|
setMode('light')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lokalMod && vyeLokalMod) {
|
||||||
|
localStorage.removeItem('oki-dark')
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NextAppDirEmotionCacheProvider options={{key: 'mui'}}>
|
||||||
|
<ColorModeContext.Provider value={colorMode}>
|
||||||
|
<ThemeProvider theme={theme}>
|
||||||
|
<CssBaseline enableColorScheme />
|
||||||
|
<ChanjeTem />
|
||||||
|
{children}
|
||||||
|
</ThemeProvider>
|
||||||
|
</ColorModeContext.Provider>
|
||||||
|
</NextAppDirEmotionCacheProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
ThemeRegistry.propTypes = {
|
||||||
|
children: PropTypes.node.isRequired
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user