Select
A native <select> styled as a bordered, rounded field and progressively upgraded with customizable-select rendering.
View code
// The change bubbles, so the listener sits on the wrapper the field renders into.
<div mix={[on<HTMLDivElement, "change">("change", readRegion)]}>
<Label htmlFor="preview-region">Primary region</Label>
<Select id="preview-region" name="region" color="brand">
<Select.Trigger>
<Select.Value />
</Select.Trigger>
{Object.entries(regions).map(([group, entries]) => (
<Select.Group key={group} label={group}>
{entries.map((entry) => (
<Select.Option key={entry.code} value={entry.code} selected={entry.code === code}>
{entry.city}
</Select.Option>
))}
</Select.Group>
))}
</Select>
<Text>Median latency from Madrid: {selected.latency}</Text>
</div>Installation
An ordinary dependency: install it, import the theme once, and import the component where it is used.
npm add @sdxc/uiimport "@sdxc/ui/theme.css";Usage
import { Select } from "@sdxc/ui";Renders a native <select> styled as a bordered, rounded field that
progressively upgrades to customizable-select rendering via
appearance: base-select, falling back to the platform's own dropdown.
Composition
The parts the component publishes, each a static property of the host.
SelectSelect.TriggerRenders Select's customizable trigger: a native<button>placed as Select's first child, showing Select.Value and a rotating chevron by default, filling the field's box edge to edge.Select.ValueRenders a native<selectedcontent>element inside Select.Trigger, mirroring the currently selected Select.Option's content via the platform;childrenrender as a fallback where it's treated as unknown.Select.OptionRenders a native<option>styled for the rounded, padded row a supporting browser shows inside Select's::picker(select)dropdown, reading its own hover, focus, checked, and disabled states.Select.GroupRenders a native<optgroup>styled as a padded run of Select.Options, set off from the group before it by a block-start divider on every group after the first.
Examples
<Select aria-label={t("form.plan.label")} color="brand">
<Select.Trigger />
<Select.Group label={t("form.plan.groups.personal")}>
<Select.Option value="free">{t("plans.free")}</Select.Option>
<Select.Option value="pro">{t("plans.pro")}</Select.Option>
</Select.Group>
</Select>Props
Read from the component's own types, so every prop, every default and every allowed value is listed.
| Prop | Type | Description |
|---|---|---|
color? | "brand" | "neutral" | "success" | "warning" | "danger" | Semantic color role for the focus-visible ring. Defaults to DEFAULT_COLOR. |
Also accepts everything in Omit<TagProps<"select">, "role" | "defaultValue" | "value">.
Select.Trigger
Also accepts everything in TagProps<"button">.
Select.Value
Also accepts everything in TagProps<"selectedcontent">.
Select.Option
Also accepts everything in TagProps<"option">.
Select.Group
Also accepts everything in TagProps<"optgroup">.
Types
| Name | Values | What it decides |
|---|---|---|
Color | "brand" | "neutral" | "success" | "warning" | "danger" | Semantic color role, each mapped to its matching --ui-* variables. |