Skip to content

Commit ec430c3

Browse files
committed
feat(provider): create providers
1 parent c73db13 commit ec430c3

2 files changed

Lines changed: 82 additions & 0 deletions

File tree

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
"use client"
2+
3+
import type { IconButtonProps } from "@chakra-ui/react"
4+
import { ClientOnly, IconButton, Skeleton } from "@chakra-ui/react"
5+
import { ThemeProvider, useTheme } from "next-themes"
6+
import type { ThemeProviderProps } from "next-themes"
7+
import { forwardRef } from "react"
8+
import { LuMoon, LuSun } from "react-icons/lu"
9+
10+
export interface ColorModeProviderProps extends ThemeProviderProps {}
11+
12+
export function ColorModeProvider(props: ColorModeProviderProps) {
13+
return (
14+
<ThemeProvider attribute="class" disableTransitionOnChange {...props} />
15+
)
16+
}
17+
18+
export function useColorMode() {
19+
const { resolvedTheme, setTheme } = useTheme()
20+
const toggleColorMode = () => {
21+
setTheme(resolvedTheme === "light" ? "dark" : "light")
22+
}
23+
return {
24+
colorMode: resolvedTheme,
25+
setColorMode: setTheme,
26+
toggleColorMode,
27+
}
28+
}
29+
30+
export function useColorModeValue<T>(light: T, dark: T) {
31+
const { colorMode } = useColorMode()
32+
return colorMode === "light" ? light : dark
33+
}
34+
35+
export function ColorModeIcon() {
36+
const { colorMode } = useColorMode()
37+
return colorMode === "light" ? <LuSun /> : <LuMoon />
38+
}
39+
40+
interface ColorModeButtonProps extends Omit<IconButtonProps, "aria-label"> {}
41+
42+
export const ColorModeButton = forwardRef<
43+
HTMLButtonElement,
44+
ColorModeButtonProps
45+
>(function ColorModeButton(props, ref) {
46+
const { toggleColorMode } = useColorMode()
47+
return (
48+
<ClientOnly fallback={<Skeleton boxSize="8" />}>
49+
<IconButton
50+
onClick={toggleColorMode}
51+
variant="ghost"
52+
aria-label="Toggle color mode"
53+
size="sm"
54+
ref={ref}
55+
{...props}
56+
css={{
57+
_icon: {
58+
width: "5",
59+
height: "5",
60+
},
61+
}}
62+
>
63+
<ColorModeIcon />
64+
</IconButton>
65+
</ClientOnly>
66+
)
67+
})
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
"use client"
2+
3+
import { ChakraProvider, defaultSystem } from "@chakra-ui/react"
4+
import {
5+
ColorModeProvider,
6+
type ColorModeProviderProps,
7+
} from "./color-mode"
8+
9+
export function Provider(props: ColorModeProviderProps) {
10+
return (
11+
<ChakraProvider value={defaultSystem}>
12+
<ColorModeProvider {...props} />
13+
</ChakraProvider>
14+
)
15+
}

0 commit comments

Comments
 (0)