---
components:
  - rx.select.root
  - rx.select.trigger
  - rx.select.content
  - rx.select.group
  - rx.select.item
  - rx.select.label
  - rx.select.separator
---

```python exec
import random
import reflex as rx
import reflex.components.radix.primitives as rdxp
```

# Select

Displays a list of options for the user to pick from, triggered by a button.

## Basic Example

```python demo
rx.select.root(
    rx.select.trigger(),
    rx.select.content(
        rx.select.group(
            rx.select.label("Fruits"),
            rx.select.item("Orange", value="orange"),
            rx.select.item("Apple", value="apple"),
            rx.select.item("Grape", value="grape", disabled=True),
        ),
        rx.select.separator(),
        rx.select.group(
            rx.select.label("Vegetables"),
            rx.select.item("Carrot", value="carrot"),
            rx.select.item("Potato", value="potato"),
        ),
    ),
    default_value="apple",
)
```

## Usage

## Disabling

It is possible to disable individual items in a `select` using the `disabled` prop associated with the `rx.select.item`.

```python demo
rx.select.root(
    rx.select.trigger(placeholder="Select a Fruit"),
    rx.select.content(
        rx.select.group(
            rx.select.item("Apple", value="apple"),
            rx.select.item("Grape", value="grape", disabled=True),
            rx.select.item("Pineapple", value="pineapple"),
        ),
    ),
)
```

To prevent the user from interacting with select entirely, set the `disabled` prop to `True` on the `rx.select.root` component.

```python demo
rx.select.root(
    rx.select.trigger(placeholder="This is Disabled"),
    rx.select.content(
        rx.select.group(
            rx.select.item("Apple", value="apple"),
            rx.select.item("Grape", value="grape"),
        ),
    ),
    disabled=True,
)
```

## Setting Defaults

It is possible to set several default values when constructing a `select`.

The `placeholder` prop in the `rx.select.trigger` specifies the content that will be rendered when `value` or `default_value` is empty or not set.

```python demo
rx.select.root(
    rx.select.trigger(placeholder="pick a fruit"),
    rx.select.content(
        rx.select.group(
            rx.select.item("Apple", value="apple"),
            rx.select.item("Grape", value="grape"),
        ),
    ),
)
```

The `default_value` in the `rx.select.root` specifies the value of the `select` when initially rendered.
The `default_value` should correspond to the `value` of a child `rx.select.item`.

```python demo
rx.select.root(
    rx.select.trigger(),
    rx.select.content(
        rx.select.group(
            rx.select.item("Apple", value="apple"),
            rx.select.item("Grape", value="grape"),
        ),
    ),
    default_value="apple",
)
```

## Fully controlled

The `on_change` event trigger is fired when the value of the select changes.
In this example the `rx.select.root` `value` prop specifies which item is selected, and this
can also be controlled using state and a button without direct interaction with the select component.

```python demo exec
class SelectState2(rx.State):
    values: list[str] = ["apple", "grape", "pear"]

    value: str = ""

    def set_value(self, value: str):
        self.value = value

    @rx.event
    def choose_randomly(self):
        """Change the select value var."""
        original_value = self.value
        while self.value == original_value:
            self.value = random.choice(self.values)


def select_example2():
    return rx.vstack(
        rx.select.root(
            rx.select.trigger(placeholder="No Selection"),
            rx.select.content(
                rx.select.group(
                    rx.foreach(
                        SelectState2.values, lambda x: rx.select.item(x, value=x)
                    )
                ),
            ),
            value=SelectState2.value,
            on_change=SelectState2.set_value,
        ),
        rx.button("Choose Randomly", on_click=SelectState2.choose_randomly),
        rx.button("Reset", on_click=SelectState2.set_value("")),
    )
```

The `open` prop and `on_open_change` event trigger work similarly to `value` and `on_change` to control the open state of the select.
If `on_open_change` handler does not alter the `open` prop, the select will not be able to be opened or closed by clicking on the
`select_trigger`.

```python demo exec
class SelectState8(rx.State):
    is_open: bool = False

    @rx.event
    def set_is_open(self, value: bool):
        self.is_open = value


def select_example8():
    return rx.flex(
        rx.select.root(
            rx.select.trigger(placeholder="No Selection"),
            rx.select.content(
                rx.select.group(
                    rx.select.item("Apple", value="apple"),
                    rx.select.item("Grape", value="grape"),
                ),
            ),
            open=SelectState8.is_open,
            on_open_change=SelectState8.set_is_open,
        ),
        rx.button("Toggle", on_click=SelectState8.set_is_open(~SelectState8.is_open)),
        spacing="2",
    )
```

### Submitting a Form with Select

When a select is part of a form, the `name` prop of the `rx.select.root` sets the key that will be submitted with the form data.

The `value` prop of `rx.select.item` provides the value to be associated with the `name` key when the form is submitted with that item selected.

When the `required` prop of the `rx.select.root` is `True`, it indicates that the user must select a value before the form may be submitted.

```python demo exec
class FormSelectState(rx.State):
    form_data: dict = {}

    @rx.event
    def handle_submit(self, form_data: dict):
        """Handle the form submit."""
        self.form_data = form_data


def form_select():
    return rx.flex(
        rx.form.root(
            rx.flex(
                rx.select.root(
                    rx.select.trigger(),
                    rx.select.content(
                        rx.select.group(
                            rx.select.label("Fruits"),
                            rx.select.item("Orange", value="orange"),
                            rx.select.item("Apple", value="apple"),
                            rx.select.item("Grape", value="grape"),
                        ),
                        rx.select.separator(),
                        rx.select.group(
                            rx.select.label("Vegetables"),
                            rx.select.item("Carrot", value="carrot"),
                            rx.select.item("Potato", value="potato"),
                        ),
                    ),
                    default_value="apple",
                    name="select",
                ),
                rx.button("Submit"),
                width="100%",
                direction="column",
                spacing="2",
            ),
            on_submit=FormSelectState.handle_submit,
            reset_on_submit=True,
        ),
        rx.divider(size="4"),
        rx.heading("Results", as_="h2"),
        rx.text(FormSelectState.form_data.to_string()),
        width="100%",
        direction="column",
        spacing="2",
    )
```

## Real World Example

```python demo
rx.card(
    rx.flex(
        rx.image(
            src="https://web.reflex-assets.dev/other/reflex_banner.png",
            alt="Reflex banner image",
            width="100%",
            height="auto",
        ),
        rx.flex(
            rx.heading("Reflex Swag", as_="h2", size="4", margin_bottom="4px"),
            rx.heading("$99", as_="h2", size="6", margin_bottom="4px"),
            direction="row",
            justify="between",
            width="100%",
        ),
        rx.text(
            "Reflex swag with a sense of nostalgia, as if they carry whispered tales of past adventures",
            size="2",
            margin_bottom="4px",
        ),
        rx.divider(size="4"),
        rx.flex(
            rx.flex(
                rx.text("Color", size="2", margin_bottom="4px", color_scheme="gray"),
                rx.select.root(
                    rx.select.trigger(),
                    rx.select.content(
                        rx.select.group(
                            rx.select.item("Light", value="light"),
                            rx.select.item("Dark", value="dark"),
                        ),
                    ),
                    default_value="light",
                ),
                direction="column",
            ),
            rx.flex(
                rx.text("Size", size="2", margin_bottom="4px", color_scheme="gray"),
                rx.select.root(
                    rx.select.trigger(),
                    rx.select.content(
                        rx.select.group(
                            rx.select.item("24", value="24"),
                            rx.select.item("26", value="26"),
                            rx.select.item("28", value="28", disabled=True),
                            rx.select.item("30", value="30"),
                            rx.select.item("32", value="32"),
                            rx.select.item("34", value="34"),
                            rx.select.item("36", value="36"),
                        ),
                    ),
                    default_value="30",
                ),
                direction="column",
            ),
            rx.button(rx.icon(tag="plus"), "Add"),
            align="end",
            justify="between",
            spacing="2",
            width="100%",
        ),
        width="15em",
        direction="column",
        spacing="2",
    ),
)
```
