Select
Displays a native list of options for the user to pick from.
Areia's Select uses the platform <select> primitive, so it keeps native keyboard, form, and mobile behavior while adding Areia styling and field helpers.
import ilha from "ilha";
import { Select } from "areia";
export default ilha.render(() => (
<Select
id="fruit"
label="Fruit"
value="apple"
items={{
apple: "Apple",
banana: "Banana",
cherry: "Cherry",
}}
/>
));Import
import { Select } from "areia";
Usage
import ilha from "ilha";
import { Select } from "areia";
export default ilha.render(() => (
<Select
id="plan"
label="Plan"
placeholder="Choose a plan"
items={{
free: "Free",
pro: "Pro",
team: "Team",
}}
/>
));Examples
Basic
A select with a visible label. When you provide the label prop, the select renders with a field wrapper and label above it.
import ilha from "ilha";
import { Select } from "areia";
export default ilha.render(() => (
<Select
id="basic-fruit"
label="Fruit"
value="apple"
items={{
apple: "Apple",
banana: "Banana",
cherry: "Cherry",
}}
/>
));Sizes
Use the size prop to match Input sizing: xs, sm, base, and lg.
import ilha from "ilha";
import { Select } from "areia";
const items = {
apple: "Apple",
banana: "Banana",
cherry: "Cherry",
};
export default ilha.render(() => (
<div class="flex w-full max-w-sm flex-col gap-3">
<Select
size="xs"
aria-label="Extra small select"
value="apple"
items={items}
/>
<Select
size="sm"
aria-label="Small select"
value="apple"
items={items}
/>
<Select
size="base"
aria-label="Base select"
value="apple"
items={items}
/>
<Select
size="lg"
aria-label="Large select"
value="apple"
items={items}
/>
</div>
));Without Visible Label
When a visible label is not needed, use aria-label for accessibility.
import ilha from "ilha";
import { Select } from "areia";
export default ilha.render(() => (
<Select
aria-label="Select fruit"
value="banana"
items={{
apple: "Apple",
banana: "Banana",
cherry: "Cherry",
}}
/>
));With Description and Error
Select can show description text and validation errors. Error styling is automatically applied when the error prop is truthy.
Choose the category that best matches your report.
import ilha from "ilha";
import { Select } from "areia";
export default ilha.render(() => (
<Select
id="issue-type"
label="Issue type"
description="Choose the category that best matches your report."
error="Select an issue type before continuing."
placeholder="Choose an issue type"
items={{
bug: "Bug",
documentation: "Documentation",
feature: "Feature",
}}
/>
));Placeholder
Use the placeholder prop to render a placeholder option before the selectable items.
import ilha from "ilha";
import { Select } from "areia";
export default ilha.render(() => (
<Select
id="priority"
label="Priority"
placeholder="Choose priority"
items={{
low: "Low",
medium: "Medium",
high: "High",
critical: "Critical",
}}
/>
));Label with Tooltip
Use labelTooltip to add additional context via a native title attribute on the label.
import ilha from "ilha";
import { Select } from "areia";
export default ilha.render(() => (
<Select
id="severity"
label="Severity"
labelTooltip="Choose the highest impact level that applies."
placeholder="Choose severity"
items={{
low: "Low",
medium: "Medium",
high: "High",
critical: "Critical",
}}
/>
));Disabled
import ilha from "ilha";
import { Select } from "areia";
export default ilha.render(() => (
<Select
label="Fruit"
disabled
value="apple"
items={{
apple: "Apple",
banana: "Banana",
cherry: "Cherry",
}}
/>
));Multiple Selection
Enable native multiple selection with the multiple prop. The select becomes a multi-row native control.
Hold Command or Control to select multiple options.
import ilha from "ilha";
import { Select } from "areia";
export default ilha.render(() => (
<Select
id="columns"
label="Columns"
multiple
description="Hold Command or Control to select multiple options."
items={{
name: "Name",
location: "Location",
size: "Size",
read: "Read",
write: "Write",
createdAt: "Created At",
}}
/>
));Disabled Options
Options can be disabled with descriptor objects in the items prop.
import ilha from "ilha";
import { Select } from "areia";
export default ilha.render(() => (
<Select
id="plan-disabled"
label="Plan"
value="free"
items={{
free: "Free",
pro: "Pro",
business: { label: "Business", disabled: true },
enterprise: { label: "Enterprise", disabled: true },
}}
/>
));Options as Children
Use Select.Option when you want explicit control over individual option markup.
import ilha from "ilha";
import { Select } from "areia";
export default ilha.render(() => (
<Select
id="explicit-options"
label="Fruit"
placeholder="Choose fruit"
>
<Select.Option value="apple" label="Apple" />
<Select.Option value="banana" label="Banana" />
<Select.Option value="cherry" label="Cherry" />
</Select>
));Grouped Options
Use Select.Group to organize related options under native optgroup labels.
import ilha from "ilha";
import { Select } from "areia";
export default ilha.render(() => (
<Select
id="grouped-food"
label="Food"
placeholder="Choose food"
>
<Select.Group label="Fruits">
<Select.Option value="apple" label="Apple" />
<Select.Option value="banana" label="Banana" />
</Select.Group>
<Select.Group label="Vegetables">
<Select.Option value="carrot" label="Carrot" />
<Select.Option value="lettuce" label="Lettuce" />
</Select.Group>
</Select>
));Ghost Variant
Use variant: "ghost" for compact UIs where the select should blend into the surrounding surface.
import ilha from "ilha";
import { Select } from "areia";
export default ilha.render(() => (
<Select
variant="ghost"
aria-label="Sort by"
value="updated"
items={{
updated: "Recently updated",
created: "Recently created",
name: "Name",
}}
/>
));API Reference
Select
Select accepts standard HTML select attributes plus the following props.
| Prop | Type | Default | Description |
|---|---|---|---|
class | string | - | Additional CSS classes applied to the select. |
className | string | - | Alias for class. |
size | "xs" | "sm" | "base" | "lg" | "base" | Size of the select. Matches Input component sizes. |
variant | "default" | "error" | "ghost" | "default" | Visual variant. |
label | unknown | - | Label content for the select. Enables the field wrapper. |
placeholder | string | - | Placeholder option shown before selectable items. |
items | Record<string, SelectItemValue> | Array<{ label: unknown; value: unknown; disabled?: boolean }> | - | Data structure of items rendered as options. |
children | unknown | - | Explicit option markup. Prefer the second Select argument for options. |
| second argument | unknown[] | - | Option markup, usually Select.Option(...) or Select.Group(...) calls. |
description | unknown | - | Helper text displayed below the select. |
error | unknown | { message: unknown; match?: unknown } | - | Error message. When truthy, error styling is automatically applied. |
disabled | boolean | - | Whether the select is disabled. |
required | boolean | - | Whether the select is required. When false, shows optional text. |
multiple | boolean | - | Enables native multiple selection. |
Select.Root and Select.Static are aliases for the base native select renderer.
Select.Option
| Prop | Type | Default | Description |
|---|---|---|---|
label | unknown | - | Option content. |
value | unknown | - | Option value. |
disabled | boolean | - | Whether the option cannot be selected. |
class | string | - | Additional CSS classes. |
className | string | - | Alias for class. |
Select.Group
Groups related options together with a native optgroup.
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | - | Visible optgroup label. |
| second argument | unknown[] | - | Option markup. |
disabled | boolean | - | Whether every option in the group is disabled. |
Select.Separator
Select.Separator() renders a disabled option that can be used as a simple divider in native selects.
Accessibility
Label Requirement
Selects should have an accessible name via one of:
labelproparia-labelfor selects without a visible labelaria-labelledbyfor custom label association
Native Behavior
Because Select uses the native <select> primitive, it keeps browser-provided keyboard navigation, form submission, and mobile picker behavior.
Error Association
When an id is provided, descriptions and error messages are automatically associated with the select using aria-describedby.