瀏覽代碼

add_style api (#3202)

Thomas Brandého 1 年之前
父節點
當前提交
57476966f3
共有 32 個文件被更改,包括 883 次插入616 次删除
  1. 1 3
      reflex/app.py
  2. 9 0
      reflex/compiler/compiler.py
  3. 97 20
      reflex/components/component.py
  4. 0 9
      reflex/components/core/cond.py
  5. 1 16
      reflex/components/core/foreach.py
  6. 0 15
      reflex/components/core/match.py
  7. 5 2
      reflex/components/datadisplay/code.py
  8. 1 0
      reflex/components/datadisplay/code.pyi
  9. 2 2
      reflex/components/markdown/markdown.py
  10. 0 1
      reflex/components/markdown/markdown.pyi
  11. 225 404
      reflex/components/radix/primitives/accordion.py
  12. 367 26
      reflex/components/radix/primitives/accordion.pyi
  13. 30 26
      reflex/components/radix/primitives/form.py
  14. 6 1
      reflex/components/radix/primitives/form.pyi
  15. 17 9
      reflex/components/radix/primitives/progress.py
  16. 2 0
      reflex/components/radix/primitives/progress.pyi
  17. 30 18
      reflex/components/radix/primitives/slider.py
  18. 4 0
      reflex/components/radix/primitives/slider.pyi
  19. 13 11
      reflex/components/radix/themes/components/icon_button.py
  20. 2 0
      reflex/components/radix/themes/components/icon_button.pyi
  21. 8 3
      reflex/components/radix/themes/layout/center.py
  22. 2 1
      reflex/components/radix/themes/layout/center.pyi
  23. 8 3
      reflex/components/radix/themes/layout/list.py
  24. 3 19
      reflex/components/radix/themes/layout/list.pyi
  25. 8 3
      reflex/components/radix/themes/layout/spacer.py
  26. 2 1
      reflex/components/radix/themes/layout/spacer.pyi
  27. 2 0
      reflex/constants/colors.py
  28. 24 6
      reflex/experimental/layout.py
  29. 6 1
      reflex/style.py
  30. 1 10
      tests/components/core/test_foreach.py
  31. 3 4
      tests/components/lucide/test_icon.py
  32. 4 2
      tests/components/radix/test_icon_button.py

+ 1 - 3
reflex/app.py

@@ -833,9 +833,7 @@ class App(Base):
 
 
         for _route, component in self.pages.items():
         for _route, component in self.pages.items():
             # Merge the component style with the app style.
             # Merge the component style with the app style.
-            component._add_style_recursive(self.style)
-
-            component.apply_theme(self.theme)
+            component._add_style_recursive(self.style, self.theme)
 
 
             # Add component._get_all_imports() to all_imports.
             # Add component._get_all_imports() to all_imports.
             all_imports.update(component._get_all_imports())
             all_imports.update(component._get_all_imports())

+ 9 - 0
reflex/compiler/compiler.py

@@ -263,9 +263,18 @@ def _compile_stateful_components(
             # Reset this flag to render the actual component.
             # Reset this flag to render the actual component.
             component.rendered_as_shared = False
             component.rendered_as_shared = False
 
 
+            # Include dynamic imports in the shared component.
+            if dynamic_imports := component._get_all_dynamic_imports():
+                rendered_components.update(
+                    {dynamic_import: None for dynamic_import in dynamic_imports}
+                )
+
+            # Include custom code in the shared component.
             rendered_components.update(
             rendered_components.update(
                 {code: None for code in component._get_all_custom_code()},
                 {code: None for code in component._get_all_custom_code()},
             )
             )
+
+            # Include all imports in the shared component.
             all_import_dicts.append(component._get_all_imports())
             all_import_dicts.append(component._get_all_imports())
 
 
             # Indicate that this component now imports from the shared file.
             # Indicate that this component now imports from the shared file.

+ 97 - 20
reflex/components/component.py

@@ -608,6 +608,8 @@ class Component(BaseComponent, ABC):
     def _apply_theme(self, theme: Optional[Component]):
     def _apply_theme(self, theme: Optional[Component]):
         """Apply the theme to this component.
         """Apply the theme to this component.
 
 
+        Deprecated. Use add_style instead.
+
         Args:
         Args:
             theme: The theme to apply.
             theme: The theme to apply.
         """
         """
@@ -779,44 +781,119 @@ class Component(BaseComponent, ABC):
 
 
         return cls(children=children, **props)
         return cls(children=children, **props)
 
 
-    def _add_style(self, style: dict):
-        """Add additional style to the component.
+    def add_style(self) -> Style | None:
+        """Add style to the component.
 
 
-        Args:
-            style: A style dict to apply.
+        Downstream components can override this method to return a style dict
+        that will be applied to the component.
+
+        Returns:
+            The style to add.
+        """
+        return None
+
+    def _add_style(self) -> Style:
+        """Call add_style for all bases in the MRO.
+
+        Downstream components should NOT override. Use add_style instead.
+
+        Returns:
+            The style to add.
         """
         """
-        self.style.update(style)
+        styles = []
+        vars = []
+
+        # Walk the MRO to call all `add_style` methods.
+        for base in self._iter_parent_classes_with_method("add_style"):
+            s = base.add_style(self)  # type: ignore
+            if s is not None:
+                styles.append(s)
+                vars.append(s._var_data)
+
+        _style = Style()
+        for s in reversed(styles):
+            _style.update(s)
+
+        _style._var_data = VarData.merge(*vars)
+        return _style
+
+    def _get_component_style(self, styles: ComponentStyle) -> Style | None:
+        """Get the style to the component from `App.style`.
 
 
-    def _add_style_recursive(self, style: ComponentStyle) -> Component:
+        Args:
+            styles: The style to apply.
+
+        Returns:
+            The style of the component.
+        """
+        component_style = None
+        if type(self) in styles:
+            component_style = Style(styles[type(self)])
+        if self.create in styles:
+            component_style = Style(styles[self.create])
+        return component_style
+
+    def _add_style_recursive(
+        self, style: ComponentStyle, theme: Optional[Component] = None
+    ) -> Component:
         """Add additional style to the component and its children.
         """Add additional style to the component and its children.
 
 
+        Apply order is as follows (with the latest overriding the earliest):
+        1. Default style from `_add_style`/`add_style`.
+        2. User-defined style from `App.style`.
+        3. User-defined style from `Component.style`.
+        4. style dict and css props passed to the component instance.
+
         Args:
         Args:
             style: A dict from component to styling.
             style: A dict from component to styling.
+            theme: The theme to apply. (for retro-compatibility with deprecated _apply_theme API)
+
+        Raises:
+            UserWarning: If `_add_style` has been overridden.
 
 
         Returns:
         Returns:
             The component with the additional style.
             The component with the additional style.
         """
         """
-        component_style = None
-        if type(self) in style:
-            # Extract the style for this component.
-            component_style = Style(style[type(self)])
-        if self.create in style:
-            component_style = Style(style[self.create])
-        if component_style is not None:
-            # Only add style props that are not overridden.
-            component_style = {
-                k: v for k, v in component_style.items() if k not in self.style
-            }
+        # 1. Default style from `_add_style`/`add_style`.
+        if type(self)._add_style != Component._add_style:
+            raise UserWarning(
+                "Do not override _add_style directly. Use add_style instead."
+            )
+        new_style = self._add_style()
+        style_vars = [new_style._var_data]
+
+        # 2. User-defined style from `App.style`.
+        component_style = self._get_component_style(style)
+        if component_style:
+            new_style.update(component_style)
+            style_vars.append(component_style._var_data)
+
+        # 3. User-defined style from `Component.style`.
+        # Apply theme for retro-compatibility with deprecated _apply_theme API
+        if type(self)._apply_theme != Component._apply_theme:
+            console.deprecate(
+                f"{self.__class__.__name__}._apply_theme",
+                reason="use add_style instead",
+                deprecation_version="0.5.0",
+                removal_version="0.6.0",
+            )
+            self._apply_theme(theme)
+
+        # 4. style dict and css props passed to the component instance.
+        new_style.update(self.style)
+        style_vars.append(self.style._var_data)
+
+        new_style._var_data = VarData.merge(*style_vars)
 
 
-            # Add the style to the component.
-            self._add_style(component_style)
+        # Assign the new style
+        self.style = new_style
 
 
         # Recursively add style to the children.
         # Recursively add style to the children.
         for child in self.children:
         for child in self.children:
             # Skip BaseComponent and StatefulComponent children.
             # Skip BaseComponent and StatefulComponent children.
             if not isinstance(child, Component):
             if not isinstance(child, Component):
                 continue
                 continue
-            child._add_style_recursive(style)
+            child._add_style_recursive(style, theme)
         return self
         return self
 
 
     def _get_style(self) -> dict:
     def _get_style(self) -> dict:

+ 0 - 9
reflex/components/core/cond.py

@@ -102,15 +102,6 @@ class Cond(MemoizationLeaf):
             _IS_TRUE_IMPORT,
             _IS_TRUE_IMPORT,
         )
         )
 
 
-    def _apply_theme(self, theme: Component):
-        """Apply the theme to this component.
-
-        Args:
-            theme: The theme to apply.
-        """
-        self.comp1.apply_theme(theme)  # type: ignore
-        self.comp2.apply_theme(theme)  # type: ignore
-
 
 
 @overload
 @overload
 def cond(condition: Any, c1: Component, c2: Any) -> Component:
 def cond(condition: Any, c1: Component, c2: Any) -> Component:

+ 1 - 16
reflex/components/core/foreach.py

@@ -3,7 +3,7 @@ from __future__ import annotations
 
 
 import inspect
 import inspect
 from hashlib import md5
 from hashlib import md5
-from typing import Any, Callable, Iterable, Optional
+from typing import Any, Callable, Iterable
 
 
 from reflex.components.base.fragment import Fragment
 from reflex.components.base.fragment import Fragment
 from reflex.components.component import Component
 from reflex.components.component import Component
@@ -23,17 +23,6 @@ class Foreach(Component):
     # A function from the render args to the component.
     # A function from the render args to the component.
     render_fn: Callable = Fragment.create
     render_fn: Callable = Fragment.create
 
 
-    # The theme if set.
-    theme: Optional[Component] = None
-
-    def _apply_theme(self, theme: Component):
-        """Apply the theme to this component.
-
-        Args:
-            theme: The theme to apply.
-        """
-        self.theme = theme
-
     @classmethod
     @classmethod
     def create(cls, iterable: Var[Iterable], render_fn: Callable, **props) -> Foreach:
     def create(cls, iterable: Var[Iterable], render_fn: Callable, **props) -> Foreach:
         """Create a foreach component.
         """Create a foreach component.
@@ -97,10 +86,6 @@ class Foreach(Component):
         tag = self._render()
         tag = self._render()
         component = tag.render_component()
         component = tag.render_component()
 
 
-        # Apply the theme to the children.
-        if self.theme is not None:
-            component.apply_theme(self.theme)
-
         return dict(
         return dict(
             tag.add_props(
             tag.add_props(
                 **self.event_triggers,
                 **self.event_triggers,

+ 0 - 15
reflex/components/core/match.py

@@ -273,18 +273,3 @@ class Match(MemoizationLeaf):
             super()._get_imports(),
             super()._get_imports(),
             getattr(self.cond._var_data, "imports", {}),
             getattr(self.cond._var_data, "imports", {}),
         )
         )
-
-    def _apply_theme(self, theme: Component):
-        """Apply the theme to this component.
-
-        Args:
-            theme: The theme to apply.
-        """
-        # apply theme to return components.
-        for match_case in self.match_cases:
-            if isinstance(match_case[-1], Component):
-                match_case[-1].apply_theme(theme)
-
-        # apply theme to default component
-        if isinstance(self.default, Component):
-            self.default.apply_theme(theme)

+ 5 - 2
reflex/components/datadisplay/code.py

@@ -1,4 +1,6 @@
 """A code component."""
 """A code component."""
+from __future__ import annotations
+
 import re
 import re
 from typing import Dict, Literal, Optional, Union
 from typing import Dict, Literal, Optional, Union
 
 
@@ -491,8 +493,9 @@ class CodeBlock(Component):
         else:
         else:
             return code_block
             return code_block
 
 
-    def _add_style(self, style):
-        self.custom_style.update(style)  # type: ignore
+    def add_style(self) -> Style | None:
+        """Add style to the component."""
+        self.custom_style.update(self.style)
 
 
     def _render(self):
     def _render(self):
         out = super()._render()
         out = super()._render()

+ 1 - 0
reflex/components/datadisplay/code.pyi

@@ -1111,5 +1111,6 @@ class CodeBlock(Component):
             The text component.
             The text component.
         """
         """
         ...
         ...
+    def add_style(self) -> Style | None: ...
     @staticmethod
     @staticmethod
     def convert_theme_name(theme) -> str: ...
     def convert_theme_name(theme) -> str: ...

+ 2 - 2
reflex/components/markdown/markdown.py

@@ -18,7 +18,6 @@ from reflex.components.radix.themes.typography.heading import Heading
 from reflex.components.radix.themes.typography.link import Link
 from reflex.components.radix.themes.typography.link import Link
 from reflex.components.radix.themes.typography.text import Text
 from reflex.components.radix.themes.typography.text import Text
 from reflex.components.tags.tag import Tag
 from reflex.components.tags.tag import Tag
-from reflex.style import Style
 from reflex.utils import console, imports, types
 from reflex.utils import console, imports, types
 from reflex.utils.imports import ImportVar
 from reflex.utils.imports import ImportVar
 from reflex.vars import Var
 from reflex.vars import Var
@@ -230,7 +229,8 @@ class Markdown(Component):
         component = self.component_map[tag](*children, **props).set(
         component = self.component_map[tag](*children, **props).set(
             special_props=special_props
             special_props=special_props
         )
         )
-        component._add_style(Style(self.custom_styles.get(tag, {})))
+        component.style.update(self.custom_styles.get(tag, {}))
+
         return component
         return component
 
 
     def format_component(self, tag: str, **props) -> str:
     def format_component(self, tag: str, **props) -> str:

+ 0 - 1
reflex/components/markdown/markdown.pyi

@@ -22,7 +22,6 @@ from reflex.components.radix.themes.typography.heading import Heading
 from reflex.components.radix.themes.typography.link import Link
 from reflex.components.radix.themes.typography.link import Link
 from reflex.components.radix.themes.typography.text import Text
 from reflex.components.radix.themes.typography.text import Text
 from reflex.components.tags.tag import Tag
 from reflex.components.tags.tag import Tag
-from reflex.style import Style
 from reflex.utils import console, imports, types
 from reflex.utils import console, imports, types
 from reflex.utils.imports import ImportVar
 from reflex.utils.imports import ImportVar
 from reflex.vars import Var
 from reflex.vars import Var

+ 225 - 404
reflex/components/radix/primitives/accordion.py

@@ -5,302 +5,42 @@ from __future__ import annotations
 from typing import Any, Dict, List, Literal, Optional, Union
 from typing import Any, Dict, List, Literal, Optional, Union
 
 
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.component import Component, ComponentNamespace
-from reflex.components.core.match import Match
+from reflex.components.core.colors import color
 from reflex.components.lucide.icon import Icon
 from reflex.components.lucide.icon import Icon
 from reflex.components.radix.primitives.base import RadixPrimitiveComponent
 from reflex.components.radix.primitives.base import RadixPrimitiveComponent
 from reflex.components.radix.themes.base import LiteralAccentColor
 from reflex.components.radix.themes.base import LiteralAccentColor
-from reflex.style import (
-    Style,
-    convert_dict_to_style_and_format_emotion,
-    format_as_emotion,
-)
+from reflex.style import Style
 from reflex.utils import imports
 from reflex.utils import imports
-from reflex.vars import BaseVar, Var, VarData, get_uuid_string_var
+from reflex.vars import Var, get_uuid_string_var
 
 
 LiteralAccordionType = Literal["single", "multiple"]
 LiteralAccordionType = Literal["single", "multiple"]
 LiteralAccordionDir = Literal["ltr", "rtl"]
 LiteralAccordionDir = Literal["ltr", "rtl"]
 LiteralAccordionOrientation = Literal["vertical", "horizontal"]
 LiteralAccordionOrientation = Literal["vertical", "horizontal"]
-LiteralAccordionRootVariant = Literal["classic", "soft", "surface", "outline", "ghost"]
-LiteralAccordionRootColorScheme = Literal["primary", "accent"]
+LiteralAccordionVariant = Literal["classic", "soft", "surface", "outline", "ghost"]
 
 
 DEFAULT_ANIMATION_DURATION = 250
 DEFAULT_ANIMATION_DURATION = 250
 
 
 
 
-def get_theme_accordion_root(variant: Var[str], color_scheme: Var[str]) -> BaseVar:
-    """Get the theme for the accordion root component.
-
-    Args:
-        variant: The variant of the accordion.
-        color_scheme: The color of the accordion.
-
-    Returns:
-        The theme for the accordion root component.
-    """
-    return Match.create(  # type: ignore
-        variant,
-        (
-            "soft",
-            convert_dict_to_style_and_format_emotion(
-                {
-                    "border_radius": "6px",
-                    "background_color": f"var(--{color_scheme}-3)",
-                    "box_shadow": "0 2px 10px var(--black-a1)",
-                }
-            ),
-        ),
-        (
-            "outline",
-            convert_dict_to_style_and_format_emotion(
-                {
-                    "border_radius": "6px",
-                    "border": f"1px solid var(--{color_scheme}-6)",
-                    "box_shadow": "0 2px 10px var(--black-a1)",
-                }
-            ),
-        ),
-        (
-            "surface",
-            convert_dict_to_style_and_format_emotion(
-                {
-                    "border_radius": "6px",
-                    "border": f"1px solid var(--{color_scheme}-6)",
-                    "background_color": f"var(--{color_scheme}-3)",
-                    "box_shadow": "0 2px 10px var(--black-a1)",
-                }
-            ),
-        ),
-        (
-            "ghost",
-            convert_dict_to_style_and_format_emotion(
-                {
-                    "border_radius": "6px",
-                    "background_color": "none",
-                    "box_shadow": "None",
-                }
-            ),
-        ),
-        convert_dict_to_style_and_format_emotion(
-            {
-                "border_radius": "6px",
-                "background_color": f"var(--{color_scheme}-9)",
-                "box_shadow": "0 2px 10px var(--black-a4)",
-            }
-        ),
-        # defaults to classic
-    )
-
-
-def get_theme_accordion_item():
-    """Get the theme for the accordion item component.
-
-    Returns:
-        The theme for the accordion item component.
-    """
-    return convert_dict_to_style_and_format_emotion(
-        {
-            "overflow": "hidden",
-            "width": "100%",
-            "margin_top": "1px",
-            "&:first-child": {
-                "margin_top": 0,
-                "border_top_left_radius": "4px",
-                "border_top_right_radius": "4px",
-            },
-            "&:last-child": {
-                "border_bottom_left_radius": "4px",
-                "border_bottom_right_radius": "4px",
-            },
-            "&:focus-within": {
-                "position": "relative",
-                "z_index": 1,
-            },
-        }
-    )
-
+class AccordionComponent(RadixPrimitiveComponent):
+    """Base class for all @radix-ui/accordion components."""
 
 
-def get_theme_accordion_header() -> dict[str, str]:
-    """Get the theme for the accordion header component.
+    library = "@radix-ui/react-accordion@^1.1.2"
 
 
-    Returns:
-        The theme for the accordion header component.
-    """
-    return {
-        "display": "flex",
-    }
+    # The color scheme of the component.
+    color_scheme: Var[LiteralAccentColor]
 
 
+    # The variant of the component.
+    variant: Var[LiteralAccordionVariant] = Var.create_safe("classic")
 
 
-def get_theme_accordion_trigger(variant: str | Var, color_scheme: str | Var) -> BaseVar:
-    """Get the theme for the accordion trigger component.
+    def add_style(self) -> Style | None:
+        """Add style to the component."""
+        if self.color_scheme is not None:
+            self.custom_attrs["data-accent-color"] = self.color_scheme
 
 
-    Args:
-        variant: The variant of the accordion.
-        color_scheme: The color of the accordion.
+        self.custom_attrs["data-variant"] = self.variant
 
 
-    Returns:
-        The theme for the accordion trigger component.
-    """
-    return Match.create(  # type: ignore
-        variant,
-        (
-            "soft",
-            convert_dict_to_style_and_format_emotion(
-                {
-                    "color": f"var(--{color_scheme}-11)",
-                    "&:hover": {
-                        "background_color": f"var(--{color_scheme}-4)",
-                    },
-                    "& > .AccordionChevron": {
-                        "color": f"var(--{color_scheme}-11)",
-                        "transition": f"transform {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)",
-                    },
-                    "&[data-state='open'] > .AccordionChevron": {
-                        "transform": "rotate(180deg)",
-                    },
-                    "font_family": "inherit",
-                    "width": "100%",
-                    "padding": "0 20px",
-                    "height": "45px",
-                    "flex": 1,
-                    "display": "flex",
-                    "align_items": "center",
-                    "justify_content": "space-between",
-                    "font_size": "15px",
-                    "line_height": 1,
-                }
-            ),
-        ),
-        (
-            "outline",
-            "surface",
-            "ghost",
-            convert_dict_to_style_and_format_emotion(
-                {
-                    "color": f"var(--{color_scheme}-11)",
-                    "&:hover": {
-                        "background_color": f"var(--{color_scheme}-4)",
-                    },
-                    "& > .AccordionChevron": {
-                        "color": f"var(--{color_scheme}-11)",
-                        "transition": f"transform {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)",
-                    },
-                    "&[data-state='open'] > .AccordionChevron": {
-                        "transform": "rotate(180deg)",
-                    },
-                    "font_family": "inherit",
-                    "width": "100%",
-                    "padding": "0 20px",
-                    "height": "45px",
-                    "flex": 1,
-                    "display": "flex",
-                    "align_items": "center",
-                    "justify_content": "space-between",
-                    "font_size": "15px",
-                    "line_height": 1,
-                }
-            ),
-        ),
-        # defaults to classic
-        convert_dict_to_style_and_format_emotion(
-            {
-                "color": f"var(--{color_scheme}-9-contrast)",
-                "box_shadow": f"var(--{color_scheme}-11)",
-                "&:hover": {
-                    "background_color": f"var(--{color_scheme}-10)",
-                },
-                "& > .AccordionChevron": {
-                    "color": f"var(--{color_scheme}-9-contrast)",
-                    "transition": f"transform {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)",
-                },
-                "&[data-state='open'] > .AccordionChevron": {
-                    "transform": "rotate(180deg)",
-                },
-                "font_family": "inherit",
-                "width": "100%",
-                "padding": "0 20px",
-                "height": "45px",
-                "flex": 1,
-                "display": "flex",
-                "align_items": "center",
-                "justify_content": "space-between",
-                "font_size": "15px",
-                "line_height": 1,
-            }
-        ),
-    )
-
-
-def get_theme_accordion_content(variant: str | Var, color_scheme: str | Var) -> BaseVar:
-    """Get the theme for the accordion content component.
-
-    Args:
-        variant: The variant of the accordion.
-        color_scheme: The color of the accordion.
-
-    Returns:
-        The theme for the accordion content component.
-    """
-    return Match.create(  # type: ignore
-        variant,
-        (
-            "outline",
-            "ghost",
-            convert_dict_to_style_and_format_emotion(
-                {
-                    "overflow": "hidden",
-                    "font_size": "10px",
-                    "color": f"var(--{color_scheme}-11)",
-                    "padding": "15px 20px",
-                    "&[data-state='open']": {
-                        "animation": Var.create(
-                            f"${{slideDown}} {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)",
-                            _var_is_string=True,
-                        ),
-                    },
-                    "&[data-state='closed']": {
-                        "animation": Var.create(
-                            f"${{slideUp}} {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)",
-                            _var_is_string=True,
-                        ),
-                    },
-                }
-            ),
-        ),
-        convert_dict_to_style_and_format_emotion(
-            {
-                "overflow": "hidden",
-                "font_size": "10px",
-                "color": Match.create(
-                    variant,
-                    ("classic", f"var(--{color_scheme}-9-contrast)"),
-                    f"var(--{color_scheme}-11)",
-                ),
-                "background_color": Match.create(
-                    variant,
-                    ("classic", f"var(--{color_scheme}-9)"),
-                    f"var(--{color_scheme}-3)",
-                ),
-                "padding": "15px 20px",
-                "&[data-state='open']": {
-                    "animation": Var.create(
-                        f"${{slideDown}} {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)",
-                        _var_is_string=True,
-                    ),
-                },
-                "&[data-state='closed']": {
-                    "animation": Var.create(
-                        f"${{slideUp}} {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)",
-                        _var_is_string=True,
-                    ),
-                },
-            }
-        ),
-    )
-
-
-class AccordionComponent(RadixPrimitiveComponent):
-    """Base class for all @radix-ui/accordion components."""
-
-    library = "@radix-ui/react-accordion@^1.1.2"
+    def _exclude_props(self) -> list[str]:
+        return ["color_scheme", "variant"]
 
 
 
 
 class AccordionRoot(AccordionComponent):
 class AccordionRoot(AccordionComponent):
@@ -332,16 +72,7 @@ class AccordionRoot(AccordionComponent):
     orientation: Var[LiteralAccordionOrientation]
     orientation: Var[LiteralAccordionOrientation]
 
 
     # The variant of the accordion.
     # The variant of the accordion.
-    variant: Var[LiteralAccordionRootVariant] = "classic"  # type: ignore
-
-    # The color scheme of the accordion.
-    color_scheme: Var[LiteralAccentColor]  # type: ignore
-
-    # dynamic themes of the accordion generated at compile time.
-    _dynamic_themes: Var[dict] = Var.create({})  # type: ignore
-
-    # The var_data associated with the component.
-    _var_data: VarData = VarData()  # type: ignore
+    variant: Var[LiteralAccordionVariant] = Var.create_safe("classic")
 
 
     _valid_children: List[str] = ["AccordionItem"]
     _valid_children: List[str] = ["AccordionItem"]
 
 
@@ -356,81 +87,12 @@ class AccordionRoot(AccordionComponent):
         Returns:
         Returns:
             The Accordion root Component.
             The Accordion root Component.
         """
         """
-        comp = super().create(*children, **props)
-
-        if comp.color_scheme is not None and not comp.color_scheme._var_state:  # type: ignore
-            # mark the vars of color string literals as strings so they can be formatted properly when performing a var operation.
-            comp.color_scheme._var_is_string = True  # type: ignore
-
-        if comp.variant is not None and not comp.variant._var_state:  # type: ignore
-            # mark the vars of variant string literals as strings so they are formatted properly in the match condition.
-            comp.variant._var_is_string = True  # type: ignore
-
-        return comp
-
-    def _get_style(self) -> dict:
-        """Get the style for the component.
-
-        Returns:
-            The dictionary of the component style as value and the style notation as key.
-        """
-        return {"css": self._dynamic_themes._merge(format_as_emotion(self.style))}  # type: ignore
-
-    def _apply_theme(self, theme: Component):
-        global_color_scheme = getattr(theme, "accent_color", None)
-
-        if global_color_scheme is None and self.color_scheme is None:
-            raise ValueError(
-                "`color_scheme` cannot be None. Either set the `color_scheme` prop on the accordion "
-                "component or set the `accent_color` prop in your global theme."
-            )
-
-        # prepare the color_scheme var to be used in an f-string(strip off the wrapping curly brace)
-        color_scheme = Var.create(
-            self.color_scheme if self.color_scheme is not None else global_color_scheme
-        )._replace(  # type: ignore
-            _var_is_string=False
-        )
+        for child in children:
+            if isinstance(child, AccordionItem):
+                child.color_scheme = props.get("color_scheme")  # type: ignore
+                child.variant = props.get("variant")  # type: ignore
 
 
-        accordion_theme_root = get_theme_accordion_root(
-            variant=self.variant, color_scheme=color_scheme
-        )
-        accordion_theme_content = get_theme_accordion_content(
-            variant=self.variant, color_scheme=color_scheme
-        )
-        accordion_theme_trigger = get_theme_accordion_trigger(
-            variant=self.variant, color_scheme=color_scheme
-        )
-
-        # extract var_data from dynamic themes.
-        self._var_data = (
-            self._var_data.merge(  # type: ignore
-                accordion_theme_trigger._var_data,
-                accordion_theme_content._var_data,
-                accordion_theme_root._var_data,
-            )
-            or self._var_data
-        )
-
-        self._dynamic_themes = Var.create(  # type: ignore
-            convert_dict_to_style_and_format_emotion(
-                {
-                    "& .AccordionItem": get_theme_accordion_item(),
-                    "& .AccordionHeader": get_theme_accordion_header(),
-                    "& .AccordionTrigger": accordion_theme_trigger,
-                    "& .AccordionContent": accordion_theme_content,
-                }
-            )
-        )._merge(  # type: ignore
-            accordion_theme_root
-        )
-
-    def _get_imports(self):
-        return imports.merge_imports(
-            super()._get_imports(),
-            self._var_data.imports if self._var_data else {},
-            {"@emotion/react": [imports.ImportVar(tag="keyframes")]},
-        )
+        return super().create(*children, **props)
 
 
     def get_event_triggers(self) -> Dict[str, Any]:
     def get_event_triggers(self) -> Dict[str, Any]:
         """Get the events triggers signatures for the component.
         """Get the events triggers signatures for the component.
@@ -443,28 +105,36 @@ class AccordionRoot(AccordionComponent):
             "on_value_change": lambda e0: [e0],
             "on_value_change": lambda e0: [e0],
         }
         }
 
 
-    def _get_custom_code(self) -> str:
-        return """
-const slideDown = keyframes`
-from {
-  height: 0;
-}
-to {
-  height: var(--radix-accordion-content-height);
-}
-`
-const slideUp = keyframes`
-from {
-  height: var(--radix-accordion-content-height);
-}
-to {
-  height: 0;
-}
-`
-"""
+    def add_style(self):
+        """Add style to the component.
 
 
-    def _exclude_props(self) -> list[str]:
-        return ["color_scheme", "variant"]
+        Returns:
+            The style of the component.
+        """
+        return Style(
+            {
+                "border_radius": "6px",
+                "box_shadow": f"0 2px 10px {color('black', 1, alpha=True)}",
+                "&[data-variant='classic']": {
+                    "background_color": color("accent", 9),
+                    "box_shadow": f"0 2px 10px {color('black', 4, alpha=True)}",
+                },
+                "&[data-variant='soft']": {
+                    "background_color": color("accent", 3),
+                },
+                "&[data-variant='outline']": {
+                    "border": f"1px solid {color('accent', 6)}",
+                },
+                "&[data-variant='surface']": {
+                    "border": f"1px solid {color('accent', 6)}",
+                    "background_color": color("accent", 3),
+                },
+                "&[data-variant='ghost']": {
+                    "background_color": "none",
+                    "box_shadow": "None",
+                },
+            }
+        )
 
 
 
 
 class AccordionItem(AccordionComponent):
 class AccordionItem(AccordionComponent):
@@ -488,13 +158,6 @@ class AccordionItem(AccordionComponent):
 
 
     _valid_parents: List[str] = ["AccordionRoot"]
     _valid_parents: List[str] = ["AccordionRoot"]
 
 
-    def _apply_theme(self, theme: Component):
-        self.style = Style(
-            {
-                **self.style,
-            }
-        )
-
     @classmethod
     @classmethod
     def create(
     def create(
         cls,
         cls,
@@ -506,9 +169,9 @@ class AccordionItem(AccordionComponent):
         """Create an accordion item.
         """Create an accordion item.
 
 
         Args:
         Args:
+            *children: The list of children to use if header and content are not provided.
             header: The header of the accordion item.
             header: The header of the accordion item.
             content: The content of the accordion item.
             content: The content of the accordion item.
-            *children: The list of children to use if header and content are not provided.
             **props: Additional properties to apply to the accordion item.
             **props: Additional properties to apply to the accordion item.
 
 
         Returns:
         Returns:
@@ -527,14 +190,55 @@ class AccordionItem(AccordionComponent):
                 AccordionHeader.create(
                 AccordionHeader.create(
                     AccordionTrigger.create(
                     AccordionTrigger.create(
                         header,
                         header,
-                        AccordionIcon.create(),
+                        AccordionIcon.create(
+                            color_scheme=props.get("color_scheme"),
+                            variant=props.get("variant"),
+                        ),
+                        color_scheme=props.get("color_scheme"),
+                        variant=props.get("variant"),
                     ),
                     ),
+                    color_scheme=props.get("color_scheme"),
+                    variant=props.get("variant"),
+                ),
+                AccordionContent.create(
+                    content, color_scheme=props.get("color_scheme")
                 ),
                 ),
-                AccordionContent.create(content),
             ]
             ]
 
 
         return super().create(*children, value=value, **props, class_name=cls_name)
         return super().create(*children, value=value, **props, class_name=cls_name)
 
 
+    def add_style(self) -> Style | None:
+        """Add style to the component.
+
+        Returns:
+            The style of the component.
+        """
+        for child in self.children:
+            if isinstance(child, (AccordionHeader, AccordionContent)):
+                child.color_scheme = self.color_scheme
+                child.variant = self.variant
+
+        return Style(
+            {
+                "overflow": "hidden",
+                "width": "100%",
+                "margin_top": "1px",
+                "&:first-child": {
+                    "margin_top": 0,
+                    "border_top_left_radius": "4px",
+                    "border_top_right_radius": "4px",
+                },
+                "&:last-child": {
+                    "border_bottom_left_radius": "4px",
+                    "border_bottom_right_radius": "4px",
+                },
+                "&:focus-within": {
+                    "position": "relative",
+                    "z_index": 1,
+                },
+            }
+        )
+
 
 
 class AccordionHeader(AccordionComponent):
 class AccordionHeader(AccordionComponent):
     """An accordion component."""
     """An accordion component."""
@@ -561,8 +265,21 @@ class AccordionHeader(AccordionComponent):
 
 
         return super().create(*children, class_name=cls_name, **props)
         return super().create(*children, class_name=cls_name, **props)
 
 
-    def _apply_theme(self, theme: Component):
-        self.style = Style({**self.style})
+    def add_style(self) -> Style | None:
+        """Add style to the component.
+
+        Returns:
+            The style of the component.
+        """
+        for child in self.children:
+            if isinstance(child, AccordionTrigger):
+                child.color_scheme = self.color_scheme
+                child.variant = self.variant
+
+        return Style({"display": "flex"})
+
+
+cubic_bezier = "cubic-bezier(0.87, 0, 0.13, 1)"
 
 
 
 
 class AccordionTrigger(AccordionComponent):
 class AccordionTrigger(AccordionComponent):
@@ -590,8 +307,52 @@ class AccordionTrigger(AccordionComponent):
 
 
         return super().create(*children, class_name=cls_name, **props)
         return super().create(*children, class_name=cls_name, **props)
 
 
-    def _apply_theme(self, theme: Component):
-        self.style = Style({**self.style})
+    def add_style(self) -> Style | None:
+        """Add style to the component.
+
+        Returns:
+            The style of the component.
+        """
+        for child in self.children:
+            if isinstance(child, AccordionIcon):
+                child.color_scheme = self.color_scheme
+                child.variant = self.variant
+
+        return Style(
+            {
+                "color": color("accent", 11),
+                "line_height": 1,
+                "font_size": "15px",
+                "justify_content": "space-between",
+                "align_items": "center",
+                "flex": 1,
+                "display": "flex",
+                "padding": "0 20px",
+                "height": "45px",
+                "font_family": "inherit",
+                "width": "100%",
+                "&[data-state='open'] > .AccordionChevron": {
+                    "transform": "rotate(180deg)",
+                },
+                "&:hover": {
+                    "background_color": color("accent", 4),
+                },
+                "& > .AccordionChevron": {
+                    "transition": f"transform {DEFAULT_ANIMATION_DURATION}ms {cubic_bezier}",
+                },
+                "&[data-variant='classic']": {
+                    "color": color("accent", 12),
+                    "box_shadow": color("accent", 11),
+                    "&:hover": {
+                        "background_color": color("accent", 10),
+                    },
+                    "& > .AccordionChevron": {
+                        "color": color("accent", 12),
+                        "transition": f"transform {DEFAULT_ANIMATION_DURATION}ms {cubic_bezier}",
+                    },
+                },
+            }
+        )
 
 
 
 
 class AccordionIcon(Icon):
 class AccordionIcon(Icon):
@@ -623,6 +384,14 @@ class AccordionContent(AccordionComponent):
 
 
     alias = "RadixAccordionContent"
     alias = "RadixAccordionContent"
 
 
+    def add_imports(self) -> imports.ImportDict:
+        """Add imports to the component.
+
+        Returns:
+            The imports of the component.
+        """
+        return {"@emotion/react": [imports.ImportVar(tag="keyframes")]}
+
     @classmethod
     @classmethod
     def create(cls, *children, **props) -> Component:
     def create(cls, *children, **props) -> Component:
         """Create the Accordion content component.
         """Create the Accordion content component.
@@ -641,14 +410,66 @@ class AccordionContent(AccordionComponent):
 
 
         return super().create(*children, class_name=cls_name, **props)
         return super().create(*children, class_name=cls_name, **props)
 
 
-    def _apply_theme(self, theme: Component):
-        self.style = Style({**self.style})
+    def add_custom_code(self) -> list[str]:
+        """Add custom code to the component.
 
 
-    # def _get_imports(self):
-    #     return {
-    #         **super()._get_imports(),
-    #         "@emotion/react": [imports.ImportVar(tag="keyframes")],
-    #     }
+        Returns:
+            The custom code of the component.
+        """
+        return [
+            """
+const slideDown = keyframes`
+from {
+  height: 0;
+}
+to {
+  height: var(--radix-accordion-content-height);
+}
+`
+const slideUp = keyframes`
+from {
+  height: var(--radix-accordion-content-height);
+}
+to {
+  height: 0;
+}
+`
+"""
+        ]
+
+    def add_style(self) -> Style | None:
+        """Add style to the component.
+
+        Returns:
+            The style of the component.
+        """
+        slideDown = Var.create(
+            f"${{slideDown}} {DEFAULT_ANIMATION_DURATION}ms {cubic_bezier}",
+            _var_is_string=True,
+        )
+
+        slideUp = Var.create(
+            f"${{slideUp}} {DEFAULT_ANIMATION_DURATION}ms {cubic_bezier}",
+            _var_is_string=True,
+        )
+
+        return Style(
+            {
+                "overflow": "hidden",
+                "font_size": "10px",
+                "color": color("accent", 11),
+                "background_color": color("accent", 3),
+                "padding": "0 15px",
+                "&[data-state='open']": {"animation": slideDown},
+                "&[data-state='closed']": {"animation": slideUp},
+                "&[data-variant='classic']": {
+                    "color": color("accent", 12),
+                    "background_color": color("accent", 9),
+                },
+                "&[data-variant='outline']": {"background_color": "transparent"},
+                "&[data-variant='ghost']": {"background_color": "transparent"},
+            }
+        )
 
 
 
 
 class Accordion(ComponentNamespace):
 class Accordion(ComponentNamespace):

+ 367 - 26
reflex/components/radix/primitives/accordion.pyi

@@ -9,41 +9,95 @@ from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
 from reflex.style import Style
 from typing import Any, Dict, List, Literal, Optional, Union
 from typing import Any, Dict, List, Literal, Optional, Union
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.component import Component, ComponentNamespace
-from reflex.components.core.match import Match
+from reflex.components.core.colors import color
 from reflex.components.lucide.icon import Icon
 from reflex.components.lucide.icon import Icon
 from reflex.components.radix.primitives.base import RadixPrimitiveComponent
 from reflex.components.radix.primitives.base import RadixPrimitiveComponent
 from reflex.components.radix.themes.base import LiteralAccentColor
 from reflex.components.radix.themes.base import LiteralAccentColor
-from reflex.style import (
-    Style,
-    convert_dict_to_style_and_format_emotion,
-    format_as_emotion,
-)
+from reflex.style import Style
 from reflex.utils import imports
 from reflex.utils import imports
-from reflex.vars import BaseVar, Var, VarData, get_uuid_string_var
+from reflex.vars import Var, get_uuid_string_var
 
 
 LiteralAccordionType = Literal["single", "multiple"]
 LiteralAccordionType = Literal["single", "multiple"]
 LiteralAccordionDir = Literal["ltr", "rtl"]
 LiteralAccordionDir = Literal["ltr", "rtl"]
 LiteralAccordionOrientation = Literal["vertical", "horizontal"]
 LiteralAccordionOrientation = Literal["vertical", "horizontal"]
-LiteralAccordionRootVariant = Literal["classic", "soft", "surface", "outline", "ghost"]
-LiteralAccordionRootColorScheme = Literal["primary", "accent"]
+LiteralAccordionVariant = Literal["classic", "soft", "surface", "outline", "ghost"]
 DEFAULT_ANIMATION_DURATION = 250
 DEFAULT_ANIMATION_DURATION = 250
 
 
-def get_theme_accordion_root(variant: Var[str], color_scheme: Var[str]) -> BaseVar: ...
-def get_theme_accordion_item(): ...
-def get_theme_accordion_header() -> dict[str, str]: ...
-def get_theme_accordion_trigger(
-    variant: str | Var, color_scheme: str | Var
-) -> BaseVar: ...
-def get_theme_accordion_content(
-    variant: str | Var, color_scheme: str | Var
-) -> BaseVar: ...
-
 class AccordionComponent(RadixPrimitiveComponent):
 class AccordionComponent(RadixPrimitiveComponent):
+    def add_style(self) -> Style | None: ...
     @overload
     @overload
     @classmethod
     @classmethod
     def create(  # type: ignore
     def create(  # type: ignore
         cls,
         cls,
         *children,
         *children,
+        color_scheme: Optional[
+            Union[
+                Var[
+                    Literal[
+                        "tomato",
+                        "red",
+                        "ruby",
+                        "crimson",
+                        "pink",
+                        "plum",
+                        "purple",
+                        "violet",
+                        "iris",
+                        "indigo",
+                        "blue",
+                        "cyan",
+                        "teal",
+                        "jade",
+                        "green",
+                        "grass",
+                        "brown",
+                        "orange",
+                        "sky",
+                        "mint",
+                        "lime",
+                        "yellow",
+                        "amber",
+                        "gold",
+                        "bronze",
+                        "gray",
+                    ]
+                ],
+                Literal[
+                    "tomato",
+                    "red",
+                    "ruby",
+                    "crimson",
+                    "pink",
+                    "plum",
+                    "purple",
+                    "violet",
+                    "iris",
+                    "indigo",
+                    "blue",
+                    "cyan",
+                    "teal",
+                    "jade",
+                    "green",
+                    "grass",
+                    "brown",
+                    "orange",
+                    "sky",
+                    "mint",
+                    "lime",
+                    "yellow",
+                    "amber",
+                    "gold",
+                    "bronze",
+                    "gray",
+                ],
+            ]
+        ] = None,
+        variant: Optional[
+            Union[
+                Var[Literal["classic", "soft", "surface", "outline", "ghost"]],
+                Literal["classic", "soft", "surface", "outline", "ghost"],
+            ]
+        ] = None,
         as_child: Optional[Union[Var[bool], bool]] = None,
         as_child: Optional[Union[Var[bool], bool]] = None,
         style: Optional[Style] = None,
         style: Optional[Style] = None,
         key: Optional[Any] = None,
         key: Optional[Any] = None,
@@ -102,6 +156,8 @@ class AccordionComponent(RadixPrimitiveComponent):
 
 
         Args:
         Args:
             *children: The children of the component.
             *children: The children of the component.
+            color_scheme: The color scheme of the component.
+            variant: The variant of the component.
             as_child: Change the default rendered element for the one passed as a child.
             as_child: Change the default rendered element for the one passed as a child.
             style: The style of the component.
             style: The style of the component.
             key: A unique key for the component.
             key: A unique key for the component.
@@ -208,8 +264,6 @@ class AccordionRoot(AccordionComponent):
                 ],
                 ],
             ]
             ]
         ] = None,
         ] = None,
-        _dynamic_themes: Optional[Union[Var[dict], dict]] = None,
-        _var_data: Optional[VarData] = None,
         as_child: Optional[Union[Var[bool], bool]] = None,
         as_child: Optional[Union[Var[bool], bool]] = None,
         style: Optional[Style] = None,
         style: Optional[Style] = None,
         key: Optional[Any] = None,
         key: Optional[Any] = None,
@@ -278,10 +332,8 @@ class AccordionRoot(AccordionComponent):
             disabled: Whether or not the accordion is disabled.
             disabled: Whether or not the accordion is disabled.
             dir: The reading direction of the accordion when applicable.
             dir: The reading direction of the accordion when applicable.
             orientation: The orientation of the accordion.
             orientation: The orientation of the accordion.
-            variant: The variant of the accordion.
-            color_scheme: The color scheme of the accordion.
-            _dynamic_themes: dynamic themes of the accordion generated at compile time.
-            _var_data: The var_data associated with the component.
+            variant: The variant of the component.
+            color_scheme: The color scheme of the component.
             as_child: Change the default rendered element for the one passed as a child.
             as_child: Change the default rendered element for the one passed as a child.
             style: The style of the component.
             style: The style of the component.
             key: A unique key for the component.
             key: A unique key for the component.
@@ -296,6 +348,7 @@ class AccordionRoot(AccordionComponent):
         """
         """
         ...
         ...
     def get_event_triggers(self) -> Dict[str, Any]: ...
     def get_event_triggers(self) -> Dict[str, Any]: ...
+    def add_style(self): ...
 
 
 class AccordionItem(AccordionComponent):
 class AccordionItem(AccordionComponent):
     @overload
     @overload
@@ -307,6 +360,74 @@ class AccordionItem(AccordionComponent):
         content: Optional[Union[Component, Var]] = None,
         content: Optional[Union[Component, Var]] = None,
         value: Optional[Union[Var[str], str]] = None,
         value: Optional[Union[Var[str], str]] = None,
         disabled: Optional[Union[Var[bool], bool]] = None,
         disabled: Optional[Union[Var[bool], bool]] = None,
+        color_scheme: Optional[
+            Union[
+                Var[
+                    Literal[
+                        "tomato",
+                        "red",
+                        "ruby",
+                        "crimson",
+                        "pink",
+                        "plum",
+                        "purple",
+                        "violet",
+                        "iris",
+                        "indigo",
+                        "blue",
+                        "cyan",
+                        "teal",
+                        "jade",
+                        "green",
+                        "grass",
+                        "brown",
+                        "orange",
+                        "sky",
+                        "mint",
+                        "lime",
+                        "yellow",
+                        "amber",
+                        "gold",
+                        "bronze",
+                        "gray",
+                    ]
+                ],
+                Literal[
+                    "tomato",
+                    "red",
+                    "ruby",
+                    "crimson",
+                    "pink",
+                    "plum",
+                    "purple",
+                    "violet",
+                    "iris",
+                    "indigo",
+                    "blue",
+                    "cyan",
+                    "teal",
+                    "jade",
+                    "green",
+                    "grass",
+                    "brown",
+                    "orange",
+                    "sky",
+                    "mint",
+                    "lime",
+                    "yellow",
+                    "amber",
+                    "gold",
+                    "bronze",
+                    "gray",
+                ],
+            ]
+        ] = None,
+        variant: Optional[
+            Union[
+                Var[Literal["classic", "soft", "surface", "outline", "ghost"]],
+                Literal["classic", "soft", "surface", "outline", "ghost"],
+            ]
+        ] = None,
         as_child: Optional[Union[Var[bool], bool]] = None,
         as_child: Optional[Union[Var[bool], bool]] = None,
         style: Optional[Style] = None,
         style: Optional[Style] = None,
         key: Optional[Any] = None,
         key: Optional[Any] = None,
@@ -364,11 +485,13 @@ class AccordionItem(AccordionComponent):
         """Create an accordion item.
         """Create an accordion item.
 
 
         Args:
         Args:
+            *children: The list of children to use if header and content are not provided.
             header: The header of the accordion item.
             header: The header of the accordion item.
             content: The content of the accordion item.
             content: The content of the accordion item.
-            *children: The list of children to use if header and content are not provided.
             value: A unique identifier for the item.
             value: A unique identifier for the item.
             disabled: When true, prevents the user from interacting with the item.
             disabled: When true, prevents the user from interacting with the item.
+            color_scheme: The color scheme of the component.
+            variant: The variant of the component.
             as_child: Change the default rendered element for the one passed as a child.
             as_child: Change the default rendered element for the one passed as a child.
             style: The style of the component.
             style: The style of the component.
             key: A unique key for the component.
             key: A unique key for the component.
@@ -382,6 +505,7 @@ class AccordionItem(AccordionComponent):
             The accordion item.
             The accordion item.
         """
         """
         ...
         ...
+    def add_style(self) -> Style | None: ...
 
 
 class AccordionHeader(AccordionComponent):
 class AccordionHeader(AccordionComponent):
     @overload
     @overload
@@ -389,6 +513,74 @@ class AccordionHeader(AccordionComponent):
     def create(  # type: ignore
     def create(  # type: ignore
         cls,
         cls,
         *children,
         *children,
+        color_scheme: Optional[
+            Union[
+                Var[
+                    Literal[
+                        "tomato",
+                        "red",
+                        "ruby",
+                        "crimson",
+                        "pink",
+                        "plum",
+                        "purple",
+                        "violet",
+                        "iris",
+                        "indigo",
+                        "blue",
+                        "cyan",
+                        "teal",
+                        "jade",
+                        "green",
+                        "grass",
+                        "brown",
+                        "orange",
+                        "sky",
+                        "mint",
+                        "lime",
+                        "yellow",
+                        "amber",
+                        "gold",
+                        "bronze",
+                        "gray",
+                    ]
+                ],
+                Literal[
+                    "tomato",
+                    "red",
+                    "ruby",
+                    "crimson",
+                    "pink",
+                    "plum",
+                    "purple",
+                    "violet",
+                    "iris",
+                    "indigo",
+                    "blue",
+                    "cyan",
+                    "teal",
+                    "jade",
+                    "green",
+                    "grass",
+                    "brown",
+                    "orange",
+                    "sky",
+                    "mint",
+                    "lime",
+                    "yellow",
+                    "amber",
+                    "gold",
+                    "bronze",
+                    "gray",
+                ],
+            ]
+        ] = None,
+        variant: Optional[
+            Union[
+                Var[Literal["classic", "soft", "surface", "outline", "ghost"]],
+                Literal["classic", "soft", "surface", "outline", "ghost"],
+            ]
+        ] = None,
         as_child: Optional[Union[Var[bool], bool]] = None,
         as_child: Optional[Union[Var[bool], bool]] = None,
         style: Optional[Style] = None,
         style: Optional[Style] = None,
         key: Optional[Any] = None,
         key: Optional[Any] = None,
@@ -447,6 +639,8 @@ class AccordionHeader(AccordionComponent):
 
 
         Args:
         Args:
             *children: The children of the component.
             *children: The children of the component.
+            color_scheme: The color scheme of the component.
+            variant: The variant of the component.
             as_child: Change the default rendered element for the one passed as a child.
             as_child: Change the default rendered element for the one passed as a child.
             style: The style of the component.
             style: The style of the component.
             key: A unique key for the component.
             key: A unique key for the component.
@@ -460,6 +654,9 @@ class AccordionHeader(AccordionComponent):
             The Accordion header Component.
             The Accordion header Component.
         """
         """
         ...
         ...
+    def add_style(self) -> Style | None: ...
+
+cubic_bezier = "cubic-bezier(0.87, 0, 0.13, 1)"
 
 
 class AccordionTrigger(AccordionComponent):
 class AccordionTrigger(AccordionComponent):
     @overload
     @overload
@@ -467,6 +664,74 @@ class AccordionTrigger(AccordionComponent):
     def create(  # type: ignore
     def create(  # type: ignore
         cls,
         cls,
         *children,
         *children,
+        color_scheme: Optional[
+            Union[
+                Var[
+                    Literal[
+                        "tomato",
+                        "red",
+                        "ruby",
+                        "crimson",
+                        "pink",
+                        "plum",
+                        "purple",
+                        "violet",
+                        "iris",
+                        "indigo",
+                        "blue",
+                        "cyan",
+                        "teal",
+                        "jade",
+                        "green",
+                        "grass",
+                        "brown",
+                        "orange",
+                        "sky",
+                        "mint",
+                        "lime",
+                        "yellow",
+                        "amber",
+                        "gold",
+                        "bronze",
+                        "gray",
+                    ]
+                ],
+                Literal[
+                    "tomato",
+                    "red",
+                    "ruby",
+                    "crimson",
+                    "pink",
+                    "plum",
+                    "purple",
+                    "violet",
+                    "iris",
+                    "indigo",
+                    "blue",
+                    "cyan",
+                    "teal",
+                    "jade",
+                    "green",
+                    "grass",
+                    "brown",
+                    "orange",
+                    "sky",
+                    "mint",
+                    "lime",
+                    "yellow",
+                    "amber",
+                    "gold",
+                    "bronze",
+                    "gray",
+                ],
+            ]
+        ] = None,
+        variant: Optional[
+            Union[
+                Var[Literal["classic", "soft", "surface", "outline", "ghost"]],
+                Literal["classic", "soft", "surface", "outline", "ghost"],
+            ]
+        ] = None,
         as_child: Optional[Union[Var[bool], bool]] = None,
         as_child: Optional[Union[Var[bool], bool]] = None,
         style: Optional[Style] = None,
         style: Optional[Style] = None,
         key: Optional[Any] = None,
         key: Optional[Any] = None,
@@ -525,6 +790,8 @@ class AccordionTrigger(AccordionComponent):
 
 
         Args:
         Args:
             *children: The children of the component.
             *children: The children of the component.
+            color_scheme: The color scheme of the component.
+            variant: The variant of the component.
             as_child: Change the default rendered element for the one passed as a child.
             as_child: Change the default rendered element for the one passed as a child.
             style: The style of the component.
             style: The style of the component.
             key: A unique key for the component.
             key: A unique key for the component.
@@ -538,6 +805,7 @@ class AccordionTrigger(AccordionComponent):
             The Accordion trigger Component.
             The Accordion trigger Component.
         """
         """
         ...
         ...
+    def add_style(self) -> Style | None: ...
 
 
 class AccordionIcon(Icon):
 class AccordionIcon(Icon):
     @overload
     @overload
@@ -618,11 +886,80 @@ class AccordionIcon(Icon):
         ...
         ...
 
 
 class AccordionContent(AccordionComponent):
 class AccordionContent(AccordionComponent):
+    def add_imports(self) -> imports.ImportDict: ...
     @overload
     @overload
     @classmethod
     @classmethod
     def create(  # type: ignore
     def create(  # type: ignore
         cls,
         cls,
         *children,
         *children,
+        color_scheme: Optional[
+            Union[
+                Var[
+                    Literal[
+                        "tomato",
+                        "red",
+                        "ruby",
+                        "crimson",
+                        "pink",
+                        "plum",
+                        "purple",
+                        "violet",
+                        "iris",
+                        "indigo",
+                        "blue",
+                        "cyan",
+                        "teal",
+                        "jade",
+                        "green",
+                        "grass",
+                        "brown",
+                        "orange",
+                        "sky",
+                        "mint",
+                        "lime",
+                        "yellow",
+                        "amber",
+                        "gold",
+                        "bronze",
+                        "gray",
+                    ]
+                ],
+                Literal[
+                    "tomato",
+                    "red",
+                    "ruby",
+                    "crimson",
+                    "pink",
+                    "plum",
+                    "purple",
+                    "violet",
+                    "iris",
+                    "indigo",
+                    "blue",
+                    "cyan",
+                    "teal",
+                    "jade",
+                    "green",
+                    "grass",
+                    "brown",
+                    "orange",
+                    "sky",
+                    "mint",
+                    "lime",
+                    "yellow",
+                    "amber",
+                    "gold",
+                    "bronze",
+                    "gray",
+                ],
+            ]
+        ] = None,
+        variant: Optional[
+            Union[
+                Var[Literal["classic", "soft", "surface", "outline", "ghost"]],
+                Literal["classic", "soft", "surface", "outline", "ghost"],
+            ]
+        ] = None,
         as_child: Optional[Union[Var[bool], bool]] = None,
         as_child: Optional[Union[Var[bool], bool]] = None,
         style: Optional[Style] = None,
         style: Optional[Style] = None,
         key: Optional[Any] = None,
         key: Optional[Any] = None,
@@ -681,6 +1018,8 @@ class AccordionContent(AccordionComponent):
 
 
         Args:
         Args:
             *children: The children of the component.
             *children: The children of the component.
+            color_scheme: The color scheme of the component.
+            variant: The variant of the component.
             as_child: Change the default rendered element for the one passed as a child.
             as_child: Change the default rendered element for the one passed as a child.
             style: The style of the component.
             style: The style of the component.
             key: A unique key for the component.
             key: A unique key for the component.
@@ -694,6 +1033,8 @@ class AccordionContent(AccordionComponent):
             The Accordion content Component.
             The Accordion content Component.
         """
         """
         ...
         ...
+    def add_custom_code(self) -> list[str]: ...
+    def add_style(self) -> Style | None: ...
 
 
 class Accordion(ComponentNamespace):
 class Accordion(ComponentNamespace):
     content = staticmethod(AccordionContent.create)
     content = staticmethod(AccordionContent.create)

+ 30 - 26
reflex/components/radix/primitives/form.py

@@ -4,10 +4,11 @@ from __future__ import annotations
 
 
 from typing import Any, Dict, Literal
 from typing import Any, Dict, Literal
 
 
-from reflex.components.component import Component, ComponentNamespace
+from reflex.components.component import ComponentNamespace
 from reflex.components.el.elements.forms import Form as HTMLForm
 from reflex.components.el.elements.forms import Form as HTMLForm
 from reflex.components.radix.themes.components.text_field import TextFieldRoot
 from reflex.components.radix.themes.components.text_field import TextFieldRoot
 from reflex.constants.event import EventTriggers
 from reflex.constants.event import EventTriggers
+from reflex.style import Style
 from reflex.vars import Var
 from reflex.vars import Var
 
 
 from .base import RadixPrimitiveComponentWithClassName
 from .base import RadixPrimitiveComponentWithClassName
@@ -37,11 +38,13 @@ class FormRoot(FormComponent, HTMLForm):
             EventTriggers.ON_CLEAR_SERVER_ERRORS: lambda: [],
             EventTriggers.ON_CLEAR_SERVER_ERRORS: lambda: [],
         }
         }
 
 
-    def _apply_theme(self, theme: Component):
-        return {
-            "width": "260px",
-            **self.style,
-        }
+    def add_style(self) -> Style | None:
+        """Add style to the component.
+
+        Returns:
+            The style of the component.
+        """
+        return Style({"width": "260px"})
 
 
 
 
 class FormField(FormComponent):
 class FormField(FormComponent):
@@ -57,12 +60,13 @@ class FormField(FormComponent):
     # Flag to mark the form field as invalid, for server side validation.
     # Flag to mark the form field as invalid, for server side validation.
     server_invalid: Var[bool]
     server_invalid: Var[bool]
 
 
-    def _apply_theme(self, theme: Component):
-        return {
-            "display": "grid",
-            "margin_bottom": "10px",
-            **self.style,
-        }
+    def add_style(self) -> Style | None:
+        """Add style to the component.
+
+        Returns:
+            The style of the component.
+        """
+        return Style({"display": "grid", "margin_bottom": "10px"})
 
 
 
 
 class FormLabel(FormComponent):
 class FormLabel(FormComponent):
@@ -72,13 +76,13 @@ class FormLabel(FormComponent):
 
 
     alias = "RadixFormLabel"
     alias = "RadixFormLabel"
 
 
-    def _apply_theme(self, theme: Component):
-        return {
-            "font_size": "15px",
-            "font_weight": "500",
-            "line_height": "35px",
-            **self.style,
-        }
+    def add_style(self) -> Style | None:
+        """Add style to the component.
+
+        Returns:
+            The style of the component.
+        """
+        return Style({"font_size": "15px", "font_weight": "500", "line_height": "35px"})
 
 
 
 
 class FormControl(FormComponent):
 class FormControl(FormComponent):
@@ -145,13 +149,13 @@ class FormMessage(FormComponent):
     # Forces the message to be shown. This is useful when using server-side validation.
     # Forces the message to be shown. This is useful when using server-side validation.
     force_match: Var[bool]
     force_match: Var[bool]
 
 
-    def _apply_theme(self, theme: Component):
-        return {
-            "font_size": "13px",
-            "opacity": "0.8",
-            "color": "white",
-            **self.style,
-        }
+    def add_style(self) -> Style | None:
+        """Add style to the component.
+
+        Returns:
+            The style of the component.
+        """
+        return Style({"font_size": "13px", "opacity": "0.8", "color": "white"})
 
 
 
 
 class FormValidityState(FormComponent):
 class FormValidityState(FormComponent):

+ 6 - 1
reflex/components/radix/primitives/form.pyi

@@ -8,10 +8,11 @@ from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
 from reflex.style import Style
 from typing import Any, Dict, Literal
 from typing import Any, Dict, Literal
-from reflex.components.component import Component, ComponentNamespace
+from reflex.components.component import ComponentNamespace
 from reflex.components.el.elements.forms import Form as HTMLForm
 from reflex.components.el.elements.forms import Form as HTMLForm
 from reflex.components.radix.themes.components.text_field import TextFieldRoot
 from reflex.components.radix.themes.components.text_field import TextFieldRoot
 from reflex.constants.event import EventTriggers
 from reflex.constants.event import EventTriggers
+from reflex.style import Style
 from reflex.vars import Var
 from reflex.vars import Var
 from .base import RadixPrimitiveComponentWithClassName
 from .base import RadixPrimitiveComponentWithClassName
 
 
@@ -95,6 +96,7 @@ class FormComponent(RadixPrimitiveComponentWithClassName):
 
 
 class FormRoot(FormComponent, HTMLForm):
 class FormRoot(FormComponent, HTMLForm):
     def get_event_triggers(self) -> Dict[str, Any]: ...
     def get_event_triggers(self) -> Dict[str, Any]: ...
+    def add_style(self) -> Style | None: ...
     @overload
     @overload
     @classmethod
     @classmethod
     def create(  # type: ignore
     def create(  # type: ignore
@@ -273,6 +275,7 @@ class FormRoot(FormComponent, HTMLForm):
         ...
         ...
 
 
 class FormField(FormComponent):
 class FormField(FormComponent):
+    def add_style(self) -> Style | None: ...
     @overload
     @overload
     @classmethod
     @classmethod
     def create(  # type: ignore
     def create(  # type: ignore
@@ -355,6 +358,7 @@ class FormField(FormComponent):
         ...
         ...
 
 
 class FormLabel(FormComponent):
 class FormLabel(FormComponent):
+    def add_style(self) -> Style | None: ...
     @overload
     @overload
     @classmethod
     @classmethod
     def create(  # type: ignore
     def create(  # type: ignore
@@ -528,6 +532,7 @@ LiteralMatcher = Literal[
 ]
 ]
 
 
 class FormMessage(FormComponent):
 class FormMessage(FormComponent):
+    def add_style(self) -> Style | None: ...
     @overload
     @overload
     @classmethod
     @classmethod
     def create(  # type: ignore
     def create(  # type: ignore

+ 17 - 9
reflex/components/radix/primitives/progress.py

@@ -28,20 +28,24 @@ class ProgressRoot(ProgressComponent):
     # Override theme radius for progress bar: "none" | "small" | "medium" | "large" | "full"
     # Override theme radius for progress bar: "none" | "small" | "medium" | "large" | "full"
     radius: Var[LiteralRadius]
     radius: Var[LiteralRadius]
 
 
-    def _apply_theme(self, theme: Component):
+    def add_style(self) -> Style | None:
+        """Add style to the component.
+
+        Returns:
+            The style of the component.
+        """
         if self.radius is not None:
         if self.radius is not None:
             self.custom_attrs["data-radius"] = self.radius
             self.custom_attrs["data-radius"] = self.radius
 
 
-        self.style = Style(
+        return Style(
             {
             {
                 "position": "relative",
                 "position": "relative",
                 "overflow": "hidden",
                 "overflow": "hidden",
-                "background": "var(--gray-a3)",
+                "background": color("gray", 3, alpha=True),
                 "border_radius": "max(var(--radius-2), var(--radius-full))",
                 "border_radius": "max(var(--radius-2), var(--radius-full))",
                 "width": "100%",
                 "width": "100%",
                 "height": "20px",
                 "height": "20px",
-                "boxShadow": "inset 0 0 0 1px var(--gray-a5)",
-                **self.style,
+                "boxShadow": f"inset 0 0 0 1px {color('gray', 5, alpha=True)}",
             }
             }
         )
         )
 
 
@@ -65,22 +69,26 @@ class ProgressIndicator(ProgressComponent):
     # The color scheme of the progress indicator.
     # The color scheme of the progress indicator.
     color_scheme: Var[LiteralAccentColor]
     color_scheme: Var[LiteralAccentColor]
 
 
-    def _apply_theme(self, theme: Component):
+    def add_style(self) -> Style | None:
+        """Add style to the component.
+
+        Returns:
+            The style of the component.
+        """
         if self.color_scheme is not None:
         if self.color_scheme is not None:
             self.custom_attrs["data-accent-color"] = self.color_scheme
             self.custom_attrs["data-accent-color"] = self.color_scheme
 
 
-        self.style = Style(
+        return Style(
             {
             {
                 "background_color": color("accent", 9),
                 "background_color": color("accent", 9),
                 "width": "100%",
                 "width": "100%",
                 "height": "100%",
                 "height": "100%",
-                f"transition": f"transform {DEFAULT_ANIMATION_DURATION}ms linear",
+                "transition": f"transform {DEFAULT_ANIMATION_DURATION}ms linear",
                 "&[data_state='loading']": {
                 "&[data_state='loading']": {
                     "transition": f"transform {DEFAULT_ANIMATION_DURATION}ms linear",
                     "transition": f"transform {DEFAULT_ANIMATION_DURATION}ms linear",
                 },
                 },
                 "transform": f"translateX(calc(-100% + ({self.value} / {self.max} * 100%)))",  # type: ignore
                 "transform": f"translateX(calc(-100% + ({self.value} / {self.max} * 100%)))",  # type: ignore
                 "boxShadow": "inset 0 0 0 1px var(--gray-a5)",
                 "boxShadow": "inset 0 0 0 1px var(--gray-a5)",
-                **self.style,
             }
             }
         )
         )
 
 

+ 2 - 0
reflex/components/radix/primitives/progress.pyi

@@ -95,6 +95,7 @@ class ProgressComponent(RadixPrimitiveComponentWithClassName):
         ...
         ...
 
 
 class ProgressRoot(ProgressComponent):
 class ProgressRoot(ProgressComponent):
+    def add_style(self) -> Style | None: ...
     @overload
     @overload
     @classmethod
     @classmethod
     def create(  # type: ignore
     def create(  # type: ignore
@@ -180,6 +181,7 @@ class ProgressRoot(ProgressComponent):
         ...
         ...
 
 
 class ProgressIndicator(ProgressComponent):
 class ProgressIndicator(ProgressComponent):
+    def add_style(self) -> Style | None: ...
     @overload
     @overload
     @classmethod
     @classmethod
     def create(  # type: ignore
     def create(  # type: ignore

+ 30 - 18
reflex/components/radix/primitives/slider.py

@@ -59,8 +59,13 @@ class SliderRoot(SliderComponent):
             "on_value_commit": lambda e0: [e0],  # trigger when thumb is released
             "on_value_commit": lambda e0: [e0],  # trigger when thumb is released
         }
         }
 
 
-    def _apply_theme(self, theme: Component):
-        self.style = Style(
+    def add_style(self) -> Style | None:
+        """Add style to the component.
+
+        Returns:
+            The style of the component.
+        """
+        return Style(
             {
             {
                 "position": "relative",
                 "position": "relative",
                 "display": "flex",
                 "display": "flex",
@@ -74,7 +79,6 @@ class SliderRoot(SliderComponent):
                     "width": "20px",
                     "width": "20px",
                     "height": "100px",
                     "height": "100px",
                 },
                 },
-                **self.style,
             }
             }
         )
         )
 
 
@@ -85,18 +89,20 @@ class SliderTrack(SliderComponent):
     tag = "Track"
     tag = "Track"
     alias = "RadixSliderTrack"
     alias = "RadixSliderTrack"
 
 
-    def _apply_theme(self, theme: Component):
-        self.style = Style(
+    def add_style(self) -> Style | None:
+        """Add style to the component.
+
+        Returns:
+            The style of the component.
+        """
+        return Style(
             {
             {
                 "position": "relative",
                 "position": "relative",
                 "flex_grow": "1",
                 "flex_grow": "1",
                 "background_color": "black",
                 "background_color": "black",
                 "border_radius": "9999px",
                 "border_radius": "9999px",
                 "height": "3px",
                 "height": "3px",
-                "&[data-orientation='vertical']": {
-                    "width": "3px",
-                },
-                **self.style,
+                "&[data-orientation='vertical']": {"width": "3px"},
             }
             }
         )
         )
 
 
@@ -107,16 +113,18 @@ class SliderRange(SliderComponent):
     tag = "Range"
     tag = "Range"
     alias = "RadixSliderRange"
     alias = "RadixSliderRange"
 
 
-    def _apply_theme(self, theme: Component):
-        self.style = Style(
+    def add_style(self) -> Style | None:
+        """Add style to the component.
+
+        Returns:
+            The style of the component.
+        """
+        return Style(
             {
             {
                 "position": "absolute",
                 "position": "absolute",
                 "background_color": "white",
                 "background_color": "white",
                 "height": "100%",
                 "height": "100%",
-                "&[data-orientation='vertical']": {
-                    "width": "100%",
-                },
-                **self.style,
+                "&[data-orientation='vertical']": {"width": "100%"},
             }
             }
         )
         )
 
 
@@ -127,8 +135,13 @@ class SliderThumb(SliderComponent):
     tag = "Thumb"
     tag = "Thumb"
     alias = "RadixSliderThumb"
     alias = "RadixSliderThumb"
 
 
-    def _apply_theme(self, theme: Component):
-        self.style = Style(
+    def add_style(self) -> Style | None:
+        """Add style to the component.
+
+        Returns:
+            The style of the component.
+        """
+        return Style(
             {
             {
                 "display": "block",
                 "display": "block",
                 "width": "20px",
                 "width": "20px",
@@ -143,7 +156,6 @@ class SliderThumb(SliderComponent):
                     "outline": "none",
                     "outline": "none",
                     "box_shadow": "0 0 0 4px gray",
                     "box_shadow": "0 0 0 4px gray",
                 },
                 },
-                **self.style,
             }
             }
         )
         )
 
 

+ 4 - 0
reflex/components/radix/primitives/slider.pyi

@@ -96,6 +96,7 @@ class SliderComponent(RadixPrimitiveComponentWithClassName):
 
 
 class SliderRoot(SliderComponent):
 class SliderRoot(SliderComponent):
     def get_event_triggers(self) -> Dict[str, Any]: ...
     def get_event_triggers(self) -> Dict[str, Any]: ...
+    def add_style(self) -> Style | None: ...
     @overload
     @overload
     @classmethod
     @classmethod
     def create(  # type: ignore
     def create(  # type: ignore
@@ -196,6 +197,7 @@ class SliderRoot(SliderComponent):
         ...
         ...
 
 
 class SliderTrack(SliderComponent):
 class SliderTrack(SliderComponent):
+    def add_style(self) -> Style | None: ...
     @overload
     @overload
     @classmethod
     @classmethod
     def create(  # type: ignore
     def create(  # type: ignore
@@ -274,6 +276,7 @@ class SliderTrack(SliderComponent):
         ...
         ...
 
 
 class SliderRange(SliderComponent):
 class SliderRange(SliderComponent):
+    def add_style(self) -> Style | None: ...
     @overload
     @overload
     @classmethod
     @classmethod
     def create(  # type: ignore
     def create(  # type: ignore
@@ -352,6 +355,7 @@ class SliderRange(SliderComponent):
         ...
         ...
 
 
 class SliderThumb(SliderComponent):
 class SliderThumb(SliderComponent):
+    def add_style(self) -> Style | None: ...
     @overload
     @overload
     @classmethod
     @classmethod
     def create(  # type: ignore
     def create(  # type: ignore

+ 13 - 11
reflex/components/radix/themes/components/icon_button.py

@@ -1,4 +1,5 @@
 """Interactive components provided by @radix-ui/themes."""
 """Interactive components provided by @radix-ui/themes."""
+from __future__ import annotations
 
 
 from typing import Literal
 from typing import Literal
 
 
@@ -6,6 +7,7 @@ from reflex import el
 from reflex.components.component import Component
 from reflex.components.component import Component
 from reflex.components.core.match import Match
 from reflex.components.core.match import Match
 from reflex.components.lucide import Icon
 from reflex.components.lucide import Icon
+from reflex.style import Style
 from reflex.vars import Var
 from reflex.vars import Var
 
 
 from ..base import (
 from ..base import (
@@ -68,25 +70,25 @@ class IconButton(el.Button, RadixLoadingProp, RadixThemesComponent):
                 "IconButton requires a child icon. Pass a string as the first child or a rx.icon."
                 "IconButton requires a child icon. Pass a string as the first child or a rx.icon."
             )
             )
         if "size" in props:
         if "size" in props:
+            RADIX_TO_LUCIDE_SIZE = {"1": "12px", "2": "24px", "3": "36px", "4": "48px"}
+
             if isinstance(props["size"], str):
             if isinstance(props["size"], str):
-                RADIX_TO_LUCIDE_SIZE = {
-                    "1": "12px",
-                    "2": "24px",
-                    "3": "36px",
-                    "4": "48px",
-                }
                 children[0].size = RADIX_TO_LUCIDE_SIZE[props["size"]]
                 children[0].size = RADIX_TO_LUCIDE_SIZE[props["size"]]
             else:
             else:
                 children[0].size = Match.create(
                 children[0].size = Match.create(
                     props["size"],
                     props["size"],
-                    ("1", "12px"),
-                    ("2", "24px"),
-                    ("3", "36px"),
-                    ("4", "48px"),
+                    *[(size, px) for size, px in RADIX_TO_LUCIDE_SIZE.items()],
                     "12px",
                     "12px",
                 )
                 )
-        props.setdefault("padding", "6px")
         return super().create(*children, **props)
         return super().create(*children, **props)
 
 
+    def add_style(self):
+        """Add style to the component.
+
+        Returns:
+            The style of the component.
+        """
+        return Style({"padding": "6px"})
+
 
 
 icon_button = IconButton.create
 icon_button = IconButton.create

+ 2 - 0
reflex/components/radix/themes/components/icon_button.pyi

@@ -12,6 +12,7 @@ from reflex import el
 from reflex.components.component import Component
 from reflex.components.component import Component
 from reflex.components.core.match import Match
 from reflex.components.core.match import Match
 from reflex.components.lucide import Icon
 from reflex.components.lucide import Icon
+from reflex.style import Style
 from reflex.vars import Var
 from reflex.vars import Var
 from ..base import (
 from ..base import (
     LiteralAccentColor,
     LiteralAccentColor,
@@ -280,5 +281,6 @@ class IconButton(el.Button, RadixLoadingProp, RadixThemesComponent):
             The IconButton component.
             The IconButton component.
         """
         """
         ...
         ...
+    def add_style(self): ...
 
 
 icon_button = IconButton.create
 icon_button = IconButton.create

+ 8 - 3
reflex/components/radix/themes/layout/center.py

@@ -2,7 +2,7 @@
 
 
 from __future__ import annotations
 from __future__ import annotations
 
 
-from reflex.components.component import Component
+from reflex.style import Style
 
 
 from .flex import Flex
 from .flex import Flex
 
 
@@ -10,8 +10,13 @@ from .flex import Flex
 class Center(Flex):
 class Center(Flex):
     """A center component."""
     """A center component."""
 
 
-    def _apply_theme(self, theme: Component):
-        self.style.update(
+    def add_style(self) -> Style | None:
+        """Add style that center the content.
+
+        Returns:
+            The style of the component.
+        """
+        return Style(
             {
             {
                 "display": "flex",
                 "display": "flex",
                 "align_items": "center",
                 "align_items": "center",

+ 2 - 1
reflex/components/radix/themes/layout/center.pyi

@@ -7,10 +7,11 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
 from reflex.style import Style
-from reflex.components.component import Component
+from reflex.style import Style
 from .flex import Flex
 from .flex import Flex
 
 
 class Center(Flex):
 class Center(Flex):
+    def add_style(self) -> Style | None: ...
     @overload
     @overload
     @classmethod
     @classmethod
     def create(  # type: ignore
     def create(  # type: ignore

+ 8 - 3
reflex/components/radix/themes/layout/list.py

@@ -1,4 +1,5 @@
 """List components."""
 """List components."""
+from __future__ import annotations
 
 
 from typing import Iterable, Literal, Optional, Union
 from typing import Iterable, Literal, Optional, Union
 
 
@@ -77,12 +78,16 @@ class BaseList(Component):
             style["gap"] = props["gap"]
             style["gap"] = props["gap"]
         return super().create(*children, **props)
         return super().create(*children, **props)
 
 
-    def _apply_theme(self, theme: Component):
-        self.style = Style(
+    def add_style(self) -> Style | None:
+        """Add style to the component.
+
+        Returns:
+            The style of the component.
+        """
+        return Style(
             {
             {
                 "direction": "column",
                 "direction": "column",
                 "list_style_position": "inside",
                 "list_style_position": "inside",
-                **self.style,
             }
             }
         )
         )
 
 

+ 3 - 19
reflex/components/radix/themes/layout/list.pyi

@@ -157,6 +157,7 @@ class BaseList(Component):
 
 
         """
         """
         ...
         ...
+    def add_style(self) -> Style | None: ...
 
 
 class UnorderedList(BaseList, Ul):
 class UnorderedList(BaseList, Ul):
     @overload
     @overload
@@ -165,7 +166,7 @@ class UnorderedList(BaseList, Ul):
         cls,
         cls,
         *children,
         *children,
         items: Optional[Union[Var[Iterable], Iterable]] = None,
         items: Optional[Union[Var[Iterable], Iterable]] = None,
-        list_style_type: Optional[Literal["none", "disc", "circle", "square"]] = "disc",
+        list_style_type: Optional[LiteralListStyleTypeUnordered] = "disc",
         access_key: Optional[
         access_key: Optional[
             Union[Var[Union[str, int, bool]], Union[str, int, bool]]
             Union[Var[Union[str, int, bool]], Union[str, int, bool]]
         ] = None,
         ] = None,
@@ -302,24 +303,7 @@ class OrderedList(BaseList, Ol):
         cls,
         cls,
         *children,
         *children,
         items: Optional[Union[Var[Iterable], Iterable]] = None,
         items: Optional[Union[Var[Iterable], Iterable]] = None,
-        list_style_type: Optional[
-            Literal[
-                "none",
-                "decimal",
-                "decimal-leading-zero",
-                "lower-roman",
-                "upper-roman",
-                "lower-greek",
-                "lower-latin",
-                "upper-latin",
-                "armenian",
-                "georgian",
-                "lower-alpha",
-                "upper-alpha",
-                "hiragana",
-                "katakana",
-            ]
-        ] = "decimal",
+        list_style_type: Optional[LiteralListStyleTypeOrdered] = "decimal",
         reversed: Optional[
         reversed: Optional[
             Union[Var[Union[str, int, bool]], Union[str, int, bool]]
             Union[Var[Union[str, int, bool]], Union[str, int, bool]]
         ] = None,
         ] = None,

+ 8 - 3
reflex/components/radix/themes/layout/spacer.py

@@ -2,7 +2,7 @@
 
 
 from __future__ import annotations
 from __future__ import annotations
 
 
-from reflex.components.component import Component
+from reflex.style import Style
 
 
 from .flex import Flex
 from .flex import Flex
 
 
@@ -10,8 +10,13 @@ from .flex import Flex
 class Spacer(Flex):
 class Spacer(Flex):
     """A spacer component."""
     """A spacer component."""
 
 
-    def _apply_theme(self, theme: Component):
-        self.style.update(
+    def add_style(self) -> Style | None:
+        """Add style to the component.
+
+        Returns:
+            The style of the component.
+        """
+        return Style(
             {
             {
                 "flex": 1,
                 "flex": 1,
                 "justify_self": "stretch",
                 "justify_self": "stretch",

+ 2 - 1
reflex/components/radix/themes/layout/spacer.pyi

@@ -7,10 +7,11 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
 from reflex.style import Style
-from reflex.components.component import Component
+from reflex.style import Style
 from .flex import Flex
 from .flex import Flex
 
 
 class Spacer(Flex):
 class Spacer(Flex):
+    def add_style(self) -> Style | None: ...
     @overload
     @overload
     @classmethod
     @classmethod
     def create(  # type: ignore
     def create(  # type: ignore

+ 2 - 0
reflex/constants/colors.py

@@ -37,6 +37,8 @@ ColorType = Literal[
     "bronze",
     "bronze",
     "gray",
     "gray",
     "accent",
     "accent",
+    "black",
+    "white",
 ]
 ]
 
 
 ShadeType = Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
 ShadeType = Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

+ 24 - 6
reflex/experimental/layout.py

@@ -1,5 +1,7 @@
 """To experiment with layout component, move them to reflex/components later."""
 """To experiment with layout component, move them to reflex/components later."""
 
 
+from __future__ import annotations
+
 from reflex import color, cond
 from reflex import color, cond
 from reflex.components.base.fragment import Fragment
 from reflex.components.base.fragment import Fragment
 from reflex.components.component import Component, ComponentNamespace, MemoizationLeaf
 from reflex.components.component import Component, ComponentNamespace, MemoizationLeaf
@@ -9,6 +11,7 @@ from reflex.components.radix.themes.layout import Box, Container, HStack
 from reflex.event import call_script
 from reflex.event import call_script
 from reflex.experimental import hooks
 from reflex.experimental import hooks
 from reflex.state import ComponentState
 from reflex.state import ComponentState
+from reflex.style import Style
 from reflex.vars import Var
 from reflex.vars import Var
 
 
 
 
@@ -26,23 +29,38 @@ class Sidebar(Box, MemoizationLeaf):
         Returns:
         Returns:
             The sidebar component.
             The sidebar component.
         """
         """
-        props.setdefault("border_right", f"1px solid {color('accent', 12)}")
-        props.setdefault("background_color", color("accent", 1))
-        props.setdefault("width", "20vw")
-        props.setdefault("height", "100vh")
-        props.setdefault("position", "fixed")
+        # props.setdefault("border_right", f"1px solid {color('accent', 12)}")
+        # props.setdefault("background_color", color("accent", 1))
+        # props.setdefault("width", "20vw")
+        # props.setdefault("height", "100vh")
+        # props.setdefault("position", "fixed")
 
 
         return super().create(
         return super().create(
             Box.create(*children, **props),  # sidebar for content
             Box.create(*children, **props),  # sidebar for content
             Box.create(width=props.get("width")),  # spacer for layout
             Box.create(width=props.get("width")),  # spacer for layout
         )
         )
 
 
-    def _apply_theme(self, theme: Component | None):
+    def add_style(self) -> Style | None:
+        """Add style to the component.
+
+        Returns:
+            The style of the component.
+        """
         sidebar: Component = self.children[-2]  # type: ignore
         sidebar: Component = self.children[-2]  # type: ignore
         spacer: Component = self.children[-1]  # type: ignore
         spacer: Component = self.children[-1]  # type: ignore
         open = self.State.open if self.State else Var.create("open")  # type: ignore
         open = self.State.open if self.State else Var.create("open")  # type: ignore
         sidebar.style["display"] = spacer.style["display"] = cond(open, "block", "none")
         sidebar.style["display"] = spacer.style["display"] = cond(open, "block", "none")
 
 
+        return Style(
+            {
+                "position": "fixed",
+                "border_right": f"1px solid {color('accent', 12)}",
+                "background_color": color("accent", 1),
+                "width": "20vw",
+                "height": "100vh",
+            }
+        )
+
     def _get_hooks(self) -> Var | None:
     def _get_hooks(self) -> Var | None:
         return hooks.useState("open", "true") if not self.State else None
         return hooks.useState("open", "true") if not self.State else None
 
 

+ 6 - 1
reflex/style.py

@@ -159,12 +159,17 @@ def format_style_key(key: str) -> Tuple[str, ...]:
 class Style(dict):
 class Style(dict):
     """A style dictionary."""
     """A style dictionary."""
 
 
-    def __init__(self, style_dict: dict | None = None):
+    def __init__(self, style_dict: dict | None = None, **kwargs):
         """Initialize the style.
         """Initialize the style.
 
 
         Args:
         Args:
             style_dict: The style dictionary.
             style_dict: The style dictionary.
+            kwargs: Other key value pairs to apply to the dict update.
         """
         """
+        if style_dict:
+            style_dict.update(kwargs)
+        else:
+            style_dict = kwargs
         style_dict, self._var_data = convert(style_dict or {})
         style_dict, self._var_data = convert(style_dict or {})
         super().__init__(style_dict)
         super().__init__(style_dict)
 
 

+ 1 - 10
tests/components/core/test_foreach.py

@@ -2,7 +2,7 @@ from typing import Dict, List, Set, Tuple, Union
 
 
 import pytest
 import pytest
 
 
-from reflex.components import box, foreach, text, theme
+from reflex.components import box, foreach, text
 from reflex.components.core import Foreach
 from reflex.components.core import Foreach
 from reflex.state import BaseState
 from reflex.state import BaseState
 from reflex.vars import Var
 from reflex.vars import Var
@@ -220,15 +220,6 @@ def test_foreach_render(state_var, render_fn, render_dict):
     seen_index_vars.add(arg_index._var_name)
     seen_index_vars.add(arg_index._var_name)
 
 
 
 
-def test_foreach_apply_theme():
-    """Test that the foreach component applies the theme."""
-    tag = Foreach.create(ForEachState.colors_list, display_color)  # type: ignore
-    _theme = theme()
-    tag.apply_theme(_theme)
-    assert tag.theme == _theme
-    tag.render()
-
-
 def test_foreach_bad_annotations():
 def test_foreach_bad_annotations():
     """Test that the foreach component raises a TypeError if the iterable is of type Any."""
     """Test that the foreach component raises a TypeError if the iterable is of type Any."""
     with pytest.raises(TypeError):
     with pytest.raises(TypeError):

+ 3 - 4
tests/components/lucide/test_icon.py

@@ -1,7 +1,6 @@
 import pytest
 import pytest
 
 
 from reflex.components.lucide.icon import LUCIDE_ICON_LIST, RENAMED_ICONS_05, Icon
 from reflex.components.lucide.icon import LUCIDE_ICON_LIST, RENAMED_ICONS_05, Icon
-from reflex.components.radix.themes.base import Theme
 from reflex.utils import format
 from reflex.utils import format
 
 
 
 
@@ -17,7 +16,7 @@ RENAMED_TAGS = [tag for tag in RENAMED_ICONS_05.items()]
 @pytest.mark.parametrize("tag, new_tag", RENAMED_TAGS)
 @pytest.mark.parametrize("tag, new_tag", RENAMED_TAGS)
 def test_icon_renamed_tags(tag, new_tag):
 def test_icon_renamed_tags(tag, new_tag):
     Icon.create(tag)
     Icon.create(tag)
-    # need a PR so we can pass the following test. Currently it fails and uses the old tag as the import.
+    # TODO: need a PR so we can pass the following test. Currently it fails and uses the old tag as the import.
     # assert icon.alias == f"Lucide{format.to_title_case(new_tag)}Icon"
     # assert icon.alias == f"Lucide{format.to_title_case(new_tag)}Icon"
 
 
 
 
@@ -36,6 +35,6 @@ def test_icon_multiple_children():
         _ = Icon.create("activity", "child1", "child2")
         _ = Icon.create("activity", "child1", "child2")
 
 
 
 
-def test_icon_apply_theme():
+def test_icon_add_style():
     ic = Icon.create("activity")
     ic = Icon.create("activity")
-    ic._apply_theme(Theme())
+    assert ic.add_style() is None

+ 4 - 2
tests/components/radix/test_icon_button.py

@@ -1,19 +1,21 @@
 import pytest
 import pytest
 
 
 from reflex.components.lucide.icon import Icon
 from reflex.components.lucide.icon import Icon
-from reflex.components.radix.themes.base import Theme
 from reflex.components.radix.themes.components.icon_button import IconButton
 from reflex.components.radix.themes.components.icon_button import IconButton
+from reflex.style import Style
 from reflex.vars import Var
 from reflex.vars import Var
 
 
 
 
 def test_icon_button():
 def test_icon_button():
     ib1 = IconButton.create("activity")
     ib1 = IconButton.create("activity")
-    ib1._apply_theme(Theme.create())
     assert isinstance(ib1, IconButton)
     assert isinstance(ib1, IconButton)
 
 
     ib2 = IconButton.create(Icon.create("activity"))
     ib2 = IconButton.create(Icon.create("activity"))
     assert isinstance(ib2, IconButton)
     assert isinstance(ib2, IconButton)
 
 
+    assert isinstance(ib1.add_style(), Style)
+    assert isinstance(ib2.add_style(), Style)
+
 
 
 def test_icon_button_no_child():
 def test_icon_button_no_child():
     with pytest.raises(ValueError):
     with pytest.raises(ValueError):