"""Radix slider components.""" from __future__ import annotations from collections.abc import Sequence from typing import Any, Literal from reflex.components.component import Component, ComponentNamespace from reflex.components.radix.primitives.base import RadixPrimitiveComponentWithClassName from reflex.event import EventHandler from reflex.vars.base 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.3.4" def on_value_event_spec( value: Var[list[int]], ) -> tuple[Var[list[int]]]: """Event handler spec for the value event. Args: value: The value of the event. Returns: The event handler spec. """ return (value,) class SliderRoot(SliderComponent): """The Slider component containing all slider parts.""" tag = "Root" alias = "RadixSliderRoot" default_value: Var[Sequence[int]] value: Var[Sequence[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] # Fired when the value of a thumb changes. on_value_change: EventHandler[on_value_event_spec] # Fired when a thumb is released. on_value_commit: EventHandler[on_value_event_spec] def add_style(self) -> dict[str, Any] | None: """Add style to the component. Returns: The style of the component. """ return { "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", }, } class SliderTrack(SliderComponent): """A Slider Track component.""" tag = "Track" alias = "RadixSliderTrack" def add_style(self) -> dict[str, Any] | None: """Add style to the component. Returns: The style of the component. """ return { "position": "relative", "flex_grow": "1", "background_color": "black", "border_radius": "9999px", "height": "3px", "&[data-orientation='vertical']": {"width": "3px"}, } class SliderRange(SliderComponent): """A SliderRange component.""" tag = "Range" alias = "RadixSliderRange" def add_style(self) -> dict[str, Any] | None: """Add style to the component. Returns: The style of the component. """ return { "position": "absolute", "background_color": "white", "height": "100%", "&[data-orientation='vertical']": {"width": "100%"}, } class SliderThumb(SliderComponent): """A SliderThumb component.""" tag = "Thumb" alias = "RadixSliderThumb" def add_style(self) -> dict[str, Any] | None: """Add style to the component. Returns: The style of the component. """ return { "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", }, } 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 # noqa: ERA001 ] return SliderRoot.create(*children, **props) slider = Slider()