progress.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. """Progress."""
  2. from __future__ import annotations
  3. from types import SimpleNamespace
  4. from typing import Optional
  5. from reflex.components.component import Component
  6. from reflex.components.radix.primitives.accordion import DEFAULT_ANIMATION_DURATION
  7. from reflex.components.radix.primitives.base import RadixPrimitiveComponentWithClassName
  8. from reflex.style import Style
  9. from reflex.vars import Var
  10. class ProgressComponent(RadixPrimitiveComponentWithClassName):
  11. """A Progress component."""
  12. library = "@radix-ui/react-progress@^1.0.3"
  13. class ProgressRoot(ProgressComponent):
  14. """The Progress Root component."""
  15. tag = "Root"
  16. alias = "RadixProgressRoot"
  17. # The current progress value.
  18. value: Var[Optional[int]]
  19. # The maximum progress value.
  20. max: Var[int]
  21. def _apply_theme(self, theme: Component):
  22. self.style = Style(
  23. {
  24. "position": "relative",
  25. "overflow": "hidden",
  26. "background": "var(--gray-a3)",
  27. "border_radius": "99999px",
  28. "width": "100%",
  29. "height": "20px",
  30. "boxShadow": "inset 0 0 0 1px var(--gray-a5)",
  31. **self.style,
  32. }
  33. )
  34. class ProgressIndicator(ProgressComponent):
  35. """The Progress bar indicator."""
  36. tag = "Indicator"
  37. alias = "RadixProgressIndicator"
  38. # The current progress value.
  39. value: Var[Optional[int]]
  40. # The maximum progress value.
  41. max: Var[Optional[int]]
  42. def _apply_theme(self, theme: Component):
  43. self.style = Style(
  44. {
  45. "background-color": "var(--accent-9)",
  46. "width": "100%",
  47. "height": "100%",
  48. f"transition": f"transform {DEFAULT_ANIMATION_DURATION}ms linear",
  49. "&[data_state='loading']": {
  50. "transition": f"transform {DEFAULT_ANIMATION_DURATION}ms linear",
  51. },
  52. "transform": f"translateX(calc(-100% + ({self.value} / {self.max} * 100%)))", # type: ignore
  53. "boxShadow": "inset 0 0 0 1px var(--gray-a5)",
  54. }
  55. )
  56. class Progress(SimpleNamespace):
  57. """High level API for progress bar."""
  58. root = staticmethod(ProgressRoot.create)
  59. indicator = staticmethod(ProgressIndicator.create)
  60. @staticmethod
  61. def __call__(width: Optional[str] = "100%", **props) -> Component:
  62. """High level API for progress bar.
  63. Args:
  64. width: The width of the progerss bar
  65. **props: The props of the progress bar
  66. Returns:
  67. The progress bar.
  68. """
  69. style = props.setdefault("style", {})
  70. style.update({"width": width})
  71. return ProgressRoot.create(
  72. ProgressIndicator.create(
  73. value=props.get("value"), max=props.get("max", 100)
  74. ),
  75. **props,
  76. )
  77. progress = Progress()