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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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(...).
| Input | Type | Default | Effect |
|---|---|---|---|
options | Sequence[CNativeSelectItem] (CNativeSelectItem) | required | Sets the finite ordered options and one-level groups; canonical option values must be unique. |
name | non-empty str | None | None | Sets the native submitted name; an unnamed Select contributes no FormData entry. |
id | str | None | generated | Uses the Field control ID when composed, otherwise sets or generates native identity. |
value | str | None | None | Sets initial and reset selection; None or "" selects an existing placeholder, while None without one uses native first-option selection. |
placeholder | non-empty str | None | None | Inserts the enabled first empty-value option and enables native required support. |
required | bool | None | None | Sets native required state when standalone and requires placeholder; omit it inside CField, which owns the state. |
disabled | bool | None | None | Sets local disabled state when standalone; disabled CForm always wins. |
invalid | bool | None | None | Sets application invalid state when standalone; omit it inside CField. |
autocomplete | str | None | None | Sets 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) | None | Adds native-root classes and merges them with attrs. |
style | str | Mapping[str, str | int | float | bool | None] | Sequence[CStyleValue] | None (CStyleValue) | None | Adds native-root inline styles and merges them with attrs. |
attrs | Mapping[str, object] | None | None | Adds 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 />.
| Input | Type | Omitted behavior | Effect |
|---|---|---|---|
value | string | null | Releases control and preserves the semantic native selection. | Controls current selection; null selects the placeholder or no selection, and "" selects an existing placeholder. |
required | boolean | Uses the server or Field value. | Controls required state when standalone; true requires a placeholder and CField owns the input when composed. |
disabled | boolean | Uses the server, Field, or Form value. | Controls local disabled state when standalone; disabled CForm always wins. |
invalid | boolean | Uses 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.
| Variable | Type | Purpose | Default |
|---|---|---|---|
--cui-native-select-background | color | Native closed-control background. | Canvas, variant adjusted |
--cui-native-select-foreground | color | Selected text and indicator. | CanvasText |
--cui-native-select-border-color | color | Resting border. | Subtle CanvasText mix, variant adjusted |
--cui-native-select-hover-border-color | color | Hover border. | Stronger CanvasText mix. |
--cui-native-select-focus-color | color | Focus outline and border. | Highlight |
--cui-native-select-invalid-border-color | color | Invalid border. | Scheme-aware negative color. |
--cui-native-select-disabled-background | color | Disabled background. | Subtle CanvasText/Canvas mix. |
--cui-native-select-placeholder-color | color | Empty placeholder text and indicator. | Muted CanvasText mix. |
--cui-native-select-radius | length | Corner radius. | 0.5rem; 0 for plain |
--cui-native-select-inline-padding | length | Logical inline padding. | Size-derived length. |
--cui-native-select-block-padding | length | Logical block padding. | Size-derived length. |
--cui-native-select-font-size | length | Closed-control text size. | Size-derived length. |
--cui-native-select-indicator-size | length | Each indicator triangle and its reserved inline space. | 0.4rem |
--cui-native-select-indicator-gap | length | Logical 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
| Attribute | Element | Type | Meaning |
|---|---|---|---|
data-required | Native Select | present | absent | Mirrors effective required state. |
data-disabled | Native Select | present | absent | Mirrors effective disabled state. |
data-invalid | Native Select | present | absent | Mirrors combined application and native invalid state. |
data-empty | Native Select | present | absent | Marks a selected placeholder or semantic no-selection. |
data-variant | Native Select | "outline" | "filled" | "plain" | Mirrors effective presentation variant. |
data-size | Native 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
| Selector | Element | Purpose |
|---|---|---|
[data-citry-ui-part="native-select"] | Native Select | Stable root, styling hook, and attrs destination. |
Interfaces
Aliases and data shapes referenced above.
Input type aliases
| Interface | Definition |
|---|---|
CClassValue | str | Mapping[str, bool] | Sequence[CClassValue] |
CStyleValue | str | Mapping[str, str | int | float | bool | None] | Sequence[CStyleValue] |
CNativeSelectVariant | Literal["outline", "filled", "plain"] |
CNativeSelectSize | Literal["sm", "md", "lg"] |
CNativeSelectItem | CNativeSelectOption | CNativeSelectGroup |
CNativeSelectOption
| Field | Type | Default | Meaning |
|---|---|---|---|
value | str | - | Unique nonempty canonical submitted value; CR and CRLF normalize to LF, and U+0000 is invalid. |
label | str | - | Nonempty plain-text option label. |
disabled | bool | False | Disables native selection. |
attrs | Mapping[str, object] | None | None | Adds trusted unowned native option attributes. |
CNativeSelectGroup
| Field | Type | Default | Meaning |
|---|---|---|---|
label | str | - | Nonempty plain-text group label. |
options | Sequence[CNativeSelectOption] | - | Ordered direct options; groups cannot nest. |
disabled | bool | False | Disables every option in the native group. |
attrs | Mapping[str, object] | None | None | Adds trusted unowned native optgroup attributes. |
Translation keys
-