123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- """Interactive components provided by @radix-ui/themes."""
- from types import SimpleNamespace
- 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 (
- LiteralAccentColor,
- LiteralRadius,
- RadixThemesComponent,
- )
- LiteralButtonSize = Literal[1, 2, 3, 4]
- class SelectRoot(RadixThemesComponent):
- """Displays a list of options for the user to pick from, triggered by a button."""
- tag = "Select.Root"
- # The size of the select: "1" | "2" | "3"
- size: Var[Literal["1", "2", "3"]]
- # The value of the select when initially rendered. Use when you do not need to control the state of the select.
- default_value: Var[str]
- # The controlled value of the select. Should be used in conjunction with on_value_change.
- value: Var[str]
- # The open state of the select when it is initially rendered. Use when you do not need to control its open state.
- default_open: Var[bool]
- # The controlled open state of the select. Must be used in conjunction with on_open_change.
- open: Var[bool]
- # The name of the select control when submitting the form.
- name: Var[str]
- # When True, prevents the user from interacting with select.
- disabled: Var[bool]
- # When True, indicates that the user must select a value before the owning form can be submitted.
- required: Var[bool]
- def get_event_triggers(self) -> Dict[str, Any]:
- """Get the events triggers signatures for the component.
- Returns:
- The signatures of the event triggers.
- """
- return {
- **super().get_event_triggers(),
- "on_open_change": lambda e0: [e0],
- "on_value_change": lambda e0: [e0],
- }
- class SelectTrigger(RadixThemesComponent):
- """The button that toggles the select."""
- tag = "Select.Trigger"
- # Variant of the select trigger
- variant: Var[Literal["classic", "surface", "soft", "ghost"]]
- # The color of the select trigger
- color_scheme: Var[LiteralAccentColor]
- # The radius of the select trigger
- radius: Var[LiteralRadius]
- # The placeholder of the select trigger
- placeholder: Var[str]
- class SelectContent(RadixThemesComponent):
- """The component that pops out when the select is open."""
- tag = "Select.Content"
- # The variant of the select content
- variant: Var[Literal["solid", "soft"]]
- # The color of the select content
- color_scheme: Var[LiteralAccentColor]
- # Whether to render the select content with higher contrast color against background
- high_contrast: Var[bool]
- # The positioning mode to use, item-aligned is the default and behaves similarly to a native MacOS menu by positioning content relative to the active item. popper positions content in the same way as our other primitives, for example Popover or DropdownMenu.
- position: Var[Literal["item-aligned", "popper"]]
- # The preferred side of the anchor to render against when open. Will be reversed when collisions occur and avoidCollisions is enabled. Only available when position is set to popper.
- side: Var[Literal["top", "right", "bottom", "left"]]
- # The distance in pixels from the anchor. Only available when position is set to popper.
- side_offset: Var[int]
- # The preferred alignment against the anchor. May change when collisions occur. Only available when position is set to popper.
- align: Var[Literal["start", "center", "end"]]
- # The vertical distance in pixels from the anchor. Only available when position is set to popper.
- align_offset: Var[int]
- def get_event_triggers(self) -> Dict[str, Any]:
- """Get the events triggers signatures for the component.
- Returns:
- The signatures of the event triggers.
- """
- return {
- **super().get_event_triggers(),
- "on_close_auto_focus": lambda e0: [e0],
- "on_escape_key_down": lambda e0: [e0],
- "on_pointer_down_outside": lambda e0: [e0],
- }
- class SelectGroup(RadixThemesComponent):
- """Used to group multiple items."""
- tag = "Select.Group"
- class SelectItem(RadixThemesComponent):
- """The component that contains the select items."""
- tag = "Select.Item"
- # The value given as data when submitting a form with a name.
- value: Var[str]
- # Whether the select item is disabled
- disabled: Var[bool]
- class SelectLabel(RadixThemesComponent):
- """Used to render the label of a group, it isn't focusable using arrow keys."""
- tag = "Select.Label"
- class SelectSeparator(RadixThemesComponent):
- """Used to visually separate items in the Select."""
- 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_scheme: 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,
- )
- class Select(SimpleNamespace):
- """Select components namespace."""
- root = staticmethod(SelectRoot.create)
- trigger = staticmethod(SelectTrigger.create)
- content = staticmethod(SelectContent.create)
- group = staticmethod(SelectGroup.create)
- item = staticmethod(SelectItem.create)
- separator = staticmethod(SelectSeparator.create)
- label = staticmethod(SelectLabel.create)
- __call__ = staticmethod(HighLevelSelect.create)
- select = Select()
|