diff --git a/pyproject.toml b/pyproject.toml index 3cc3708..1d59e17 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "reflex-chakra" -version = "0.6.0a1" +version = "0.6.0a4" description = "reflex using chakra components" authors = [ "Elijah Ahianyo " diff --git a/reflex_chakra/assets/chakra_color_mode_provider.js b/reflex_chakra/assets/chakra_color_mode_provider.js new file mode 100644 index 0000000..ad41d51 --- /dev/null +++ b/reflex_chakra/assets/chakra_color_mode_provider.js @@ -0,0 +1,36 @@ +import { useColorMode as chakraUseColorMode } from "@chakra-ui/react"; +import { useTheme } from "next-themes"; +import { useEffect, useState } from "react"; +import { ColorModeContext, defaultColorMode } from "/utils/context.js"; + +export default function ChakraColorModeProvider({ children }) { + const { theme, resolvedTheme, setTheme } = useTheme(); + const { colorMode, toggleColorMode } = chakraUseColorMode(); + const [resolvedColorMode, setResolvedColorMode] = useState(colorMode); + + useEffect(() => { + if (colorMode != resolvedTheme) { + toggleColorMode(); + } + setResolvedColorMode(resolvedTheme); + }, [theme, resolvedTheme]); + + const rawColorMode = colorMode; + const setColorMode = (mode) => { + const allowedModes = ["light", "dark", "system"]; + if (!allowedModes.includes(mode)) { + console.error( + `Invalid color mode "${mode}". Defaulting to "${defaultColorMode}".` + ); + mode = defaultColorMode; + } + setTheme(mode); + }; + return ( + + {children} + + ); +} diff --git a/reflex_chakra/components/base.py b/reflex_chakra/components/base.py index bd55a94..33c0dd3 100644 --- a/reflex_chakra/components/base.py +++ b/reflex_chakra/components/base.py @@ -2,7 +2,9 @@ from __future__ import annotations +import shutil from functools import lru_cache +from pathlib import Path from typing import List, Literal from reflex.components.component import Component @@ -10,6 +12,8 @@ from reflex.utils.imports import ImportDict, ImportVar from reflex.vars import Var +from reflex_chakra import constants + class ChakraComponent(Component): """A component that wraps a Chakra component.""" @@ -51,6 +55,24 @@ def _get_dependencies_imports(cls) -> ImportDict: ] } + @classmethod + def create(cls, *children, **props) -> Component: + # copy color mode provider file to client's asset dir if it doesnt exist. + client_asset_dir = Path.cwd() / constants.ASSETS_DIR_NAME + if not ( + client_color_mode_provider := ( + Path.cwd() + / constants.ASSETS_DIR_NAME + / constants.COLOR_MODE_PROVIDER_FILENAME + ) + ).exists(): + client_asset_dir.mkdir(exist_ok=True) + shutil.copy( + constants.ASSETS_DIR / constants.COLOR_MODE_PROVIDER_FILENAME, + client_color_mode_provider.parent, + ) + return super().create(*children, **props) + class ChakraProvider(ChakraComponent): """Top level Chakra provider must be included in any app using chakra components.""" @@ -95,7 +117,7 @@ def _get_app_wrap_components() -> dict[tuple[int, str], Component]: class ChakraColorModeProvider(Component): """Next-themes integration for chakra colorModeProvider.""" - library = "/components/reflex/chakra_color_mode_provider.js" + library = "/public/chakra_color_mode_provider.js" tag = "ChakraColorModeProvider" is_default = True diff --git a/reflex_chakra/constants.py b/reflex_chakra/constants.py new file mode 100644 index 0000000..a63de53 --- /dev/null +++ b/reflex_chakra/constants.py @@ -0,0 +1,6 @@ +from pathlib import Path + +ASSETS_DIR_NAME = "assets" +ASSETS_DIR = (Path(__file__).parent / ASSETS_DIR_NAME).resolve() + +COLOR_MODE_PROVIDER_FILENAME = "chakra_color_mode_provider.js"