diff --git a/reflex/components/radix/themes/components/__init__.py b/reflex/components/radix/themes/components/__init__.py index 2a088f3bd..794dee274 100644 --- a/reflex/components/radix/themes/components/__init__.py +++ b/reflex/components/radix/themes/components/__init__.py @@ -52,6 +52,7 @@ from .popover import PopoverClose, PopoverContent, PopoverRoot, PopoverTrigger from .radiogroup import RadioGroupItem, RadioGroupRoot from .scrollarea import ScrollArea from .select import ( + HighLevelSelect, SelectContent, SelectGroup, SelectItem, @@ -174,6 +175,7 @@ select_item = SelectItem.create select_separator = SelectSeparator.create select_group = SelectGroup.create select_label = SelectLabel.create +select = HighLevelSelect.create # Separator separator = Separator.create diff --git a/reflex/components/radix/themes/components/select.py b/reflex/components/radix/themes/components/select.py index e62c76a12..432d15cfd 100644 --- a/reflex/components/radix/themes/components/select.py +++ b/reflex/components/radix/themes/components/select.py @@ -1,6 +1,8 @@ """Interactive components provided by @radix-ui/themes.""" -from typing import Any, Dict, Literal +from typing import Any, Dict, List, Literal, Union +import reflex as rx +from reflex.components.component import Component from reflex.vars import Var from ..base import ( @@ -144,3 +146,81 @@ class SelectSeparator(CommonMarginProps, RadixThemesComponent): """Trigger an action or event, such as submitting a form or displaying a dialog.""" tag = "Select.Separator" + + +class HighLevelSelect(SelectRoot): + """High level wrapper for the Select component.""" + + # The items of the select. + items: Var[List[str]] + + # The placeholder of the select. + placeholder: Var[str] + + # The label of the select. + label: Var[str] + + # The color of the select. + color: Var[LiteralAccentColor] + + # Whether to render the select with higher contrast color against background. + high_contrast: Var[bool] + + # The variant of the select. + variant: Var[Literal["classic", "surface", "soft", "ghost"]] + + # The radius of the select. + radius: Var[LiteralRadius] + + # The width of the select. + width: Var[str] + + @classmethod + def create(cls, items: Union[List[str], Var[List[str]]], **props) -> Component: + """Create a select component. + + Args: + items: The items of the select. + **props: Additional properties to apply to the select component. + + Returns: + The select component. + """ + content_props = { + prop: props.pop(prop) for prop in ["high_contrast"] if prop in props + } + + trigger_props = { + prop: props.pop(prop) + for prop in ["placeholder", "variant", "radius", "width"] + if prop in props + } + + color = props.pop("color", None) + + if color is not None: + content_props["color_scheme"] = color + trigger_props["color_scheme"] = color + + label = props.pop("label", None) + + if isinstance(items, Var): + child = [ + rx.foreach(items, lambda item: SelectItem.create(item, value=item)) + ] + else: + child = [SelectItem.create(item, value=item) for item in items] + + return SelectRoot.create( + SelectTrigger.create( + **trigger_props, + ), + SelectContent.create( + SelectGroup.create( + SelectLabel.create(label) if label is not None else "", + *child, + ), + **content_props, + ), + **props, + ) diff --git a/reflex/components/radix/themes/components/select.pyi b/reflex/components/radix/themes/components/select.pyi index 142ff5864..30ece06b1 100644 --- a/reflex/components/radix/themes/components/select.pyi +++ b/reflex/components/radix/themes/components/select.pyi @@ -7,7 +7,9 @@ from typing import Any, Dict, Literal, Optional, Union, overload from reflex.vars import Var, BaseVar, ComputedVar from reflex.event import EventChain, EventHandler, EventSpec from reflex.style import Style -from typing import Any, Dict, Literal +from typing import Any, Dict, List, Literal, Union +import reflex as rx +from reflex.components.component import Component from reflex.vars import Var from ..base import ( CommonMarginProps, @@ -1452,3 +1454,237 @@ class SelectSeparator(CommonMarginProps, RadixThemesComponent): A new component instance. """ ... + +class HighLevelSelect(SelectRoot): + @overload + @classmethod + def create( # type: ignore + cls, + *children, + items: Optional[Union[Var[List[str]], List[str]]] = None, + placeholder: Optional[Union[Var[str], str]] = None, + label: Optional[Union[Var[str], str]] = None, + color: Optional[ + Union[ + Var[ + Literal[ + "tomato", + "red", + "ruby", + "crimson", + "pink", + "plum", + "purple", + "violet", + "iris", + "indigo", + "blue", + "cyan", + "teal", + "jade", + "green", + "grass", + "brown", + "orange", + "sky", + "mint", + "lime", + "yellow", + "amber", + "gold", + "bronze", + "gray", + ] + ], + Literal[ + "tomato", + "red", + "ruby", + "crimson", + "pink", + "plum", + "purple", + "violet", + "iris", + "indigo", + "blue", + "cyan", + "teal", + "jade", + "green", + "grass", + "brown", + "orange", + "sky", + "mint", + "lime", + "yellow", + "amber", + "gold", + "bronze", + "gray", + ], + ] + ] = None, + high_contrast: Optional[Union[Var[bool], bool]] = None, + variant: Optional[ + Union[ + Var[Literal["classic", "surface", "soft", "ghost"]], + Literal["classic", "surface", "soft", "ghost"], + ] + ] = None, + radius: Optional[ + Union[ + Var[Literal["none", "small", "medium", "large", "full"]], + Literal["none", "small", "medium", "large", "full"], + ] + ] = None, + width: Optional[Union[Var[str], str]] = None, + size: Optional[Union[Var[Literal[1, 2, 3]], Literal[1, 2, 3]]] = None, + default_value: Optional[Union[Var[str], str]] = None, + value: Optional[Union[Var[str], str]] = None, + default_open: Optional[Union[Var[bool], bool]] = None, + open: Optional[Union[Var[bool], bool]] = None, + name: Optional[Union[Var[str], str]] = None, + disabled: Optional[Union[Var[bool], bool]] = None, + required: Optional[Union[Var[bool], bool]] = None, + m: Optional[ + Union[ + Var[Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"]], + Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"], + ] + ] = None, + mx: Optional[ + Union[ + Var[Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"]], + Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"], + ] + ] = None, + my: Optional[ + Union[ + Var[Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"]], + Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"], + ] + ] = None, + mt: Optional[ + Union[ + Var[Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"]], + Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"], + ] + ] = None, + mr: Optional[ + Union[ + Var[Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"]], + Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"], + ] + ] = None, + mb: Optional[ + Union[ + Var[Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"]], + Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"], + ] + ] = None, + ml: Optional[ + Union[ + Var[Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"]], + Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"], + ] + ] = None, + style: Optional[Style] = None, + key: Optional[Any] = None, + id: Optional[Any] = None, + class_name: Optional[Any] = None, + autofocus: Optional[bool] = None, + custom_attrs: Optional[Dict[str, Union[Var, str]]] = None, + on_blur: Optional[ + Union[EventHandler, EventSpec, list, function, BaseVar] + ] = None, + on_click: Optional[ + Union[EventHandler, EventSpec, list, function, BaseVar] + ] = None, + on_context_menu: Optional[ + Union[EventHandler, EventSpec, list, function, BaseVar] + ] = None, + on_double_click: Optional[ + Union[EventHandler, EventSpec, list, function, BaseVar] + ] = None, + on_focus: Optional[ + Union[EventHandler, EventSpec, list, function, BaseVar] + ] = None, + on_mount: Optional[ + Union[EventHandler, EventSpec, list, function, BaseVar] + ] = None, + on_mouse_down: Optional[ + Union[EventHandler, EventSpec, list, function, BaseVar] + ] = None, + on_mouse_enter: Optional[ + Union[EventHandler, EventSpec, list, function, BaseVar] + ] = None, + on_mouse_leave: Optional[ + Union[EventHandler, EventSpec, list, function, BaseVar] + ] = None, + on_mouse_move: Optional[ + Union[EventHandler, EventSpec, list, function, BaseVar] + ] = None, + on_mouse_out: Optional[ + Union[EventHandler, EventSpec, list, function, BaseVar] + ] = None, + on_mouse_over: Optional[ + Union[EventHandler, EventSpec, list, function, BaseVar] + ] = None, + on_mouse_up: Optional[ + Union[EventHandler, EventSpec, list, function, BaseVar] + ] = None, + on_open_change: Optional[ + Union[EventHandler, EventSpec, list, function, BaseVar] + ] = None, + on_scroll: Optional[ + Union[EventHandler, EventSpec, list, function, BaseVar] + ] = None, + on_unmount: Optional[ + Union[EventHandler, EventSpec, list, function, BaseVar] + ] = None, + on_value_change: Optional[ + Union[EventHandler, EventSpec, list, function, BaseVar] + ] = None, + **props + ) -> "HighLevelSelect": + """Create a select component. + + Args: + items: The items of the select. + items: The items of the select. + placeholder: The placeholder of the select. + label: The label of the select. + color: The color of the select. + high_contrast: Whether to render the select with higher contrast color against background. + variant: The variant of the select. + radius: The radius of the select. + width: The width of the select. + size: The size of the select: "1" | "2" | "3" + default_value: The value of the select when initially rendered. Use when you do not need to control the state of the select. + value: The controlled value of the select. Should be used in conjunction with on_value_change. + default_open: The open state of the select when it is initially rendered. Use when you do not need to control its open state. + open: The controlled open state of the select. Must be used in conjunction with on_open_change. + name: The name of the select control when submitting the form. + disabled: When True, prevents the user from interacting with select. + required: When True, indicates that the user must select a value before the owning form can be submitted. + m: Margin: "0" - "9" + mx: Margin horizontal: "0" - "9" + my: Margin vertical: "0" - "9" + mt: Margin top: "0" - "9" + mr: Margin right: "0" - "9" + mb: Margin bottom: "0" - "9" + ml: Margin left: "0" - "9" + style: The style of the component. + key: A unique key for the component. + id: The id for the component. + class_name: The class name for the component. + autofocus: Whether the component should take the focus once the page is loaded + custom_attrs: custom attribute + **props: Additional properties to apply to the select component. + + Returns: + The select component. + """ + ...