"""A switch component for toggling color_mode. To style components based on color mode, use style props with `color_mode_cond`: ``` pc.text( "Hover over me", _hover={ "background": pc.color_mode_cond( light="var(--chakra-colors-gray-200)", dark="var(--chakra-colors-gray-700)", ), }, ) ``` """ from __future__ import annotations from typing import Any from pynecone.components.component import Component from pynecone.components.layout.cond import Cond, cond from pynecone.components.media.icon import Icon from pynecone.style import color_mode, toggle_color_mode from pynecone.vars import BaseVar from .button import Button from .switch import Switch DEFAULT_COLOR_MODE = "light" DEFAULT_LIGHT_ICON = Icon.create(tag="sun") DEFAULT_DARK_ICON = Icon.create(tag="moon") def color_mode_cond(light: Any, dark: Any = None) -> BaseVar | Component: """Create a component or Prop based on color_mode. Args: light: The component or prop to render if color_mode is default dark: The component or prop to render if color_mode is non-default Returns: The conditional component or prop. """ return cond( color_mode == DEFAULT_COLOR_MODE, light, dark, ) class ColorModeIcon(Cond): """Displays the current color mode as an icon.""" @classmethod def create( cls, light_component: Component | None = None, dark_component: Component | None = None, ): """Create an icon component based on color_mode. Args: light_component: the component to display when color mode is default dark_component: the component to display when color mode is dark (non-default) Returns: The conditionally rendered component """ return color_mode_cond( light=light_component or DEFAULT_LIGHT_ICON, dark=dark_component or DEFAULT_DARK_ICON, ) class ColorModeSwitch(Switch): """Switch for toggling chakra light / dark mode via toggle_color_mode.""" @classmethod def create(cls, *children, **props): """Create a switch component bound to color_mode. Args: *children: The children of the component. **props: The props to pass to the component. Returns: The switch component. """ return Switch.create( *children, is_checked=color_mode != DEFAULT_COLOR_MODE, on_change=toggle_color_mode, **props, ) class ColorModeButton(Button): """Button for toggling chakra light / dark mode via toggle_color_mode.""" @classmethod def create(cls, *children, **props): """Create a button component that calls toggle_color_mode on click. Args: *children: The children of the component. **props: The props to pass to the component. Returns: The switch component. """ return Button.create( *children, on_click=toggle_color_mode, **props, )