Skip to content

Commit

Permalink
fix: color mode
Browse files Browse the repository at this point in the history
  • Loading branch information
Pagebakers committed Nov 25, 2023
1 parent 328b7c8 commit 0a14812
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import weakMemoize from '@emotion/weak-memoize'
import { FrameContextConsumer, useFrame } from 'react-frame-component'
import { SaasProvider } from '@saas-ui/react'
import theme from '../../../../styles/theme'
import { GlobalStyle, useColorMode } from '@chakra-ui/system'
import { ColorMode, GlobalStyle, useColorMode } from '@chakra-ui/system'

let memoizedCreateCacheWithContainer = weakMemoize((container: Node) => {
let newCache = createCache({ key: 'frame', container })
Expand All @@ -26,7 +26,7 @@ export const FrameProvider = (props) => {
<CacheProvider
value={memoizedCreateCacheWithContainer(document.head)}
>
<ColorModeScript />
<ColorModeScript colorMode={colorMode} />
<SaasProvider theme={theme}>{props.children}</SaasProvider>
</CacheProvider>
)
Expand All @@ -35,37 +35,100 @@ export const FrameProvider = (props) => {
)
}

const ColorModeScript = () => {
const { document, window } = useFrame()
const ColorModeScript = ({ colorMode }) => {
const { getSystemTheme, setClassName, setDataset } = useColorModeUtils()

const setColorMode = React.useCallback(
(value: ColorMode | 'system') => {
//
const resolved = value === 'system' ? getSystemTheme() : value

setClassName(resolved === 'dark')
setDataset(resolved)
},
[getSystemTheme, setClassName, setDataset]
)

React.useEffect(() => {
try {
if (!document || !window) return
var a = function (c) {
var v = '(prefers-color-scheme: dark)',
h = window.matchMedia(v).matches ? 'dark' : 'light',
r = c === 'system' ? h : c,
o = document.documentElement,
s = document.body,
l = 'chakra-ui-light',
d = 'chakra-ui-dark',
i = r === 'dark'
return (
s.classList.add(i ? d : l),
s.classList.remove(i ? l : d),
(o.style.colorScheme = r),
(o.dataset.theme = r),
r
)
},
n = a,
m = 'dark',
e = 'chakra-ui-color-mode',
t = localStorage.getItem(e)
t ? a(t) : localStorage.setItem(e, a(m))
} catch (a) {
console.log(a)
}
}, [])
setColorMode(colorMode)
}, [colorMode, setColorMode])

return null
}

const classNames = {
light: 'chakra-ui-light',
dark: 'chakra-ui-dark',
}

type UtilOptions = {
preventTransition?: boolean
document?: Document
}

function useColorModeUtils(options: UtilOptions = {}) {
const { preventTransition = true } = options

const frame = useFrame()

const doc = frame?.document ?? document
const win = frame?.window ?? window

const utils = {
setDataset: (value: ColorMode) => {
const cleanup = preventTransition ? utils.preventTransition() : undefined
doc.documentElement.dataset.theme = value
doc.documentElement.style.colorScheme = value
cleanup?.()
},
setClassName(dark: boolean) {
doc.body.classList.add(dark ? classNames.dark : classNames.light)
doc.body.classList.remove(dark ? classNames.light : classNames.dark)
},
query() {
return win.matchMedia('(prefers-color-scheme: dark)')
},
getSystemTheme(fallback?: ColorMode) {
const dark = utils.query().matches ?? fallback === 'dark'
return dark ? 'dark' : 'light'
},
addListener(fn: (cm: ColorMode) => unknown) {
const mql = utils.query()
const listener = (e: MediaQueryListEvent) => {
fn(e.matches ? 'dark' : 'light')
}

if (typeof mql.addListener === 'function') mql.addListener(listener)
else mql.addEventListener('change', listener)

return () => {
if (typeof mql.removeListener === 'function')
mql.removeListener(listener)
else mql.removeEventListener('change', listener)
}
},
preventTransition() {
const css = document.createElement('style')
css.appendChild(
document.createTextNode(
`*{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}`
)
)
doc.head.appendChild(css)

return () => {
// force a reflow
;(() => win.getComputedStyle(doc.body))()

// wait for next tick
requestAnimationFrame(() => {
requestAnimationFrame(() => {
doc.head.removeChild(css)
})
})
}
},
}

return utils
}
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ function ReactLiveBlock({
}, [frameRef, inline])

const frame = inline ? (
<LiveCodePreview fontSize="sm" sx={sx} />
<LiveCodePreview fontSize="sm" sx={sx} minH="200px" />
) : (
<Frame ref={(ref) => setFrameRef(ref)} width="100%" height="100%">
<FrameProvider>
Expand Down Expand Up @@ -200,11 +200,15 @@ function ReactLiveBlock({
width="4px"
bg="muted"
mx="2"
height="100px"
height="80px"
rounded="full"
_hover={{
bg: 'primary.500',
}}
_focus={{
outline: 'none',
bg: 'primary.500',
}}
/>
<Splitter.Panel id="b"></Splitter.Panel>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,15 @@ If you need more flexiblity it's possible to use these components directly.
The default authentication strategy is `magiclink`.

```jsx center=true height=550px
import { SaasUILogo } from '@saas-ui/assets'
import { Card, CardHeader, CardBody } from '@chakra-ui/react'
import { Auth } from '@saas-ui/auth'

export default function AuthPage() {
return (
<Card flex="1" maxW="400px">
<CardHeader>
<SaasUILogo width="100px" margin="0 auto" />
<CardHeader display="flex" alignItems="center" justifyContent="center">
<SaasUILogo width="100px" />
</CardHeader>
<CardBody>
<Auth />
Expand All @@ -71,14 +72,15 @@ export default function AuthPage() {
Using the `type` prop you can switch to password login.

```jsx center=true height=550px
import { SaasUILogo } from '@saas-ui/assets'
import { Card, CardHeader, CardBody } from '@chakra-ui/react'
import { Auth } from '@saas-ui/auth'

export default function AuthPage() {
return (
<Card flex="1" maxW="400px">
<CardHeader>
<SaasUILogo width="100px" margin="0 auto" />
<CardHeader display="flex" alignItems="center" justifyContent="center">
<SaasUILogo width="100px" />
</CardHeader>
<CardBody>
<Auth type="password" />
Expand All @@ -93,14 +95,15 @@ export default function AuthPage() {
Using the `providers` prop you can add social login buttons.

```jsx center=true height=550px
import { SaasUILogo } from '@saas-ui/assets'
import { Card, CardHeader, CardBody } from '@chakra-ui/react'
import { Auth } from '@saas-ui/auth'

export default function AuthPage() {
return (
<Card flex="1" maxW="400px">
<CardHeader>
<SaasUILogo width="100px" margin="0 auto" />
<CardHeader display="flex" alignItems="center" justifyContent="center">
<SaasUILogo width="100px" />
</CardHeader>
<CardBody>
<Auth
Expand All @@ -123,14 +126,15 @@ Using the `view` prop you can switch different supported view. The default view
Supported views: `login`, `signup`, `forgotPassword`, `updatePassword`, `otp`.

```jsx center=true height=550px
import { SaasUILogo } from '@saas-ui/assets'
import { Card, CardHeader, CardBody } from '@chakra-ui/react'
import { Auth } from '@saas-ui/auth'

export default function AuthPage() {
return (
<Card flex="1" maxW="400px">
<CardHeader>
<SaasUILogo width="100px" margin="0 auto" />
<CardHeader display="flex" alignItems="center" justifyContent="center">
<SaasUILogo width="100px" />
</CardHeader>
<CardBody>
<Auth
Expand All @@ -151,14 +155,15 @@ export default function AuthPage() {
### One time password

```jsx center=true height=550px
import { SaasUILogo } from '@saas-ui/assets'
import { Card, CardHeader, CardBody } from '@chakra-ui/react'
import { Auth } from '@saas-ui/auth'

export default function AuthPage() {
return (
<Card flex="1" maxW="400px">
<CardHeader>
<SaasUILogo width="100px" margin="0 auto" />
<CardHeader display="flex" alignItems="center" justifyContent="center">
<SaasUILogo width="100px" />
</CardHeader>
<CardBody>
<Auth view="otp" />
Expand All @@ -173,6 +178,7 @@ export default function AuthPage() {
Use the `redirectTo` prop to redirect the user after login.

```jsx center=true height=550px
import { SaasUILogo } from '@saas-ui/assets'
import { Card, CardHeader, CardBody } from '@chakra-ui/react'
import { useSnackbar } from '@saas-ui/react'
import { Auth } from '@saas-ui/auth'
Expand All @@ -187,8 +193,8 @@ const getAbsoluteUrl = (path: string) => {
export default function AuthPage() {
return (
<Card flex="1" maxW="400px">
<CardHeader>
<SaasUILogo width="100px" margin="0 auto" />
<CardHeader display="flex" alignItems="center" justifyContent="center">
<SaasUILogo width="100px" />
</CardHeader>
<CardBody>
<Auth
Expand All @@ -213,6 +219,7 @@ The `Auth` component accepts an `onError` prop that can be used to handle errors
You can use the `useSnackbar` hook to display a message.

```jsx center=true height=550px
import { SaasUILogo } from '@saas-ui/assets'
import { Card, CardHeader, CardBody } from '@chakra-ui/react'
import { useSnackbar } from '@saas-ui/react'
import { Auth } from '@saas-ui/auth'
Expand All @@ -227,8 +234,8 @@ const getAbsoluteUrl = (path: string) => {
export default function AuthPage() {
return (
<Card flex="1" maxW="400px">
<CardHeader>
<SaasUILogo width="100px" margin="0 auto" />
<CardHeader display="flex" alignItems="center" justifyContent="center">
<SaasUILogo width="100px" />
</CardHeader>
<CardBody>
<Auth
Expand All @@ -254,6 +261,7 @@ export default function AuthPage() {
### Custom links

```jsx center=true height=550px
import { SaasUILogo } from '@saas-ui/assets'
import { Card, CardHeader, CardBody } from '@chakra-ui/react'
import { useSnackbar } from '@saas-ui/react'
import { Auth } from '@saas-ui/auth'
Expand All @@ -268,8 +276,8 @@ const getAbsoluteUrl = (path: string) => {
export default function AuthPage() {
return (
<Card flex="1" maxW="400px">
<CardHeader>
<SaasUILogo width="100px" margin="0 auto" />
<CardHeader display="flex" alignItems="center" justifyContent="center">
<SaasUILogo width="100px" />
</CardHeader>
<CardBody>
<Auth
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import {

Press `S` to trigger the action.

```jsx inline=true
```jsx center=true inline=true
import { Box, Flex, Kbd } from '@chakra-ui/react'
import { useHotkeys, SearchInput } from '@saas-ui/react'

Expand Down Expand Up @@ -81,7 +81,7 @@ To target multiple platforms it's possible to pass an array of key combinations.

Press `⌘ Enter` or `Ctrl+Enter` to trigger the action.

```jsx inline=true
```jsx center=true inline=true
import { Box, Tooltip, Button } from '@chakra-ui/react'
import { useHotkeys } from '@saas-ui/react'

Expand All @@ -108,7 +108,7 @@ export default function Dialog() {
You can combine mutiple keys using the `+` sign or by adding a space.
Press `cmd shift D` or `Ctrl+Shift+D` to trigger the action.

```jsx inline=true
```jsx center=true inline=true
import { Box, Tooltip, Button } from '@chakra-ui/react'
import { useHotkeys } from '@saas-ui/react'

Expand All @@ -134,7 +134,7 @@ export default function Dialog() {

To prevent the default behavior of a key combination you can set the `preventDefault` option to `true`.

```jsx inline=true
```jsx center=true inline=true
import { Box, Tooltip, Button } from '@chakra-ui/react'
import { useHotkeys, SearchInput } from '@saas-ui/react'

Expand Down Expand Up @@ -165,7 +165,7 @@ Use the `then` keyword to create a sequence of keys.

Press `A` then `S` to trigger the action.

```jsx inline=true
```jsx center=true inline=true
import { Box, Tooltip, Button } from '@chakra-ui/react'
import { useHotkeys } from '@saas-ui/react'

Expand All @@ -192,7 +192,7 @@ export default function Dialog() {
Create a config object containing all the keyboard shortcuts in your app.
The keys in the config can be used as shortcuts with the included hook throughout your app.

```jsx inline=true live=false
```jsx center=true inline=true live=false
// app.tsx
import { HotkeysProvider, HotkeysListOptions } from '@saas-ui/react'

Expand All @@ -219,7 +219,7 @@ export default const App = () => {

`useHotkeysShortcut` returns the command value and can be used to show the key combinations to your users.

```jsx inline=true live=false
```jsx center=true inline=true live=false
import { Kbd } from '@chakra-ui/react'
import { useHotkeysShortcut } from '@saas-ui/react'

Expand All @@ -246,7 +246,7 @@ The `HotkeysList` component can be used to list all available hotkeys in your ap
Press `?` to open the modal.
```jsx inline=true
```jsx center=true inline=true
import {
Box,
Text,
Expand Down

1 comment on commit 0a14812

@vercel
Copy link

@vercel vercel bot commented on 0a14812 Nov 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.