186 lines
4.9 KiB
Python
186 lines
4.9 KiB
Python
"""Radix slider components."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any, Dict, List, Literal
|
|
|
|
from reflex.components.component import Component, ComponentNamespace
|
|
from reflex.components.radix.primitives.base import RadixPrimitiveComponentWithClassName
|
|
from reflex.style import Style
|
|
from reflex.vars import Var
|
|
|
|
LiteralSliderOrientation = Literal["horizontal", "vertical"]
|
|
LiteralSliderDir = Literal["ltr", "rtl"]
|
|
|
|
|
|
class SliderComponent(RadixPrimitiveComponentWithClassName):
|
|
"""Base class for all @radix-ui/react-slider components."""
|
|
|
|
library = "@radix-ui/react-slider@^1.1.2"
|
|
|
|
|
|
class SliderRoot(SliderComponent):
|
|
"""The Slider component comtaining all slider parts."""
|
|
|
|
tag = "Root"
|
|
alias = "RadixSliderRoot"
|
|
|
|
default_value: Var[List[int]]
|
|
|
|
value: Var[List[int]]
|
|
|
|
name: Var[str]
|
|
|
|
disabled: Var[bool]
|
|
|
|
orientation: Var[LiteralSliderOrientation]
|
|
|
|
dir: Var[LiteralSliderDir]
|
|
|
|
inverted: Var[bool]
|
|
|
|
min: Var[int]
|
|
|
|
max: Var[int]
|
|
|
|
step: Var[int]
|
|
|
|
min_steps_between_thumbs: Var[int]
|
|
|
|
def get_event_triggers(self) -> Dict[str, Any]:
|
|
"""Event triggers for radix slider primitive.
|
|
|
|
Returns:
|
|
The triggers for event supported by radix primitives.
|
|
"""
|
|
return {
|
|
**super().get_event_triggers(),
|
|
"on_value_change": lambda e0: [e0], # trigger for all change of a thumb
|
|
"on_value_commit": lambda e0: [e0], # trigger when thumb is released
|
|
}
|
|
|
|
def _apply_theme(self, theme: Component):
|
|
self.style = Style(
|
|
{
|
|
"position": "relative",
|
|
"display": "flex",
|
|
"align_items": "center",
|
|
"user_select": "none",
|
|
"touch_action": "none",
|
|
"width": "200px",
|
|
"height": "20px",
|
|
"&[data-orientation='vertical']": {
|
|
"flex_direction": "column",
|
|
"width": "20px",
|
|
"height": "100px",
|
|
},
|
|
**self.style,
|
|
}
|
|
)
|
|
|
|
|
|
class SliderTrack(SliderComponent):
|
|
"""A Slider Track component."""
|
|
|
|
tag = "Track"
|
|
alias = "RadixSliderTrack"
|
|
|
|
def _apply_theme(self, theme: Component):
|
|
self.style = Style(
|
|
{
|
|
"position": "relative",
|
|
"flex_grow": "1",
|
|
"background_color": "black",
|
|
"border_radius": "9999px",
|
|
"height": "3px",
|
|
"&[data-orientation='vertical']": {
|
|
"width": "3px",
|
|
},
|
|
**self.style,
|
|
}
|
|
)
|
|
|
|
|
|
class SliderRange(SliderComponent):
|
|
"""A SliderRange component."""
|
|
|
|
tag = "Range"
|
|
alias = "RadixSliderRange"
|
|
|
|
def _apply_theme(self, theme: Component):
|
|
self.style = Style(
|
|
{
|
|
"position": "absolute",
|
|
"background_color": "white",
|
|
"height": "100%",
|
|
"&[data-orientation='vertical']": {
|
|
"width": "100%",
|
|
},
|
|
**self.style,
|
|
}
|
|
)
|
|
|
|
|
|
class SliderThumb(SliderComponent):
|
|
"""A SliderThumb component."""
|
|
|
|
tag = "Thumb"
|
|
alias = "RadixSliderThumb"
|
|
|
|
def _apply_theme(self, theme: Component):
|
|
self.style = Style(
|
|
{
|
|
"display": "block",
|
|
"width": "20px",
|
|
"height": "20px",
|
|
"background_color": "black",
|
|
"box_shadow": "0 2px 10px black",
|
|
"border_radius": "10px",
|
|
"&:hover": {
|
|
"background_color": "gray",
|
|
},
|
|
"&:focus": {
|
|
"outline": "none",
|
|
"box_shadow": "0 0 0 4px gray",
|
|
},
|
|
**self.style,
|
|
}
|
|
)
|
|
|
|
|
|
class Slider(ComponentNamespace):
|
|
"""High level API for slider."""
|
|
|
|
root = staticmethod(SliderRoot.create)
|
|
track = staticmethod(SliderTrack.create)
|
|
range = staticmethod(SliderRange.create)
|
|
thumb = staticmethod(SliderThumb.create)
|
|
|
|
@staticmethod
|
|
def __call__(**props) -> Component:
|
|
"""High level API for slider.
|
|
|
|
Args:
|
|
**props: The props of the slider.
|
|
|
|
Returns:
|
|
A slider component.
|
|
"""
|
|
track = SliderTrack.create(SliderRange.create())
|
|
# if default_value is not set, the thumbs will not render properly but the slider will still work
|
|
if "default_value" in props:
|
|
children = [
|
|
track,
|
|
*[SliderThumb.create() for _ in props.get("default_value", [])],
|
|
]
|
|
else:
|
|
children = [
|
|
track,
|
|
# Foreach.create(props.get("value"), lambda e: SliderThumb.create()), # foreach doesn't render Thumbs properly
|
|
]
|
|
|
|
return SliderRoot.create(*children, **props)
|
|
|
|
|
|
slider = Slider()
|