Select
A native dropdown styled to match Input. The platform handles the picker, typeahead and keyboard.
New projects start in this theme.
Theme: system
Choose where files are stored.
Set by your workspace owner.
Usage
use hydroxy_leptos::select::{Select, SelectOption};
use leptos::prelude::*;
pub fn demo() -> AnyView {
let (theme, set_theme) = signal(String::from("system"));
let themes = vec![
SelectOption::new("system", "Match the system"),
SelectOption::new("light", "Light"),
SelectOption::new("dark", "Dark"),
];
let (region, set_region) = signal(String::new());
view! {
<div style="display: grid; gap: var(--space-7); max-width: 360px;">
// Controlled.
<Select
label="Default theme"
options=themes
value=theme
on_change=move |v| set_theme.set(v)
hint="New projects start in this theme."
/>
<p style="margin: 0; font: var(--text-sm); color: var(--text-2);">"Theme: " {theme}</p>
// Uncontrolled, with validation.
<Select
label="Data region"
options=vec![
SelectOption::new("", "Choose a region"),
SelectOption::new("eu", "Europe (Frankfurt)"),
SelectOption::new("us", "United States (Virginia)"),
]
on_change=move |v| set_region.set(v)
error=Signal::derive(move || region.get().is_empty().then(|| "Choose where files are stored.".to_string()))
required=true
name="region"
/>
<Select
label="Billing currency"
options=vec![SelectOption::new("gbp", "GBP (£)")]
disabled=true
hint="Set by your workspace owner."
/>
</div>
}
.into_any()
}use dioxus::prelude::*;
use hydroxy_dioxus::select::{Select, SelectOption};
#[component]
pub fn SelectDemo() -> Element {
let mut theme = use_signal(|| String::from("system"));
let mut region = use_signal(String::new);
let region_error = region().is_empty().then(|| "Choose where files are stored.".to_string());
rsx! {
div { style: "display: grid; gap: var(--space-7); max-width: 360px;",
Select {
label: "Default theme",
options: vec![
SelectOption::new("system", "Match the system"),
SelectOption::new("light", "Light"),
SelectOption::new("dark", "Dark"),
],
value: theme(),
on_change: move |v| theme.set(v),
hint: "New projects start in this theme.",
}
p { style: "margin: 0; font: var(--text-sm); color: var(--text-2);", "Theme: {theme}" }
Select {
label: "Data region",
options: vec![
SelectOption::new("", "Choose a region"),
SelectOption::new("eu", "Europe (Frankfurt)"),
SelectOption::new("us", "United States (Virginia)"),
],
on_change: move |v| region.set(v),
error: region_error,
required: true,
name: "region",
}
Select {
label: "Billing currency",
options: vec![SelectOption::new("gbp", "GBP (£)")],
disabled: true,
hint: "Set by your workspace owner.",
}
}
}
}
Anatomy
| Component | data-part | Renders |
|---|---|---|
Select | root | Wrapper. data-invalid, data-disabled |
Select | label | <label for> the control |
Select | field | Positions the chevron over the control |
Select | control | Native <select>. aria-describedby the hint or error, aria-invalid on error |
Select | icon | Chevron. Ignores the pointer, so clicks reach the select |
Select | hint | Help text. Hidden while there is an error |
Select | error | Error text |
Keyboard
| Key | Does |
|---|---|
Space / Enter / Alt+ArrowDown | Opens the platform picker |
ArrowUp / ArrowDown | Moves through the options |
Letters | Jumps to the next option starting with them |
Props
| Prop | Type | Notes |
|---|---|---|
label | String | Required. Visible label |
options | Vec<SelectOption> | Required. SelectOption::new(value, label) |
value | Option<String> | Controlled value. Pair with on_change |
default_value | String | Initial value when uncontrolled. Defaults to the first option |
on_change | Callback<String> | Called with the chosen value |
hint | Option<String> | Help text under the field |
error | Option<String> | Replaces the hint and marks the field invalid |
disabled | bool | Block changes |
name | String | Form field name |
required | bool | Native required |