Skip to content

Select

A labeled native select with flat options, option groups, a placeholder option, and standard field accessibility.

Import

import { Select } from "@hyzer-labs/ui"

Demo

Select vs Combobox

Reach for Select when your option set is small and static: single-select, or multi-select via the native multiple attribute. Use Combobox when there are many options (where filtering or virtualization helps), or when you need search and type-to-filter.

The placeholder is a disabled leading option, so it cannot be re-selected once a real choice is made. Disabled options stay visible but inert.

const putters: SelectOption[] = [
	{ value: 'aviar', label: 'Aviar' },
	{ value: 'luna', label: 'Luna' },
	{ value: 'judge', label: 'Judge' },
	{ value: 'zone', label: 'Zone (out of stock)', disabled: true }
];

<Select name="putter" label="Putter" options={putters} bind:value={putter} placeholder="Pick a putter" />

Props

NameTypeDefaultNote
namestringRequired. Form field name.
labelstringRequired. Always in the DOM; sr-only with hideLabel.
optionsSelectOption[]Required. Flat options and optgroups mix freely — see SelectOption below.
multiplebooleanfalseRenders the native multiple attribute; switches value to string[].
valuestring | string[]'' (single) / [] (multiple)Bindable. A discriminated union on multiple: string when omitted/false, string[] when true.
placeholderstring'Select...'Rendered as a disabled leading option.
descriptionstringHelp text below the label.
errorstringInline error message; sets the error state.
requiredbooleanfalse
disabledbooleanfalse
hideLabelbooleanfalse
classstringMerged after the hz-field class.

SelectOption (flat arm: FormOption)

NameTypeDefaultNote
valuestringRequired.
labelstringRequired.
disabledboolean

SelectOption (group arm)

NameTypeDefaultNote
groupstringGroup form: renders an <optgroup> with this label.
optionsFormOption[]Group form: the flat options inside the group.

Theme hooks

What this component promises your CSS. The reference theme styles exactly these — from @layer hz-theme, so your unlayered rules win. See Styling Components for the how.

Root class: .hz-field

Data attributes

HookValuesStyles
data-state'default' | 'error' | 'disabled'The universal field state hook, on the root. Precedence is fixed: error beats disabled.

Part classes

HookValuesStyles
.hz-field-labelchild elementThe label.
.hz-field-requiredchild elementThe required marker.
.hz-field-descriptionchild elementThe hint text.
.hz-field-errorchild elementThe error message.

Accessibility

The select is associated with its label via id/for. With hideLabel, the label stays in the DOM as screen-reader-only text.

description and error chain into aria-describedby, description first. required sets aria-required, and an error sets aria-invalid.

The control is the native <select>, so keyboard and assistive-tech behavior come from the platform.

References: MDN: <select>