[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
This commit is contained in:
parent
e4c32e3edf
commit
75b63cbc25
@ -2,13 +2,13 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Optional, Union
|
||||
from typing import Optional
|
||||
|
||||
from reflex.components.component import Component, ComponentNamespace
|
||||
from reflex.components.core.colors import color
|
||||
from reflex.components.radix.primitives.accordion import DEFAULT_ANIMATION_DURATION
|
||||
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.vars import Var
|
||||
|
||||
@ -25,19 +25,19 @@ class ProgressRoot(ProgressComponent):
|
||||
tag = "Root"
|
||||
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):
|
||||
if self.radius is not None:
|
||||
self.custom_attrs["data-radius"] = self.radius
|
||||
|
||||
self.style = Style(
|
||||
{
|
||||
"position": "relative",
|
||||
"overflow": "hidden",
|
||||
"background": "var(--gray-a3)",
|
||||
"border_radius": "99999px",
|
||||
"border_radius": "max(var(--radius-2), var(--radius-full))",
|
||||
"width": "100%",
|
||||
"height": "20px",
|
||||
"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):
|
||||
"""The Progress bar indicator."""
|
||||
@ -63,22 +66,12 @@ class ProgressIndicator(ProgressComponent):
|
||||
color_scheme: Var[LiteralAccentColor]
|
||||
|
||||
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(
|
||||
{
|
||||
"background-color": color_scheme,
|
||||
"background_color": color("accent", 9),
|
||||
"width": "100%",
|
||||
"height": "100%",
|
||||
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
|
||||
"boxShadow": "inset 0 0 0 1px var(--gray-a5)",
|
||||
**self.style,
|
||||
}
|
||||
)
|
||||
|
||||
@ -94,43 +88,48 @@ class ProgressIndicator(ProgressComponent):
|
||||
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.
|
||||
|
||||
Args:
|
||||
width: The width of the progress bar.
|
||||
**props: The props of the progress bar.
|
||||
color_scheme: The color scheme of the progress indicator.
|
||||
|
||||
Returns:
|
||||
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(
|
||||
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,
|
||||
)
|
||||
|
||||
|
||||
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()
|
||||
|
@ -7,12 +7,12 @@ from typing import Any, Dict, Literal, Optional, Union, overload
|
||||
from reflex.vars import Var, BaseVar, ComputedVar
|
||||
from reflex.event import EventChain, EventHandler, EventSpec
|
||||
from reflex.style import Style
|
||||
from typing import Optional, Union
|
||||
from typing import Optional
|
||||
from reflex.components.component import Component, ComponentNamespace
|
||||
from reflex.components.core.colors import color
|
||||
from reflex.components.radix.primitives.accordion import DEFAULT_ANIMATION_DURATION
|
||||
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.vars import Var
|
||||
|
||||
@ -103,8 +103,12 @@ class ProgressRoot(ProgressComponent):
|
||||
def create( # type: ignore
|
||||
cls,
|
||||
*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,
|
||||
style: Optional[Style] = None,
|
||||
key: Optional[Any] = None,
|
||||
@ -163,8 +167,7 @@ class ProgressRoot(ProgressComponent):
|
||||
|
||||
Args:
|
||||
*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.
|
||||
style: The style of 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)
|
||||
indicator = staticmethod(ProgressIndicator.create)
|
||||
|
||||
@staticmethod
|
||||
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
|
||||
) -> Component: ...
|
||||
) -> "Progress":
|
||||
"""High-level API for progress bar.
|
||||
|
||||
progress = Progress()
|
||||
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 = ProgressNamespace()
|
||||
|
Loading…
Reference in New Issue
Block a user