Skip to content
This repository was archived by the owner on Sep 20, 2024. It is now read-only.

Commit f53daf9

Browse files
committed
feat(nuxt): ssr color mode
1 parent aabb225 commit f53daf9

File tree

9 files changed

+82
-12
lines changed

9 files changed

+82
-12
lines changed

examples/nuxt-app/app.vue

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,25 @@
11
<template>
2-
<div>
3-
<NuxtWelcome />
4-
</div>
2+
<chakra.div
3+
display="flex"
4+
min-h="600px"
5+
justify-content="center"
6+
align-items="center"
7+
>
8+
<chakra.button
9+
@click="toggleColorMode"
10+
px="4"
11+
py="3"
12+
bg="red"
13+
color="white"
14+
font-weight="bold"
15+
>
16+
Click me to toggle. ({{ colorMode }})
17+
</chakra.button>
18+
</chakra.div>
519
</template>
20+
21+
<script lang="ts" setup>
22+
import { chakra, useColorMode } from "@chakra-ui/vue-next"
23+
24+
const { colorMode, toggleColorMode } = useColorMode()
25+
</script>

examples/nuxt-app/nuxt.config.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
import { extendTheme } from "@chakra-ui/vue-next"
2+
13
export default defineNuxtConfig({
24
modules: ["@chakra-ui/nuxt-next"],
5+
chakra: {
6+
extendTheme: extendTheme({
7+
colors: {
8+
$brand: "#f5f",
9+
},
10+
}),
11+
},
312
})

packages/c-color-mode/src/color-mode-provider.tsx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,22 @@ export function setupColorModeContext(
9696

9797
const managerValue = colorModeManager.get()
9898

99-
if (managerValue) {
99+
// If this is SSR, we check to see if the cookie has been specified.
100+
// Otherwise we should bail.
101+
if (
102+
// Is SSR
103+
typeof document !== "undefined" &&
104+
document.documentElement.dataset.chakraUiSsr === "true"
105+
// !initialColorMode
106+
) {
107+
// Bail and
108+
// Forcefully hydrate client to match ccolor mode
109+
const ssrColorMode = document.documentElement.dataset.theme
110+
if (ssrColorMode) {
111+
console.debug("chakra-ui-ssr color mode is", ssrColorMode)
112+
setColorMode(ssrColorMode as ColorMode)
113+
}
114+
} else if (managerValue) {
100115
setColorMode(managerValue)
101116
} else if (initialColorMode === "system") {
102117
setColorMode("system")
@@ -108,7 +123,7 @@ export function setupColorModeContext(
108123

109124
function setColorMode(value: ColorMode | "system") {
110125
const { setClassName, setDataset, getSystemTheme } = utils.value
111-
const resolved = value === "system" ? getSystemTheme() : value
126+
const resolved = value === "system" ? getSystemTheme()! : value
112127
colorMode.value = resolved
113128

114129
setClassName(resolved === "dark")

packages/c-color-mode/src/color-mode-script.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
export type ColorModeScriptProps = {
22
type?: "localStorage" | "cookie"
33
initialColorMode?: "light" | "dark" | "system"
4-
storageKey?: string
4+
storageKey?: ColorModeConstants
55
nonce?: string
66
}
77

8+
export enum ColorModeConstants {
9+
CookieStorageKey = "chakra-ui-color-mode",
10+
LocalStorageKey = "chakra-ui-color-mode",
11+
BaseStorageKey = "chakra-ui-color-mode",
12+
}
13+
814
const VALID_VALUES = new Set(["dark", "light", "system"])
915

1016
/**
@@ -20,7 +26,7 @@ export function getScriptSrc(props: ColorModeScriptProps = {}) {
2026
const {
2127
initialColorMode = "light",
2228
type = "localStorage",
23-
storageKey: key = "chakra-ui-color-mode",
29+
storageKey: key = ColorModeConstants.LocalStorageKey,
2430
} = props
2531

2632
// runtime safe-guard against invalid color mode values
@@ -41,6 +47,8 @@ export function getScriptSrc(props: ColorModeScriptProps = {}) {
4147
export function mountColorModeScript(props: ColorModeScriptProps = {}) {
4248
const { nonce } = props
4349

50+
if (typeof document === "undefined") return
51+
4452
const script = document.createElement("script")
4553
script.id = "chakra-script"
4654
script.nonce = nonce

packages/c-color-mode/src/color-mode.utils.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,29 @@ export function getColorModeUtils(options: UtilOptions = {}) {
1818

1919
const utils = {
2020
setDataset: (value: ColorMode) => {
21+
if (!globalThis?.document) return
2122
const cleanup = preventTransition ? utils.preventTransition() : undefined
2223
document.documentElement.dataset.theme = value
2324
document.documentElement.style.colorScheme = value
2425
cleanup?.()
2526
},
2627
setClassName(dark: boolean) {
28+
if (!globalThis?.document) return
2729
document.body.classList.add(dark ? classNames.dark : classNames.light)
2830
document.body.classList.remove(dark ? classNames.light : classNames.dark)
2931
},
3032
query() {
33+
if (!globalThis?.document) return
3134
return window.matchMedia("(prefers-color-scheme: dark)")
3235
},
3336
getSystemTheme(fallback?: ColorMode) {
34-
const dark = utils.query().matches ?? fallback === "dark"
37+
if (!globalThis?.document) return
38+
const dark = utils.query()!.matches ?? fallback === "dark"
3539
return dark ? "dark" : "light"
3640
},
3741
addListener(fn: (cm: ColorMode) => unknown) {
3842
const mql = utils.query()
43+
if (!globalThis?.document || !mql) return
3944
const listener = (e: MediaQueryListEvent) => {
4045
fn(e.matches ? "dark" : "light")
4146
}

packages/c-color-mode/src/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from "./color-mode-provider"
2+
export * from "./color-mode-script"
23
export * from "./storage-manager"

packages/c-color-mode/src/storage-manager.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { __DEV__ } from "@chakra-ui/utils"
2+
import { ColorModeConstants } from "./color-mode-script"
23
import { ColorMode } from "./color-mode.utils"
34

4-
export const STORAGE_KEY = "chakra-ui-color-mode"
5+
export const STORAGE_KEY = ColorModeConstants.BaseStorageKey
56

67
const hasSupport = () => typeof Storage !== "undefined"
7-
export const storageKey = "chakra-ui-color-mode"
88

99
type MaybeColorMode = ColorMode | undefined
1010

@@ -60,6 +60,7 @@ export function createCookieStorageManager(
6060
return parseCookie(document.cookie, key) || init
6161
},
6262
set(value) {
63+
if (typeof document === "undefined") return
6364
document.cookie = `${key}=${value}; max-age=31536000; path=/`
6465
},
6566
}

packages/core/README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,11 @@
1-
## Project Stats
2-
![Alt](https://repobeats.axiom.co/api/embed/40b60a8e21b08d97af5849ea7a8c7d7f46956824.svg "Repobeats analytics image")
1+
# @chakra-ui/vue-next
2+
3+
Chakra UI on Vue 3
4+
5+
## Installation
6+
7+
```sh
8+
yarn add @chakra-ui/vue-next
9+
# or
10+
npm i @chakra-ui/vue-next
11+
```

pnpm-lock.yaml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)