colormodeswitch.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. """A switch component for toggling color_mode.
  2. To style components based on color mode, use style props with `color_mode_cond`:
  3. ```
  4. pc.text(
  5. "Hover over me",
  6. _hover={
  7. "background": pc.color_mode_cond(
  8. light="var(--chakra-colors-gray-200)",
  9. dark="var(--chakra-colors-gray-700)",
  10. ),
  11. },
  12. )
  13. ```
  14. """
  15. from __future__ import annotations
  16. from typing import Any
  17. from pynecone.components.component import Component
  18. from pynecone.components.layout.cond import Cond, cond
  19. from pynecone.components.media.icon import Icon
  20. from pynecone.style import color_mode, toggle_color_mode
  21. from pynecone.vars import BaseVar
  22. from .button import Button
  23. from .switch import Switch
  24. DEFAULT_COLOR_MODE = "light"
  25. DEFAULT_LIGHT_ICON = Icon.create(tag="sun")
  26. DEFAULT_DARK_ICON = Icon.create(tag="moon")
  27. def color_mode_cond(light: Any, dark: Any = None) -> BaseVar | Component:
  28. """Create a component or Prop based on color_mode.
  29. Args:
  30. light: The component or prop to render if color_mode is default
  31. dark: The component or prop to render if color_mode is non-default
  32. Returns:
  33. The conditional component or prop.
  34. """
  35. return cond(
  36. color_mode == DEFAULT_COLOR_MODE,
  37. light,
  38. dark,
  39. )
  40. class ColorModeIcon(Cond):
  41. """Displays the current color mode as an icon."""
  42. @classmethod
  43. def create(
  44. cls,
  45. light_component: Component | None = None,
  46. dark_component: Component | None = None,
  47. ):
  48. """Create an icon component based on color_mode.
  49. Args:
  50. light_component: the component to display when color mode is default
  51. dark_component: the component to display when color mode is dark (non-default)
  52. Returns:
  53. The conditionally rendered component
  54. """
  55. return color_mode_cond(
  56. light=light_component or DEFAULT_LIGHT_ICON,
  57. dark=dark_component or DEFAULT_DARK_ICON,
  58. )
  59. class ColorModeSwitch(Switch):
  60. """Switch for toggling chakra light / dark mode via toggle_color_mode."""
  61. @classmethod
  62. def create(cls, *children, **props):
  63. """Create a switch component bound to color_mode.
  64. Args:
  65. *children: The children of the component.
  66. **props: The props to pass to the component.
  67. Returns:
  68. The switch component.
  69. """
  70. return Switch.create(
  71. *children,
  72. is_checked=color_mode != DEFAULT_COLOR_MODE,
  73. on_change=toggle_color_mode,
  74. **props,
  75. )
  76. class ColorModeButton(Button):
  77. """Button for toggling chakra light / dark mode via toggle_color_mode."""
  78. @classmethod
  79. def create(cls, *children, **props):
  80. """Create a button component that calls toggle_color_mode on click.
  81. Args:
  82. *children: The children of the component.
  83. **props: The props to pass to the component.
  84. Returns:
  85. The switch component.
  86. """
  87. return Button.create(
  88. *children,
  89. on_click=toggle_color_mode,
  90. **props,
  91. )