From 41fffe677bd065f97bc5fdf2b7654d4e50178d9d Mon Sep 17 00:00:00 2001 From: advo-kat <119153319+advo-kat@users.noreply.github.com> Date: Tue, 31 Jan 2023 07:39:32 +1100 Subject: [PATCH] Add support for toggling color mode ('night/day mode') (#382) Co-authored-by: g0ee <0@g0.ee> Co-authored-by: g0ee --- pynecone/__init__.py | 1 + pynecone/compiler/compiler.py | 1 + pynecone/compiler/templates.py | 3 +++ pynecone/compiler/utils.py | 5 ++++- pynecone/components/base/__init__.py | 2 +- pynecone/components/base/document.py | 13 +++++++++++++ pynecone/components/component.py | 5 +++++ pynecone/style.py | 9 +++++++++ 8 files changed, 37 insertions(+), 2 deletions(-) diff --git a/pynecone/__init__.py b/pynecone/__init__.py index a96abf7cf..ce37ad760 100644 --- a/pynecone/__init__.py +++ b/pynecone/__init__.py @@ -15,3 +15,4 @@ from .middleware import Middleware from .model import Model, session from .state import ComputedVar as var from .state import State +from .style import toggle_color_mode diff --git a/pynecone/compiler/compiler.py b/pynecone/compiler/compiler.py index 7f3a4d9e1..b5788ad24 100644 --- a/pynecone/compiler/compiler.py +++ b/pynecone/compiler/compiler.py @@ -17,6 +17,7 @@ DEFAULT_IMPORTS: ImportDict = { "next/router": {"useRouter"}, f"/{constants.STATE_PATH}": {"connect", "updateState", "E"}, "": {"focus-visible/dist/focus-visible"}, + "@chakra-ui/react": {"useColorMode"}, } diff --git a/pynecone/compiler/templates.py b/pynecone/compiler/templates.py index 879af88c5..3977235d0 100644 --- a/pynecone/compiler/templates.py +++ b/pynecone/compiler/templates.py @@ -197,3 +197,6 @@ ROUTER = f"const {constants.ROUTER} = useRouter()" # Sockets. SOCKET = "const socket = useRef(null)" + +# Color toggle +COLORTOGGLE = "const { colorMode, toggleColorMode } = useColorMode()" diff --git a/pynecone/compiler/utils.py b/pynecone/compiler/utils.py index 6868b13d6..bce94d58f 100644 --- a/pynecone/compiler/utils.py +++ b/pynecone/compiler/utils.py @@ -17,6 +17,7 @@ from pynecone.components.base import ( Main, Script, Title, + ColorModeScript, ) from pynecone.components.component import Component, CustomComponent, ImportDict from pynecone.state import State @@ -120,7 +121,8 @@ def compile_state(state: Type[State]) -> str: router = templates.ROUTER socket = templates.SOCKET ready = templates.READY - return templates.join([synced_state, result, router, socket, ready]) + color_toggle = templates.COLORTOGGLE + return templates.join([synced_state, result, router, socket, ready, color_toggle]) def compile_events(state: Type[State]) -> str: @@ -209,6 +211,7 @@ def create_document_root(stylesheets: List[str]) -> Component: return Html.create( DocumentHead.create(*sheets), Body.create( + ColorModeScript.create(), Main.create(), Script.create(), ), diff --git a/pynecone/components/base/__init__.py b/pynecone/components/base/__init__.py index c34499a48..e4fedf206 100644 --- a/pynecone/components/base/__init__.py +++ b/pynecone/components/base/__init__.py @@ -1,7 +1,7 @@ """Base components.""" from .body import Body -from .document import DocumentHead, Html, Main, Script +from .document import DocumentHead, Html, Main, Script, ColorModeScript from .head import Head from .link import Link from .meta import Description, Image, Title diff --git a/pynecone/components/base/document.py b/pynecone/components/base/document.py index f7b57d9f6..28a846b3a 100644 --- a/pynecone/components/base/document.py +++ b/pynecone/components/base/document.py @@ -31,3 +31,16 @@ class Script(NextDocumentLib): """The document main scripts.""" tag = "NextScript" + + +class ChakraUiReactLib(Component): + """Chakra UI React document components.""" + + library = "@chakra-ui/react" + + +class ColorModeScript(ChakraUiReactLib): + """Chakra color mode script.""" + + tag = "ColorModeScript" + initialColorMode = "light" diff --git a/pynecone/components/component.py b/pynecone/components/component.py index c9b4e3456..16399cee3 100644 --- a/pynecone/components/component.py +++ b/pynecone/components/component.py @@ -162,6 +162,11 @@ class Component(Base, ABC): Raises: ValueError: If the value is not a valid event chain. """ + # If it's a JS var, return it. + if isinstance(value, Var): + if value.is_local is False and value.is_string is False: + return value + # If it's an event chain var, return it. if isinstance(value, Var): if value.type_ is not EventChain: diff --git a/pynecone/style.py b/pynecone/style.py index ce7d77c7e..379a106b1 100644 --- a/pynecone/style.py +++ b/pynecone/style.py @@ -6,6 +6,15 @@ from pynecone import utils from pynecone.var import Var +def toggle_color_mode(): + """Toggle the color mode. + + Returns: + Toggle color mode JS event as a variable + """ + return Var.create(value="toggleColorMode", is_local=False, is_string=False) + + def convert(style_dict): """Format a style dictionary.