progress.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. """Progress."""
  2. from __future__ import annotations
  3. from typing import Optional
  4. from reflex.components.component import Component, ComponentNamespace
  5. from reflex.components.core.colors import color
  6. from reflex.components.radix.primitives.accordion import DEFAULT_ANIMATION_DURATION
  7. from reflex.components.radix.primitives.base import RadixPrimitiveComponentWithClassName
  8. from reflex.components.radix.themes.base import LiteralAccentColor, LiteralRadius
  9. from reflex.style import Style
  10. from reflex.vars import Var
  11. class ProgressComponent(RadixPrimitiveComponentWithClassName):
  12. """A Progress component."""
  13. library = "@radix-ui/react-progress@^1.0.3"
  14. class ProgressRoot(ProgressComponent):
  15. """The Progress Root component."""
  16. tag = "Root"
  17. alias = "RadixProgressRoot"
  18. # Override theme radius for progress bar: "none" | "small" | "medium" | "large" | "full"
  19. radius: Optional[Var[LiteralRadius]] = None
  20. def _apply_theme(self, theme: Component):
  21. if self.radius is not None:
  22. self.custom_attrs["data-radius"] = self.radius
  23. self.style = Style(
  24. {
  25. "position": "relative",
  26. "overflow": "hidden",
  27. "background": "var(--gray-a3)",
  28. "border_radius": "max(var(--radius-2), var(--radius-full))",
  29. "width": "100%",
  30. "height": "20px",
  31. "boxShadow": "inset 0 0 0 1px var(--gray-a5)",
  32. **self.style,
  33. }
  34. )
  35. def _exclude_props(self) -> list[str]:
  36. return ["radius"]
  37. class ProgressIndicator(ProgressComponent):
  38. """The Progress bar indicator."""
  39. tag = "Indicator"
  40. alias = "RadixProgressIndicator"
  41. # The current progress value.
  42. value: Optional[Var[Optional[int]]] = None
  43. # The maximum progress value.
  44. max: Optional[Var[Optional[int]]] = None
  45. # The color scheme of the progress indicator.
  46. color_scheme: Optional[Var[LiteralAccentColor]] = None
  47. def _apply_theme(self, theme: Component):
  48. if self.color_scheme is not None:
  49. self.custom_attrs["data-accent-color"] = self.color_scheme
  50. self.style = Style(
  51. {
  52. "background_color": color("accent", 9),
  53. "width": "100%",
  54. "height": "100%",
  55. f"transition": f"transform {DEFAULT_ANIMATION_DURATION}ms linear",
  56. "&[data_state='loading']": {
  57. "transition": f"transform {DEFAULT_ANIMATION_DURATION}ms linear",
  58. },
  59. "transform": f"translateX(calc(-100% + ({self.value} / {self.max} * 100%)))", # type: ignore
  60. "boxShadow": "inset 0 0 0 1px var(--gray-a5)",
  61. **self.style,
  62. }
  63. )
  64. def _exclude_props(self) -> list[str]:
  65. return ["color_scheme"]
  66. class Progress(ProgressRoot):
  67. """The high-level Progress component."""
  68. # Override theme color for progress bar indicator
  69. color_scheme: Optional[Var[LiteralAccentColor]] = None
  70. # The current progress value.
  71. value: Optional[Var[Optional[int]]] = None
  72. # The maximum progress value.
  73. max: Optional[Var[Optional[int]]] = None
  74. @classmethod
  75. def create(cls, **props) -> Component:
  76. """High-level API for progress bar.
  77. Args:
  78. **props: The props of the progress bar.
  79. Returns:
  80. The progress bar.
  81. """
  82. progress_indicator_props = {}
  83. if "color_scheme" in props:
  84. progress_indicator_props["color_scheme"] = props.pop("color_scheme")
  85. return ProgressRoot.create(
  86. ProgressIndicator.create(
  87. value=props.pop("value", 0),
  88. max=props.pop("max", 100),
  89. **progress_indicator_props,
  90. ),
  91. **props,
  92. )
  93. class ProgressNamespace(ComponentNamespace):
  94. """High-level API for progress bar."""
  95. root = staticmethod(ProgressRoot.create)
  96. indicator = staticmethod(ProgressIndicator.create)
  97. __call__ = staticmethod(Progress.create)
  98. progress = ProgressNamespace()