---
title: "Выбирать"
description: "Стилизованный собственный элемент выбора HTML с последовательной интеграцией системы дизайна."
order: 13
---
## Select, стилизованный собственный HTML-элемент Select с последовательной интеграцией системы дизайна.



> Обработка ошибки `usage`: ожидался модуль, класс, метод, функция, обратная трассировка, кадр или объект кода, получен NativeSelect


```python
from typing import Any

from reflex.components.component import Component
from reflex.utils.imports import ImportVar
from reflex.vars import FunctionVar, Var
from reflex.vars.base import VarData

PACKAGE_CN = "clsx-for-tailwind@1.0.0"
CN = Var(
    "cn",
    _var_data=VarData(
        imports={
            PACKAGE_CN: ImportVar(tag="cn"),
        },
    ),
).to(FunctionVar)


class CoreComponent(Component):
    unstyled: Var[bool]

    @classmethod
    def set_class_name(
        cls, default_class_name: str | Var[str], props: dict[str, Any]
    ) -> None:

        if "render_" in props:
            return

        props_class_name = props.get("class_name", "")

        if props.pop("unstyled", False):
            props["class_name"] = props_class_name
            return

        props["class_name"] = cn(default_class_name, props_class_name)

    def _exclude_props(self) -> list[str]:
        return [
            *super()._exclude_props(),
            "unstyled",
        ]


def cn(*classes: Var | str | tuple | list | None) -> Var:
    return CN.call(*classes).to(str)
```

```python
from reflex.components.component import Component
from reflex.utils.imports import ImportVar
from reflex.vars.base import Var, VarData

from ..core.core import CoreComponent

REACT_LIBRARY = "@hugeicons/react@1.1.9"
CORE_ICONS_LIBRARY = "@hugeicons/core-free-icons@4.2.3"


class HugeIcon(CoreComponent):
    library = REACT_LIBRARY

    tag = "HugeiconsIcon"

    icon: Var[str]

    alt_icon: Var[str | None]

    show_alt: Var[bool]

    size: Var[int | str] = Var.create(16)

    color: Var[str]

    primary_color: Var[str]

    secondary_color: Var[str]

    stroke_width: Var[float] = Var.create(1.5)

    absolute_stroke_width: Var[bool]

    disable_secondary_opacity: Var[bool]

    @classmethod
    def create(cls, *children, **props) -> Component:

        if children and isinstance(children[0], str) and "icon" not in props:
            props["icon"] = children[0]
            children = children[1:]

        for prop in ("icon", "alt_icon"):
            value = props.get(prop)

            if isinstance(value, str):
                props[prop] = Var(
                    value,
                    _var_data=VarData(
                        imports={CORE_ICONS_LIBRARY: [ImportVar(tag=value)]}
                    ),
                )

        stroke_width = props.get("stroke_width", 1.5)

        cls.set_class_name(
            f"[&_path]:stroke-[{stroke_width}]",
            props,
        )

        return super().create(*children, **props)


hi = icon = HugeIcon.create
```

```python
from typing import Literal

import reflex as rx
from reflex.components.component import ComponentNamespace

from ..core.core import CoreComponent, cn
from ..core.hugeicon import hi

LiteralNativeSelectSize = Literal["default", "sm"]


class ClassNames:
    WRAPPER = "group/native-select relative w-fit has-[select:disabled]:opacity-50"

    SELECT = (
        "h-8 w-full min-w-0 appearance-none rounded-lg border border-input "
        "bg-transparent py-1 pr-8 pl-2.5 text-sm outline-none "
        "select-none selection:bg-primary selection:text-primary-foreground "
        "placeholder:text-muted-foreground "
        "focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 "
        "disabled:pointer-events-none disabled:cursor-not-allowed "
        "aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 "
        "data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] "
        "data-[size=sm]:py-0.5 "
        "dark:bg-input/30 dark:hover:bg-input/50 "
        "dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40"
    )

    ICON = (
        "pointer-events-none absolute top-1/2 right-2.5 size-4 -translate-y-1/2 "
        "text-muted-foreground select-none"
    )

    OPTION = "bg-[Canvas] text-[CanvasText]"

    OPTGROUP = "bg-[Canvas] text-[CanvasText]"


class NativeSelectComponent(CoreComponent):
    @classmethod
    def create(cls, *children, **props) -> rx.Component:
        size = props.pop("size", "default")
        wrapper_class_name = props.pop("wrapper_class_name", "")
        data_slot = props.pop("data_slot", "native-select")

        select_class_name = cn(ClassNames.SELECT, props.get("class_name", ""))
        props["class_name"] = select_class_name
        props["data-slot"] = data_slot
        props["data-size"] = size

        select_el = rx.el.select(*children, **props)

        return rx.el.div(
            select_el,
            hi(
                "ArrowDown01Icon",
                class_name=ClassNames.ICON,
                data_slot="native-select-icon",
                aria_hidden="true",
            ),
            data_slot="native-select-wrapper",
            data_size=size,
            class_name=cn(ClassNames.WRAPPER, wrapper_class_name),
        )


class NativeSelectOptionComponent(CoreComponent):
    @classmethod
    def create(cls, *children, **props) -> rx.Component:
        props["data-slot"] = "native-select-option"
        cls.set_class_name(ClassNames.OPTION, props)
        return rx.el.option(*children, **props)


class NativeSelectOptGroupComponent(CoreComponent):
    @classmethod
    def create(cls, *children, **props) -> rx.Component:
        props["data-slot"] = "native-select-optgroup"
        cls.set_class_name(ClassNames.OPTGROUP, props)
        return rx.el.optgroup(*children, **props)


class NativeSelect(ComponentNamespace):
    __call__ = staticmethod(NativeSelectComponent.create)
    option = staticmethod(NativeSelectOptionComponent.create)
    optgroup = staticmethod(NativeSelectOptGroupComponent.create)
    class_names = ClassNames


select = NativeSelect()
```

# Примеры

## Базовый

Один родной `<select>` в паре с `field.label`. Использует `wrapper_class_name`, чтобы растянуть выделение на всю ширину его контейнера.

**Использованный реквизит:** `id`, `name`, `default_value`, `wrapper_class_name` на `select`; `value` по `select.option`; `html_for` на `field.label`.

```python
def select_basic() -> rx.Component:
    return rx.el.div(
        field.root(
            field.label("Favorite fruit", html_for="fruit-basic"),
            select(
                select.option("Apple", value="apple"),
                select.option("Banana", value="banana"),
                select.option("Blueberry", value="blueberry"),
                select.option("Grapes", value="grapes"),
                select.option("Pineapple", value="pineapple"),
                id="fruit-basic",
                name="fruit",
                default_value="apple",
                wrapper_class_name="w-full",
            ),
        ),
        class_name="mx-auto max-w-sm",
    )
```

## Сгруппированные параметры

Опции организованы под заголовками `select.optgroup`, с отключенной, скрытой первой опцией, выступающей в качестве заполнителя — стандартный способ отображения текста заполнителя в собственном выборе без возможности выбора реального пустого значения.

**Использованный реквизит:** `label` на `select.optgroup`; `value`, `disabled`, `hidden` по `select.option`; `id`, `name`, `default_value`, `wrapper_class_name` на `select`.

```python
def select_optgroup() -> rx.Component:
    return rx.el.div(
        field.root(
            field.label("Ingredient", html_for="ingredient-select"),
            select(
                select.option(
                    "Select an ingredient", value="", disabled=True, hidden=True
                ),
                select.optgroup(
                    select.option("Apple", value="apple"),
                    select.option("Banana", value="banana"),
                    select.option("Blueberry", value="blueberry"),
                    label="Fruits",
                ),
                select.optgroup(
                    select.option("Carrot", value="carrot"),
                    select.option("Potato", value="potato"),
                    select.option("Broccoli", value="broccoli"),
                    label="Vegetables",
                ),
                id="ingredient-select",
                name="ingredient",
                default_value="",
                wrapper_class_name="w-full",
            ),
        ),
        class_name="mx-auto max-w-sm",
    )
```

## Размеры

Два варианта размера рядом — `sm` для компактных макетов (панели инструментов, ячейки таблиц) и размер `default` для отдельных полей формы.

**Использованный реквизит:** `size`, `default_value` на `select`; `value` на `select.option`.

```python
def select_sizes() -> rx.Component:
    return rx.el.div(
        select(
            select.option("Small", value="sm"),
            select.option("Medium", value="md"),
            select.option("Large", value="lg"),
            default_value="md",
            size="sm",
        ),
        select(
            select.option("Small", value="sm"),
            select.option("Medium", value="md"),
            select.option("Large", value="lg"),
            default_value="md",
        ),
        class_name="mx-auto flex max-w-sm items-center gap-4",
    )
```

## Макет формы

Два выбора сгруппированы под общим `field.set` с `field.legend`, показывая, как выборки составляются внутри более крупного раздела формы.

**Использованный реквизит:** `id`, `name`, `default_value`, `wrapper_class_name` на `select`; `value` по `select.option`; `html_for` на `field.label`.

```python
def select_form() -> rx.Component:
    return field.set(
        field.legend("Shipping details"),
        field.group(
            field.root(
                field.label("Country", html_for="shipping-country"),
                select(
                    select.option("United States", value="us"),
                    select.option("Canada", value="ca"),
                    select.option("United Kingdom", value="uk"),
                    select.option("Germany", value="de"),
                    id="shipping-country",
                    name="country",
                    default_value="us",
                    wrapper_class_name="w-full",
                ),
            ),
            field.root(
                field.label("Timezone", html_for="shipping-timezone"),
                select(
                    select.option("Pacific Time (PT)", value="pt"),
                    select.option("Mountain Time (MT)", value="mt"),
                    select.option("Central Time (CT)", value="ct"),
                    select.option("Eastern Time (ET)", value="et"),
                    id="shipping-timezone",
                    name="timezone",
                    default_value="et",
                    wrapper_class_name="w-full",
                ),
            ),
        ),
        class_name="mx-auto max-w-sm",
    )
```

## Отключено

Отключенный выбор с `field.description`, объясняющим, почему он заблокирован. Отключение визуального каскадирования для всего элемента управления с помощью стиля оболочки `has-[select:disabled]`.

**Использованный реквизит:** `id`, `default_value`, `disabled`, `wrapper_class_name` на `select`; `value` на `select.option`.

```python
def select_disabled() -> rx.Component:
    return rx.el.div(
        field.root(
            field.label("Country", html_for="country-disabled"),
            select(
                select.option("United States", value="us"),
                select.option("Canada", value="ca"),
                select.option("Mexico", value="mx"),
                id="country-disabled",
                default_value="us",
                disabled=True,
                wrapper_class_name="w-full",
            ),
            field.description("This field is currently locked."),
        ),
        class_name="mx-auto max-w-sm",
    )
```

# Справочник по API
 
## выбрать
 
Основной компонент выбора. Вызов `select(...)` напрямую визуализирует собственный `<select>`, завернутый в позиционирование `div` со значком шеврона — `select` сам по себе является вызываемым (через `NativeSelect.__call__`), поэтому отдельный `.root` не требуется.
 
```python
select(
    select.option("Option 1", value="option1"),
    select.option("Option 2", value="option2"),
)
```
 
| Опора | Тип | По умолчанию |
| -------------------- | ----------------------- | ---------------- |
| `size` | `Literal["default", "sm"]` | `"default"` |
| `wrapper_class_name` | `str` | `""` |
| `class_name` | `str` | `""` |
| `data_slot` | `str` | `"native-select"` |
| `disabled` | `bool` | `False` |
| `value` / `default_value` | `str` |                   |
| `name` | `str` |                   |
| `id` | `str` |                   |
| `on_change` | `EventHandler` |                   |
 
Любое другое свойство, принятое собственным HTML `<select>` (`required`, `aria-invalid` и т. д.), также передается напрямую.
 
## выбор.опция
 
Представляет отдельный параметр в пределах выбора.
 
```python
select.option("Apple", value="apple")
select.option("Sold out", value="oos", disabled=True)
```
 
| Опора | Тип | По умолчанию |
| ---------- | ------ | ------- |
| `value` | `str` |         |
| `disabled` | `bool` | `False` |
| `hidden` | `bool` | `False` |
 
## выберите.optgroup
 
Группирует связанные параметры под помеченным заголовком.
 
```python
select.optgroup(
    select.option("Apple", value="apple"),
    select.option("Banana", value="banana"),
    label="Fruits",
)
```
 
| Опора | Тип | По умолчанию |
| ---------- | ------ | ------- |
| `label` | `str` |         |
| `disabled` | `bool` | `False` |