rangeslider.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. """A range slider component."""
  2. from __future__ import annotations
  3. from typing import Any, List, Optional, Union
  4. from reflex.components.chakra import ChakraComponent, LiteralChakraDirection
  5. from reflex.components.component import Component
  6. from reflex.constants import EventTriggers
  7. from reflex.utils import format
  8. from reflex.vars import Var
  9. class RangeSlider(ChakraComponent):
  10. """The RangeSlider is a multi thumb slider used to select a range of related values. A common use-case of this component is a price range picker that allows a user to set the minimum and maximum price."""
  11. tag = "RangeSlider"
  12. # State var to bind the the input.
  13. value: Var[List[int]]
  14. # The default values.
  15. default_value: Var[List[int]]
  16. # The writing mode ("ltr" | "rtl")
  17. direction: Var[LiteralChakraDirection]
  18. # If false, the slider handle will not capture focus when value changes.
  19. focus_thumb_on_change: Var[bool]
  20. # If true, the slider will be disabled
  21. is_disabled: Var[bool]
  22. # If true, the slider will be in `read-only` state.
  23. is_read_only: Var[bool]
  24. # If true, the value will be incremented or decremented in reverse.
  25. is_reversed: Var[bool]
  26. # The minimum value of the slider.
  27. min_: Var[int]
  28. # The maximum value of the slider.
  29. max_: Var[int]
  30. # The minimum distance between slider thumbs. Useful for preventing the thumbs from being too close together.
  31. min_steps_between_thumbs: Var[int]
  32. # The name of the form field
  33. name: Var[str]
  34. def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
  35. """Get the event triggers that pass the component's value to the handler.
  36. Returns:
  37. A dict mapping the event trigger to the var that is passed to the handler.
  38. """
  39. return {
  40. **super().get_event_triggers(),
  41. EventTriggers.ON_CHANGE: lambda e0: [e0],
  42. EventTriggers.ON_CHANGE_END: lambda e0: [e0],
  43. EventTriggers.ON_CHANGE_START: lambda e0: [e0],
  44. }
  45. def get_ref(self):
  46. """Get the ref of the component.
  47. Returns:
  48. The ref of the component.
  49. """
  50. return None
  51. def _get_ref_hook(self) -> Optional[str]:
  52. """Override the base _get_ref_hook to handle array refs.
  53. Returns:
  54. The overrided hooks.
  55. """
  56. if self.id:
  57. ref = format.format_array_ref(self.id, None)
  58. if ref:
  59. return (
  60. f"const {ref} = Array.from({{length:2}}, () => useRef(null)); "
  61. f"{str(Var.create_safe(ref).as_ref())} = {ref}"
  62. )
  63. return super()._get_ref_hook()
  64. @classmethod
  65. def create(cls, *children, **props) -> Component:
  66. """Create a RangeSlider component.
  67. If no children are provided, a default RangeSlider will be created.
  68. Args:
  69. *children: The children of the component.
  70. **props: The properties of the component.
  71. Returns:
  72. The RangeSlider component.
  73. """
  74. if len(children) == 0:
  75. _id = props.get("id", None)
  76. if _id:
  77. children = [
  78. RangeSliderTrack.create(
  79. RangeSliderFilledTrack.create(),
  80. ),
  81. RangeSliderThumb.create(index=0, id=_id),
  82. RangeSliderThumb.create(index=1, id=_id),
  83. ]
  84. else:
  85. children = [
  86. RangeSliderTrack.create(
  87. RangeSliderFilledTrack.create(),
  88. ),
  89. RangeSliderThumb.create(index=0),
  90. RangeSliderThumb.create(index=1),
  91. ]
  92. return super().create(*children, **props)
  93. class RangeSliderTrack(ChakraComponent):
  94. """A range slider track."""
  95. tag = "RangeSliderTrack"
  96. class RangeSliderFilledTrack(ChakraComponent):
  97. """A filled range slider track."""
  98. tag = "RangeSliderFilledTrack"
  99. class RangeSliderThumb(ChakraComponent):
  100. """A range slider thumb."""
  101. tag = "RangeSliderThumb"
  102. # The position of the thumb.
  103. index: Var[int]
  104. def _get_ref_hook(self) -> Optional[str]:
  105. # hook is None because RangeSlider is handling it.
  106. return None
  107. def get_ref(self):
  108. """Get an array ref for the range slider thumb.
  109. Returns:
  110. The array ref.
  111. """
  112. if self.id:
  113. return format.format_array_ref(self.id, self.index)