progress.py 2.9 KB

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