소스 검색

[REF-2087] Better rx.progress styling integration with radix themes (#2762)

* [REF-2087] Better rx.progress styling integration with radix themes

Support the `radius` prop on `ProgressRoot`, via data-radius and CSS tokens

Support the `color_scheme` on `ProgressIndicator`, via data-accent-color and CSS token

Move high-level `Progress` to a real `Component` subclass to get better pyi hinting

Allow overriding the background color of the `ProgressIndicator` via low-level api

Remove `value` and `max` props from `ProgressRoot` (these only apply to `ProgressIndicator`)

* Progress: do not pass `value` or `max` to ProgressRoot

* progress: use background_color instead of background-color
Masen Furer 1 년 전
부모
커밋
75b63cbc25
2개의 변경된 파일348개의 추가작업 그리고 54개의 파일을 삭제
  1. 42 43
      reflex/components/radix/primitives/progress.py
  2. 306 11
      reflex/components/radix/primitives/progress.pyi

+ 42 - 43
reflex/components/radix/primitives/progress.py

@@ -2,13 +2,13 @@
 
 
 from __future__ import annotations
 from __future__ import annotations
 
 
-from typing import Optional, Union
+from typing import Optional
 
 
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.core.colors import color
 from reflex.components.core.colors import color
 from reflex.components.radix.primitives.accordion import DEFAULT_ANIMATION_DURATION
 from reflex.components.radix.primitives.accordion import DEFAULT_ANIMATION_DURATION
 from reflex.components.radix.primitives.base import RadixPrimitiveComponentWithClassName
 from reflex.components.radix.primitives.base import RadixPrimitiveComponentWithClassName
-from reflex.components.radix.themes.base import LiteralAccentColor
+from reflex.components.radix.themes.base import LiteralAccentColor, LiteralRadius
 from reflex.style import Style
 from reflex.style import Style
 from reflex.vars import Var
 from reflex.vars import Var
 
 
@@ -25,19 +25,19 @@ class ProgressRoot(ProgressComponent):
     tag = "Root"
     tag = "Root"
     alias = "RadixProgressRoot"
     alias = "RadixProgressRoot"
 
 
-    # The current progress value.
-    value: Var[Optional[int]]
-
-    # The maximum progress value.
-    max: Var[int]
+    # Override theme radius for progress bar: "none" | "small" | "medium" | "large" | "full"
+    radius: Var[LiteralRadius]
 
 
     def _apply_theme(self, theme: Component):
     def _apply_theme(self, theme: Component):
+        if self.radius is not None:
+            self.custom_attrs["data-radius"] = self.radius
+
         self.style = Style(
         self.style = Style(
             {
             {
                 "position": "relative",
                 "position": "relative",
                 "overflow": "hidden",
                 "overflow": "hidden",
                 "background": "var(--gray-a3)",
                 "background": "var(--gray-a3)",
-                "border_radius": "99999px",
+                "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)",
                 "boxShadow": "inset 0 0 0 1px var(--gray-a5)",
@@ -45,6 +45,9 @@ class ProgressRoot(ProgressComponent):
             }
             }
         )
         )
 
 
+    def _exclude_props(self) -> list[str]:
+        return ["radius"]
+
 
 
 class ProgressIndicator(ProgressComponent):
 class ProgressIndicator(ProgressComponent):
     """The Progress bar indicator."""
     """The Progress bar indicator."""
@@ -63,22 +66,12 @@ class ProgressIndicator(ProgressComponent):
     color_scheme: Var[LiteralAccentColor]
     color_scheme: Var[LiteralAccentColor]
 
 
     def _apply_theme(self, theme: Component):
     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 progress indicator "
-                "component or set the `accent_color` prop in your global theme."
-            )
-
-        color_scheme = color(
-            self.color_scheme if self.color_scheme is not None else global_color_scheme,  # type: ignore
-            9,
-        )
+        if self.color_scheme is not None:
+            self.custom_attrs["data-accent-color"] = self.color_scheme
 
 
         self.style = Style(
         self.style = Style(
             {
             {
-                "background-color": color_scheme,
+                "background_color": color("accent", 9),
                 "width": "100%",
                 "width": "100%",
                 "height": "100%",
                 "height": "100%",
                 f"transition": f"transform {DEFAULT_ANIMATION_DURATION}ms linear",
                 f"transition": f"transform {DEFAULT_ANIMATION_DURATION}ms linear",
@@ -87,6 +80,7 @@ class ProgressIndicator(ProgressComponent):
                 },
                 },
                 "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,
             }
             }
         )
         )
 
 
@@ -94,43 +88,48 @@ class ProgressIndicator(ProgressComponent):
         return ["color_scheme"]
         return ["color_scheme"]
 
 
 
 
-class Progress(ComponentNamespace):
-    """High-level API for progress bar."""
+class Progress(ProgressRoot):
+    """The high-level Progress component."""
 
 
-    root = staticmethod(ProgressRoot.create)
-    indicator = staticmethod(ProgressIndicator.create)
+    # Override theme color for progress bar indicator
+    color_scheme: Var[LiteralAccentColor]
 
 
-    @staticmethod
-    def __call__(
-        width: Optional[str] = "100%",
-        color_scheme: Optional[Union[Var, LiteralAccentColor]] = None,
-        **props,
-    ) -> Component:
+    # The current progress value.
+    value: Var[Optional[int]]
+
+    # The maximum progress value.
+    max: Var[Optional[int]]
+
+    @classmethod
+    def create(cls, **props) -> Component:
         """High-level API for progress bar.
         """High-level API for progress bar.
 
 
         Args:
         Args:
-            width: The width of the progress bar.
             **props: The props of the progress bar.
             **props: The props of the progress bar.
-            color_scheme: The color scheme of the progress indicator.
 
 
         Returns:
         Returns:
             The progress bar.
             The progress bar.
         """
         """
-        style = props.setdefault("style", {})
-        style.update({"width": width})
-
-        progress_indicator_props = (
-            {"color_scheme": color_scheme} if color_scheme is not None else {}
-        )
+        progress_indicator_props = {}
+        if "color_scheme" in props:
+            progress_indicator_props["color_scheme"] = props.pop("color_scheme")
 
 
         return ProgressRoot.create(
         return ProgressRoot.create(
             ProgressIndicator.create(
             ProgressIndicator.create(
-                value=props.get("value"),
-                max=props.get("max", 100),
-                **progress_indicator_props,  # type: ignore
+                value=props.pop("value", 0),
+                max=props.pop("max", 100),
+                **progress_indicator_props,
             ),
             ),
             **props,
             **props,
         )
         )
 
 
 
 
-progress = Progress()
+class ProgressNamespace(ComponentNamespace):
+    """High-level API for progress bar."""
+
+    root = staticmethod(ProgressRoot.create)
+    indicator = staticmethod(ProgressIndicator.create)
+    __call__ = staticmethod(Progress.create)
+
+
+progress = ProgressNamespace()

+ 306 - 11
reflex/components/radix/primitives/progress.pyi

@@ -7,12 +7,12 @@ 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 typing import Optional, Union
+from typing import Optional
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.component import Component, ComponentNamespace
 from reflex.components.core.colors import color
 from reflex.components.core.colors import color
 from reflex.components.radix.primitives.accordion import DEFAULT_ANIMATION_DURATION
 from reflex.components.radix.primitives.accordion import DEFAULT_ANIMATION_DURATION
 from reflex.components.radix.primitives.base import RadixPrimitiveComponentWithClassName
 from reflex.components.radix.primitives.base import RadixPrimitiveComponentWithClassName
-from reflex.components.radix.themes.base import LiteralAccentColor
+from reflex.components.radix.themes.base import LiteralAccentColor, LiteralRadius
 from reflex.style import Style
 from reflex.style import Style
 from reflex.vars import Var
 from reflex.vars import Var
 
 
@@ -103,8 +103,12 @@ class ProgressRoot(ProgressComponent):
     def create(  # type: ignore
     def create(  # type: ignore
         cls,
         cls,
         *children,
         *children,
-        value: Optional[Union[Var[Optional[int]], Optional[int]]] = None,
-        max: Optional[Union[Var[int], int]] = None,
+        radius: Optional[
+            Union[
+                Var[Literal["none", "small", "medium", "large", "full"]],
+                Literal["none", "small", "medium", "large", "full"],
+            ]
+        ] = 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,
@@ -163,8 +167,7 @@ class ProgressRoot(ProgressComponent):
 
 
         Args:
         Args:
             *children: The children of the component.
             *children: The children of the component.
-            value: The current progress value.
-            max: The maximum progress value.
+            radius: Override theme radius for progress bar: "none" | "small" | "medium" | "large" | "full"
             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.
@@ -330,15 +333,307 @@ class ProgressIndicator(ProgressComponent):
         """
         """
         ...
         ...
 
 
-class Progress(ComponentNamespace):
+class Progress(ProgressRoot):
+    @overload
+    @classmethod
+    def create(  # type: ignore
+        cls,
+        *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,
+        value: Optional[Union[Var[Optional[int]], Optional[int]]] = None,
+        max: Optional[Union[Var[Optional[int]], Optional[int]]] = None,
+        radius: Optional[
+            Union[
+                Var[Literal["none", "small", "medium", "large", "full"]],
+                Literal["none", "small", "medium", "large", "full"],
+            ]
+        ] = None,
+        as_child: Optional[Union[Var[bool], bool]] = None,
+        style: Optional[Style] = None,
+        key: Optional[Any] = None,
+        id: Optional[Any] = None,
+        class_name: Optional[Any] = None,
+        autofocus: Optional[bool] = None,
+        custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
+        on_blur: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_click: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_context_menu: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_double_click: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_focus: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_mount: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_mouse_down: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_mouse_enter: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_mouse_leave: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_mouse_move: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_mouse_out: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_mouse_over: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_mouse_up: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_scroll: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_unmount: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        **props
+    ) -> "Progress":
+        """High-level API for progress bar.
+
+        Args:
+            color_scheme: Override theme color for progress bar indicator
+            value: The current progress value.
+            max: The maximum progress value.
+            radius: Override theme radius for progress bar: "none" | "small" | "medium" | "large" | "full"
+            as_child: Change the default rendered element for the one passed as a child.
+            style: The style of the component.
+            key: A unique key for the component.
+            id: The id for the component.
+            class_name: The class name for the component.
+            autofocus: Whether the component should take the focus once the page is loaded
+            custom_attrs: custom attribute
+            **props: The props of the progress bar.
+
+        Returns:
+            The progress bar.
+        """
+        ...
+
+class ProgressNamespace(ComponentNamespace):
     root = staticmethod(ProgressRoot.create)
     root = staticmethod(ProgressRoot.create)
     indicator = staticmethod(ProgressIndicator.create)
     indicator = staticmethod(ProgressIndicator.create)
 
 
     @staticmethod
     @staticmethod
     def __call__(
     def __call__(
-        width: Optional[str] = "100%",
-        color_scheme: Optional[Union[Var, LiteralAccentColor]] = None,
+        *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,
+        value: Optional[Union[Var[Optional[int]], Optional[int]]] = None,
+        max: Optional[Union[Var[Optional[int]], Optional[int]]] = None,
+        radius: Optional[
+            Union[
+                Var[Literal["none", "small", "medium", "large", "full"]],
+                Literal["none", "small", "medium", "large", "full"],
+            ]
+        ] = None,
+        as_child: Optional[Union[Var[bool], bool]] = None,
+        style: Optional[Style] = None,
+        key: Optional[Any] = None,
+        id: Optional[Any] = None,
+        class_name: Optional[Any] = None,
+        autofocus: Optional[bool] = None,
+        custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
+        on_blur: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_click: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_context_menu: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_double_click: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_focus: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_mount: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_mouse_down: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_mouse_enter: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_mouse_leave: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_mouse_move: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_mouse_out: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_mouse_over: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_mouse_up: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_scroll: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
+        on_unmount: Optional[
+            Union[EventHandler, EventSpec, list, function, BaseVar]
+        ] = None,
         **props
         **props
-    ) -> Component: ...
+    ) -> "Progress":
+        """High-level API for progress bar.
+
+        Args:
+            color_scheme: Override theme color for progress bar indicator
+            value: The current progress value.
+            max: The maximum progress value.
+            radius: Override theme radius for progress bar: "none" | "small" | "medium" | "large" | "full"
+            as_child: Change the default rendered element for the one passed as a child.
+            style: The style of the component.
+            key: A unique key for the component.
+            id: The id for the component.
+            class_name: The class name for the component.
+            autofocus: Whether the component should take the focus once the page is loaded
+            custom_attrs: custom attribute
+            **props: The props of the progress bar.
+
+        Returns:
+            The progress bar.
+        """
+        ...
 
 
-progress = Progress()
+progress = ProgressNamespace()