Native Select
Anatomy
Thin wrapper around the native HTML <select> element with consistent styling. Provides a chevron icon overlay and integrates with the Input component's visual design.
maud_ui::primitives::native_select
Props
Generated from public Rust fields. Defaults are evaluated from the implementation.
| Prop | Type | Default | Description |
|---|---|---|---|
name | String | "" | No description |
id | String | "" | No description |
options | Vec<NativeOption> | [] | No description |
selected | Option<String> | None | No description |
disabled | bool | false | No description |
placeholder | Option<String> | None | No description |
required | bool | false | Participate in native constraint validation when no option is chosen. |
invalid | bool | false | No description |
aria_describedby | Option<String> | None | Existing hints/errors; field-feedback preserves these references. |
Examples
Usage and composition
Import
use maud_ui::primitives::native_select::{self, NativeSelectProps, NativeOption};
Example
use maud::html;
use maud_ui::primitives::native_select;
html! {
div class="mui-field" {
label class="mui-label" for="country" { "Country" }
(native_select::render(native_select::NativeSelectProps {
name: "country".to_string(),
id: "country".to_string(),
options: vec![
native_select::NativeOption {
value: "us".to_string(),
label: "United States".to_string(),
disabled: false,
},
native_select::NativeOption {
value: "ca".to_string(),
label: "Canada".to_string(),
disabled: false,
},
native_select::NativeOption {
value: "mx".to_string(),
label: "Mexico".to_string(),
disabled: false,
},
],
selected: Some("us".to_string()),
disabled: false,
placeholder: None,
..Default::default()
}))
}
}
NativeOption
| Field | Type | Description |
|---|---|---|
| value | String | Value submitted when this option is selected. |
| label | String | Text displayed to the user. |
| disabled | bool | When true, this option cannot be selected. |
Variants
| Variant | Configuration | Use Case |
|---|---|---|
| Default | Single selected option, no placeholder | Pre-selected choice (currency, timezone). |
| With placeholder | placeholder: Some("Select...") | Force user to make an explicit choice. |
| Disabled | disabled: true | Read-only field; user cannot change the value. |
| Disabled options | Some options have disabled: true | Certain choices are unavailable. |
| Multiple options | Large option list | Extensive choices (country, state, category). |
Helpers
None. The component is a minimal semantic wrapper around the native <select> element.
Design Notes
NativeSelect uses the native <select> element intentionally, not a custom dropdown component. This approach ensures:
- Browser consistency: Users experience familiar platform-specific select behavior.
- Mobile optimization: Touch devices open native picker UI.
- Accessibility: Native semantics are stronger than custom components.
- Keyboard support: Built-in keyboard navigation is instant, no JavaScript required.
The chevron icon is purely decorative and does not indicate open/closed state (browser handles that).
Related
Input, Native Textarea, Label, Dropdown Menu.
Shadcn reference
https://ui.shadcn.com/docs/components/base/select
Validation (0.14.0)
NativeSelectProps implements Default and accepts required, invalid and aria_describedby. Set required: true with an empty placeholder for payment methods or other mandatory choices. The native select now participates in browser constraints; form::Props.feedback keeps the failure beside the field and focuses it. invalid and aria_describedby also support server-rendered feedback without JavaScript. Exhaustive older literals must add these fields or ..Default::default(). A supplied selected option no longer leaves the placeholder selected as well.
Accessibility
- Label association: Use a
<label>element withformatching the select'sid. - Chevron icon: Marked with
aria-hidden="true"so screen readers ignore the decorative SVG. - Native control: Leverages native browser
<select>behavior; keyboard navigation (arrow keys) is handled by the browser. - Disabled state: Sets
disabledattribute; screen readers announce "disabled" state. - Placeholder: When present, the placeholder option is marked
disabledandhidden, ensuring it cannot be selected after the user chooses another option.