Theme
Version
GitHub PyPI Discord
On this page

Native Select

Use CNativeSelect for one choice from a finite server-owned list. It renders one native Select element, so keyboards, touch pickers, autofill, forms, validation, and reset keep their browser behavior.

Native Select at a glance

Native Select at a glance
Show code
from typing import Any

import citry_ui
from citry import Component, citry
from citry_ui import CNativeSelectGroup, CNativeSelectOption

citry.register_library(citry_ui)


class NativeSelectAtAGlance(Component):
    class Kwargs:
        pass

    class Slots:
        pass

    def template_data(self, kwargs: Kwargs, slots: Slots) -> dict[str, Any]:  # noqa: ARG002
        return {
            "habitats": [
                CNativeSelectGroup(
                    "Coastal",
                    [
                        CNativeSelectOption("kelp", "Kelp forest"),
                        CNativeSelectOption("reef", "Coral reef"),
                        CNativeSelectOption("mangrove", "Mangrove nursery"),
                    ],
                ),
                CNativeSelectGroup(
                    "Open ocean",
                    [
                        CNativeSelectOption("pelagic", "Pelagic zone"),
                        CNativeSelectOption("abyss", "Abyssal plain"),
                    ],
                ),
            ],
        }

    template = """
      <section class="ocean-glance" aria-label="Ocean habitat survey">
        <c-CField required>
          <c-fill name="label">Primary habitat</c-fill>
          <c-fill name="default">
            <c-CNativeSelect
              name="habitat"
              c-options="habitats"
              placeholder="Choose a habitat"
              value="reef"
            />
          </c-fill>
          <c-fill name="description">Choose the habitat represented by this dive.</c-fill>
        </c-CField>

        <div class="ocean-glance__deep" style="color-scheme: dark">
          <c-CField invalid>
            <c-fill name="label">Unverified station</c-fill>
            <c-fill name="default">
              <c-CNativeSelect
                c-options="habitats"
                placeholder="Choose a station type"
                variant="filled"
              />
            </c-fill>
            <c-fill name="error">Match this station to a surveyed habitat.</c-fill>
          </c-CField>
        </div>
      </section>
    """

    css = """
      :where(.ocean-glance) {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
        gap: 1rem;
        max-width: 54rem;
        color: CanvasText;
        font-family: ui-sans-serif, system-ui, sans-serif;
      }

      :where(.ocean-glance > *) {
        padding: 1rem;
        border: 1px solid light-dark(#9ccbd3, #315f6a);
        border-radius: 0.875rem;
        background: light-dark(#f1fbfc, #10272d);
      }

      :where(.ocean-glance__deep) {
        --cui-native-select-background: #142f36;
        --cui-native-select-border-color: #57828c;
        --cui-native-select-focus-color: #7ddbea;
      }
    """


preview = NativeSelectAtAGlance()

preview  # noqa: B018

Compose a labelled Select

Put Native Select inside CField when it needs a label, description, error, or composed state. Pass options as CNativeSelectOption and CNativeSelectGroup records.

Compose Native Select in templates and Python
Show code
from typing import Any

import citry_ui
from citry import Component, citry
from citry_ui import CNativeSelect, CNativeSelectOption

citry.register_library(citry_ui)


class ComposeNativeSelect(Component):
    class Kwargs:
        pass

    class Slots:
        pass

    def template_data(self, kwargs: Kwargs, slots: Slots) -> dict[str, Any]:  # noqa: ARG002
        options = [
            CNativeSelectOption("north", "North transect"),
            CNativeSelectOption("central", "Central transect"),
            CNativeSelectOption("south", "South transect"),
        ]
        return {
            "options": options,
            "python_select": CNativeSelect(
                options=options,
                id="python-transect",
                name="python_transect",
                value="central",
            ),
        }

    template = """
      <section class="ocean-compose">
        <c-CField>
          <c-fill name="label">Template-composed transect</c-fill>
          <c-fill name="default">
            <c-CNativeSelect
              name="template_transect"
              c-options="options"
              value="north"
            />
          </c-fill>
        </c-CField>

        <div>
          <label class="ocean-compose__label" for="python-transect">
            Python-composed transect
          </label>
          {{ python_select }}
        </div>
      </section>
    """

    css = """
      :where(.ocean-compose) {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
        gap: 1rem;
        color: CanvasText;
        font-family: ui-sans-serif, system-ui, sans-serif;
      }

      :where(.ocean-compose__label) {
        display: block;
        margin-block-end: 0.5rem;
        font-weight: 650;
      }
    """


preview = ComposeNativeSelect()

preview  # noqa: B018

Outside CField, provide a native label or accessible name yourself. CNativeSelect has no slots or child content.

Build options and groups

Option values are stable form and morph identities. They must be unique and nonempty. Groups preserve order, cannot nest, and may disable all their options.

Use flat options, groups, and disabled choices
Show code
from typing import Any

import citry_ui
from citry import Component, citry
from citry_ui import CNativeSelectGroup, CNativeSelectOption

citry.register_library(citry_ui)


class NativeSelectOptions(Component):
    class Kwargs:
        pass

    class Slots:
        pass

    def template_data(self, kwargs: Kwargs, slots: Slots) -> dict[str, Any]:  # noqa: ARG002
        return {
            "regions": [
                CNativeSelectOption("harbor", "Research harbor"),
                CNativeSelectGroup(
                    "Continental shelf",
                    [
                        CNativeSelectOption("bank", "Emerald Bank"),
                        CNativeSelectOption("canyon", "Bluefin Canyon"),
                        CNativeSelectOption("closure", "Seasonal closure", disabled=True),
                    ],
                ),
                CNativeSelectGroup(
                    "Weather hold",
                    [CNativeSelectOption("offshore", "Offshore station")],
                    disabled=True,
                ),
            ],
        }

    template = """
      <section class="ocean-options">
        <c-CField>
          <c-fill name="label">Expedition region</c-fill>
          <c-fill name="default">
            <c-CNativeSelect
              name="region"
              c-options="regions"
              value="bank"
            />
          </c-fill>
          <c-fill name="description">Closed choices remain visible but unavailable.</c-fill>
        </c-CField>
      </section>
    """

    css = """
      :where(.ocean-options) {
        max-width: 34rem;
        color: CanvasText;
        font-family: ui-sans-serif, system-ui, sans-serif;
      }
    """


preview = NativeSelectOptions()

preview  # noqa: B018

Labels are plain text. Put rich rows or search in CSelect, CMultiSelect, or CListbox rather than native options. Remote data and virtualization still need application ownership or a later dedicated collection family.

Prompt and require a choice

placeholder inserts the first empty-value option. It is also required for a conforming required single Select.

Compare optional and required destinations
Show code
from typing import Any

import citry_ui
from citry import Component, citry
from citry_ui import CNativeSelectOption

citry.register_library(citry_ui)


class NativeSelectPlaceholder(Component):
    class Kwargs:
        pass

    class Slots:
        pass

    def template_data(self, kwargs: Kwargs, slots: Slots) -> dict[str, Any]:  # noqa: ARG002
        return {
            "destinations": [
                CNativeSelectOption("lagoon", "Lagoon station"),
                CNativeSelectOption("shelf", "Shelf station"),
                CNativeSelectOption("slope", "Continental slope"),
            ],
        }

    template = """
      <c-CForm class_="ocean-placeholders">
        <c-CField required>
          <c-fill name="label">Required destination</c-fill>
          <c-fill name="default">
            <c-CNativeSelect
              name="required_destination"
              c-options="destinations"
              placeholder="Choose a destination"
            />
          </c-fill>
          <c-fill name="error">Choose a destination before departure.</c-fill>
        </c-CField>

        <c-CField>
          <c-fill name="label">Optional backup</c-fill>
          <c-fill name="default">
            <c-CNativeSelect
              name="backup_destination"
              c-options="destinations"
              placeholder="No backup destination"
            />
          </c-fill>
        </c-CField>

        <div class="ocean-placeholders__actions">
          <c-CButton type="submit">Validate route</c-CButton>
          <c-CButton type="reset" variant="outline">Reset</c-CButton>
        </div>
      </c-CForm>
    """

    css = """
      :where(.ocean-placeholders) {
        display: grid;
        gap: 1rem;
        max-width: 36rem;
        color: CanvasText;
        font-family: ui-sans-serif, system-ui, sans-serif;
      }

      :where(.ocean-placeholders__actions) {
        display: flex;
        flex-wrap: wrap;
        gap: 0.75rem;
      }
    """


preview = NativeSelectPlaceholder()

preview  # noqa: B018

An empty string selects an existing placeholder. Without a placeholder, None leaves native initial selection to the first enabled option.

Choose a variant

outline, filled, and plain change the closed-control treatment without changing the native picker.

Compare Native Select variants
Show code
from typing import Any

import citry_ui
from citry import Component, citry
from citry_ui import CNativeSelectOption

citry.register_library(citry_ui)


class NativeSelectVariants(Component):
    class Kwargs:
        pass

    class Slots:
        pass

    def template_data(self, kwargs: Kwargs, slots: Slots) -> dict[str, Any]:  # noqa: ARG002
        return {
            "variants": ("outline", "filled", "plain"),
            "depths": [
                CNativeSelectOption("surface", "Surface"),
                CNativeSelectOption("twilight", "Twilight zone"),
                CNativeSelectOption("midnight", "Midnight zone"),
            ],
        }

    template = """
      <section class="ocean-variants">
        <c-for each="variant in variants">
          <c-CField>
            <c-fill name="label">{{ variant.title() }}</c-fill>
            <c-fill name="default">
              <c-CNativeSelect
                c-options="depths"
                c-variant="variant"
                value="twilight"
              />
            </c-fill>
          </c-CField>
        </c-for>
      </section>
    """

    css = """
      :where(.ocean-variants) {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
        gap: 1rem;
        color: CanvasText;
        font-family: ui-sans-serif, system-ui, sans-serif;
      }
    """


preview = NativeSelectVariants()

preview  # noqa: B018

Choose a size

sm, md, and lg adjust visual padding and text size. This size is not the native listbox-size attribute, which the component rejects.

Compare Native Select sizes
Show code
from typing import Any

import citry_ui
from citry import Component, citry
from citry_ui import CNativeSelectOption

citry.register_library(citry_ui)


class NativeSelectSizes(Component):
    class Kwargs:
        pass

    class Slots:
        pass

    def template_data(self, kwargs: Kwargs, slots: Slots) -> dict[str, Any]:  # noqa: ARG002
        return {
            "sizes": ("sm", "md", "lg"),
            "vessels": [
                CNativeSelectOption("tern", "Tern"),
                CNativeSelectOption("albatross", "Albatross"),
                CNativeSelectOption(
                    "bathyscaphe",
                    "Bathyscaphe for the long continental-slope transect",
                ),
            ],
        }

    template = """
      <section class="ocean-sizes">
        <c-for each="size in sizes">
          <c-CField>
            <c-fill name="label">{{ size.upper() }} vessel control</c-fill>
            <c-fill name="default">
              <c-CNativeSelect
                c-options="vessels"
                c-size="size"
                value="bathyscaphe"
              />
            </c-fill>
          </c-CField>
        </c-for>
      </section>
    """

    css = """
      :where(.ocean-sizes) {
        display: grid;
        gap: 1rem;
        max-width: 34rem;
        color: CanvasText;
        font-family: ui-sans-serif, system-ui, sans-serif;
      }
    """


preview = NativeSelectSizes()

preview  # noqa: B018

Use Field and Form states

Required, disabled, and invalid keep their native differences. Native Select does not simulate read-only behavior: a Field requesting read-only rejects this control instead of presenting an editable control as locked.

Compare survey states
Show code
from typing import Any

import citry_ui
from citry import Component, citry
from citry_ui import CNativeSelectOption

citry.register_library(citry_ui)


class NativeSelectStates(Component):
    class Kwargs:
        pass

    class Slots:
        pass

    def template_data(self, kwargs: Kwargs, slots: Slots) -> dict[str, Any]:  # noqa: ARG002
        return {
            "stations": [
                CNativeSelectOption("alpha", "Station Alpha"),
                CNativeSelectOption("beta", "Station Beta"),
                CNativeSelectOption("gamma", "Station Gamma"),
            ],
        }

    template = """
      <section class="ocean-states">
        <c-CField required>
          <c-fill name="label">Required station</c-fill>
          <c-fill name="default">
            <c-CNativeSelect
              name="station"
              c-options="stations"
              placeholder="Choose a station"
            />
          </c-fill>
        </c-CField>
        <c-CField disabled>
          <c-fill name="label">Closed station</c-fill>
          <c-fill name="default">
            <c-CNativeSelect c-options="stations" value="beta" />
          </c-fill>
        </c-CField>
        <c-CField invalid>
          <c-fill name="label">Unverified station</c-fill>
          <c-fill name="default">
            <c-CNativeSelect c-options="stations" value="gamma" />
          </c-fill>
          <c-fill name="error">Confirm the station with bridge control.</c-fill>
        </c-CField>
        <c-CForm disabled>
          <c-CField>
            <c-fill name="label">Survey locked by Form</c-fill>
            <c-fill name="default">
              <c-CNativeSelect c-options="stations" value="alpha" />
            </c-fill>
          </c-CField>
        </c-CForm>
      </section>
    """

    css = """
      :where(.ocean-states) {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
        gap: 1rem;
        color: CanvasText;
        font-family: ui-sans-serif, system-ui, sans-serif;
      }
    """


preview = NativeSelectStates()

preview  # noqa: B018

Control browser selection

Supply client value through $c-props to control current selection. Mirror the native input event to accept user choices. Omit the prop to release control without replacing a valid browser-owned selection.

Control and release a vessel assignment
Show code
from typing import Any

import citry_ui
from citry import Component, citry
from citry_ui import CNativeSelectOption

citry.register_library(citry_ui)


class ControlledNativeSelect(Component):
    class Kwargs:
        pass

    class Slots:
        pass

    def template_data(self, kwargs: Kwargs, slots: Slots) -> dict[str, Any]:  # noqa: ARG002
        return {
            "vessels": [
                CNativeSelectOption("calypso", "Calypso"),
                CNativeSelectOption("nautilus", "Nautilus"),
                CNativeSelectOption("aronnax", "Aronnax"),
            ],
        }

    template = """
      <section
        class="ocean-controlled"
        x-data
        x-init="Alpine.store('nativeSelectFleet', {
          controlled: true,
          vessel: 'nautilus',
        })"
      >
        <c-CField>
          <c-fill name="label">Survey vessel</c-fill>
          <c-fill name="default">
            <c-CNativeSelect
              name="vessel"
              c-options="vessels"
              placeholder="Unassigned"
              $c-props="{
                value: $store.nativeSelectFleet.controlled
                  ? $store.nativeSelectFleet.vessel
                  : undefined,
              }"
              @input="$store.nativeSelectFleet.vessel = $event.target.value"
            />
          </c-fill>
          <c-fill name="description">
            <span
              x-text="$store.nativeSelectFleet.controlled
                ? 'Application controlled'
                : 'Browser controlled'"
            ></span>
          </c-fill>
        </c-CField>

        <div class="ocean-controlled__actions">
          <c-CButton
            type="button"
            size="sm"
            @click="$store.nativeSelectFleet.controlled = false"
          >
            Release
          </c-CButton>
          <c-CButton
            type="button"
            size="sm"
            variant="outline"
            @click="
              $store.nativeSelectFleet.vessel = 'calypso';
              $store.nativeSelectFleet.controlled = true;
            "
          >
            Assign Calypso
          </c-CButton>
          <c-CButton
            type="button"
            size="sm"
            variant="ghost"
            @click="
              $store.nativeSelectFleet.vessel = null;
              $store.nativeSelectFleet.controlled = true;
            "
          >
            Clear
          </c-CButton>
        </div>
      </section>
    """

    css = """
      :where(.ocean-controlled) {
        display: grid;
        gap: 1rem;
        max-width: 36rem;
        color: CanvasText;
        font-family: ui-sans-serif, system-ui, sans-serif;
      }

      :where(.ocean-controlled__actions) {
        display: flex;
        flex-wrap: wrap;
        gap: 0.75rem;
      }
    """


preview = ControlledNativeSelect()

preview  # noqa: B018

Client null selects the placeholder when present, otherwise it means no selection. Invalid or disabled controlled values report once and follow the documented fallback. Native Select adds no value-change callback or custom DOM event.

Keep the platform picker

Citry UI styles the closed root. The browser or operating system owns the open picker, including its layout, scrolling, dismissal, touch behavior, and assistive-technology presentation.

Use native focus, events, and external Form ownership
Show code
from typing import Any

import citry_ui
from citry import Component, citry
from citry_ui import CNativeSelectOption

citry.register_library(citry_ui)


class NativePickerBoundary(Component):
    class Kwargs:
        pass

    class Slots:
        pass

    def template_data(self, kwargs: Kwargs, slots: Slots) -> dict[str, Any]:  # noqa: ARG002
        return {
            "currents": [
                CNativeSelectOption("north", "North Equatorial Current"),
                CNativeSelectOption("counter", "Equatorial Countercurrent"),
                CNativeSelectOption("south", "South Equatorial Current"),
            ],
        }

    template = """
      <section class="ocean-picker" dir="rtl">
        <form id="current-survey"></form>
        <label for="current-select">تيار المحيط</label>
        <c-CNativeSelect
          id="current-select"
          name="current"
          c-options="currents"
          value="counter"
          c-attrs="{'form': 'current-survey', 'dir': 'rtl'}"
          @change="document.querySelector('#picker-value').textContent = $event.target.value"
        />
        <div class="ocean-picker__actions">
          <c-CButton
            type="button"
            size="sm"
            @click="
              const select = document.querySelector('#current-select');
              if (select.showPicker) select.showPicker();
              else select.focus();
            "
          >
            Open native picker
          </c-CButton>
          <output id="picker-value">counter</output>
        </div>
      </section>
    """

    css = """
      :where(.ocean-picker) {
        display: grid;
        gap: 0.75rem;
        max-width: 38rem;
        color: CanvasText;
        font-family: ui-sans-serif, system-ui, sans-serif;
      }

      :where(.ocean-picker__actions) {
        display: flex;
        align-items: center;
        gap: 1rem;
      }

      :where(.ocean-picker output) {
        font-family: ui-monospace, monospace;
      }
    """


preview = NativePickerBoundary()

preview  # noqa: B018

Listen to native input, change, focus, and invalid events directly. Consumers may call native methods such as focus() and, where supported, showPicker() on the root ref. The component does not promise the open picker's DOM or styling.

Customize the theme

Override public variables on an ancestor or one Select. Use the stable part selector for targeted rules.

Theme two expedition controls
Show code
from typing import Any

import citry_ui
from citry import Component, citry
from citry_ui import CNativeSelectOption

citry.register_library(citry_ui)


class NativeSelectThemes(Component):
    class Kwargs:
        pass

    class Slots:
        pass

    def template_data(self, kwargs: Kwargs, slots: Slots) -> dict[str, Any]:  # noqa: ARG002
        return {
            "instruments": [
                CNativeSelectOption("ctd", "CTD profiler"),
                CNativeSelectOption("sonar", "Multibeam sonar"),
                CNativeSelectOption("rov", "Remotely operated vehicle"),
            ],
        }

    template = """
      <section class="ocean-themes">
        <div class="ocean-themes__lagoon">
          <c-CField>
            <c-fill name="label">Lagoon instrument</c-fill>
            <c-fill name="default">
              <c-CNativeSelect c-options="instruments" value="ctd" />
            </c-fill>
          </c-CField>
        </div>
        <div class="ocean-themes__trench" style="color-scheme: dark">
          <c-CField>
            <c-fill name="label">Trench instrument</c-fill>
            <c-fill name="default">
              <c-CNativeSelect
                c-options="instruments"
                value="rov"
                class_="ocean-themes__root"
              />
            </c-fill>
          </c-CField>
        </div>
      </section>
    """

    css = """
      :where(.ocean-themes) {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
        gap: 1rem;
        color: CanvasText;
        font-family: ui-sans-serif, system-ui, sans-serif;
      }

      :where(.ocean-themes > div) {
        padding: 1rem;
        border-radius: 1rem;
      }

      :where(.ocean-themes__lagoon) {
        --cui-native-select-background: #f3feff;
        --cui-native-select-foreground: #103f49;
        --cui-native-select-border-color: #5ca4b0;
        --cui-native-select-hover-border-color: #236b78;
        --cui-native-select-focus-color: #087e8b;
        --cui-native-select-placeholder-color: #52717a;
        --cui-native-select-radius: 1rem;
        --cui-native-select-indicator-size: 0.5rem;
        background: #dff4f6;
      }

      :where(.ocean-themes__trench) {
        --cui-native-select-background: #10262d;
        --cui-native-select-foreground: #e0f7fa;
        --cui-native-select-border-color: #527b86;
        --cui-native-select-hover-border-color: #83bbc6;
        --cui-native-select-focus-color: #76e4f7;
        --cui-native-select-placeholder-color: #a1bdc3;
        --cui-native-select-radius: 0.25rem;
        background: #08191e;
      }

      :where(.ocean-themes__root[data-citry-ui-part="native-select"]:focus-visible) {
        outline-style: double;
      }
    """


preview = NativeSelectThemes()

preview  # noqa: B018

class_ and style target the native root. Unlayered consumer CSS overrides the low-specificity defaults; named layers follow the site-wide Citry UI layer ordering contract.

Accessibility and trust

Keep a visible label even when placeholder text is present. Native Select adds no role, focus proxy, or keyboard handler. Labels, values, names, IDs, and autocomplete hints render as plain text, including trusted-string subclasses. attrs, class_, style, and option/group attrs remain trusted code surfaces for unowned native, ARIA, data, and Alpine attributes.

Use attrs={"form": "survey"} for an external native Form owner. That Form element and ID must remain stable for one Select initialization; rerender the Select when ownership changes. Dynamic form bindings and duplicate case-insensitive spellings are rejected.

API reference

Inputs

CNativeSelect server inputs

Server inputs are passed in a template through <c-CNativeSelect ... /> or in Python through CNativeSelect(...).

InputTypeDefaultEffect
optionsSequence[CNativeSelectItem] (CNativeSelectItem)requiredSets the finite ordered options and one-level groups; canonical option values must be unique.
namenon-empty str | NoneNoneSets the native submitted name; an unnamed Select contributes no FormData entry.
idstr | NonegeneratedUses the Field control ID when composed, otherwise sets or generates native identity.
valuestr | NoneNoneSets initial and reset selection; None or "" selects an existing placeholder, while None without one uses native first-option selection.
placeholdernon-empty str | NoneNoneInserts the enabled first empty-value option and enables native required support.
requiredbool | NoneNoneSets native required state when standalone and requires placeholder; omit it inside CField, which owns the state.
disabledbool | NoneNoneSets local disabled state when standalone; disabled CForm always wins.
invalidbool | NoneNoneSets application invalid state when standalone; omit it inside CField.
autocompletestr | NoneNoneSets the native autofill hint.
variant"outline" | "filled" | "plain" (CNativeSelectVariant)"outline"Selects presentation.
size"sm" | "md" | "lg" (CNativeSelectSize)"md"Selects visual padding and text size; this is not native Select size.
class_str | Mapping[str, bool] | Sequence[CClassValue] | None (CClassValue)NoneAdds native-root classes and merges them with attrs.
stylestr | Mapping[str, str | int | float | bool | None] | Sequence[CStyleValue] | None (CStyleValue)NoneAdds native-root inline styles and merges them with attrs.
attrsMapping[str, object] | NoneNoneAdds native Form ownership, ARIA, data, and trusted Alpine attributes not owned by explicit inputs.

CNativeSelect client inputs

Client inputs are passed in the browser through the $c-props="{ ... }" attribute on <c-CNativeSelect />.

InputTypeOmitted behaviorEffect
valuestring | nullReleases control and preserves the semantic native selection.Controls current selection; null selects the placeholder or no selection, and "" selects an existing placeholder.
requiredbooleanUses the server or Field value.Controls required state when standalone; true requires a placeholder and CField owns the input when composed.
disabledbooleanUses the server, Field, or Form value.Controls local disabled state when standalone; disabled CForm always wins.
invalidbooleanUses the server or Field value.Controls application invalid state; native invalidity still combines with it.
variant"outline" | "filled" | "plain" (CNativeSelectVariant)Uses the server input.Controls presentation.
size"sm" | "md" | "lg" (CNativeSelectSize)Uses the server input.Controls visual padding and text size.

Slots

-

Events

-

Methods

-

CSS

CSS variables to theme the components. Set them on an ancestor or the component itself.

CNativeSelect CSS variables

Apply these variables to CNativeSelect or one of its ancestors.

VariableTypePurposeDefault
--cui-native-select-backgroundcolorNative closed-control background.Canvas, variant adjusted
--cui-native-select-foregroundcolorSelected text and indicator.CanvasText
--cui-native-select-border-colorcolorResting border.Subtle CanvasText mix, variant adjusted
--cui-native-select-hover-border-colorcolorHover border.Stronger CanvasText mix.
--cui-native-select-focus-colorcolorFocus outline and border.Highlight
--cui-native-select-invalid-border-colorcolorInvalid border.Scheme-aware negative color.
--cui-native-select-disabled-backgroundcolorDisabled background.Subtle CanvasText/Canvas mix.
--cui-native-select-placeholder-colorcolorEmpty placeholder text and indicator.Muted CanvasText mix.
--cui-native-select-radiuslengthCorner radius.0.5rem; 0 for plain
--cui-native-select-inline-paddinglengthLogical inline padding.Size-derived length.
--cui-native-select-block-paddinglengthLogical block padding.Size-derived length.
--cui-native-select-font-sizelengthClosed-control text size.Size-derived length.
--cui-native-select-indicator-sizelengthEach indicator triangle and its reserved inline space.0.4rem
--cui-native-select-indicator-gaplengthLogical gap between the indicator and root edge.0.75rem

Attributes

HTML attributes defined on the components that you can refer to for CSS, inspection, and testing. Read-only.

CNativeSelect attributes

AttributeElementTypeMeaning
data-requiredNative Selectpresent | absentMirrors effective required state.
data-disabledNative Selectpresent | absentMirrors effective disabled state.
data-invalidNative Selectpresent | absentMirrors combined application and native invalid state.
data-emptyNative Selectpresent | absentMarks a selected placeholder or semantic no-selection.
data-variantNative Select"outline" | "filled" | "plain"Mirrors effective presentation variant.
data-sizeNative Select"sm" | "md" | "lg"Mirrors effective visual size.

Selectors

Selectors for the DOM nodes in the components that you can use for CSS, inspection, and testing.

CNativeSelect selectors

SelectorElementPurpose
[data-citry-ui-part="native-select"]Native SelectStable root, styling hook, and attrs destination.

Interfaces

Aliases and data shapes referenced above.

Input type aliases

InterfaceDefinition
CClassValuestr | Mapping[str, bool] | Sequence[CClassValue]
CStyleValuestr | Mapping[str, str | int | float | bool | None] | Sequence[CStyleValue]
CNativeSelectVariantLiteral["outline", "filled", "plain"]
CNativeSelectSizeLiteral["sm", "md", "lg"]
CNativeSelectItemCNativeSelectOption | CNativeSelectGroup

CNativeSelectOption

FieldTypeDefaultMeaning
valuestr-Unique nonempty canonical submitted value; CR and CRLF normalize to LF, and U+0000 is invalid.
labelstr-Nonempty plain-text option label.
disabledboolFalseDisables native selection.
attrsMapping[str, object] | NoneNoneAdds trusted unowned native option attributes.

CNativeSelectGroup

FieldTypeDefaultMeaning
labelstr-Nonempty plain-text group label.
optionsSequence[CNativeSelectOption]-Ordered direct options; groups cannot nest.
disabledboolFalseDisables every option in the native group.
attrsMapping[str, object] | NoneNoneAdds trusted unowned native optgroup attributes.

Translation keys

-