Select
Select components are used to create a dropdown list of options.
<Select label="Label" name="example-1" options={[ { value: null, label: '- Select -' }, { value: 'option-a', label: 'Option A' }, { value: 'option-b', label: 'Option B' }, { value: 'option-c', label: 'Option C' }, ]}/>
<div class="field-group" data-layout="FieldGroup" data-component="Select"> <label for="example-1" id="label-example-1"> <span class="field-label">Label</span> </label> <select id="example-1" name="input-example-1" aria-labelledby="label-example-1" > <option>- Select -</option> <option value="option-a">Option A</option> <option value="option-b">Option B</option> <option value="option-c">Option C</option> </select></div>
API Reference
This component inherits from the Field Group component.
This component is based on the <select>
element and can take in any additional HTML attributes through the use of the inputProps
property. The following are the custom props that can be passed to the component.
Prop | Type | Default |
---|---|---|
name * | string | — |
label * | string | — |
options * | [{ value: string, label: string }] | — |
labelHidden | boolean | false |
sublabel | string | — |
instructions | string | — |
placeholder | string | — |
disabled | boolean | false |
required | boolean | "long" | false |
inputProps | HTMLAttributes<select> | — |
errorMessages | string[] | — |
Accessibility
The <Select>
component is designed with accessibility in mind and extends much of the accessibility features from the <Field Group>
component. The following are some of the field specific accessibility features that are included in the component and worth considering:
- The
aria-labelledby
attribute is used to associate thelabel
andinstructions
elements with the input field. This is an important consideration specifically for the instructions so that they are read out by screen readers when the field is focused, rather than after the input field.
Examples
Required
Use the required
prop to mark a field as required. You can also use the required
prop to mark a field as required and include explicit “required” text by passing the value "long"
.
<Select label="Label" name="example-2" options={[ { value: null, label: '- Select -' }, { value: 'option-a', label: 'Option A' }, { value: 'option-b', label: 'Option B' }, { value: 'option-c', label: 'Option C' }, ]} required/><Select label="Label" name="example-3" options={[ { value: null, label: '- Select -' }, { value: 'option-a', label: 'Option A' }, { value: 'option-b', label: 'Option B' }, { value: 'option-c', label: 'Option C' }, ]} required="long"/>
<div class="field-group" data-required="" data-layout="FieldGroup" data-component="Select"> <label for="example-2" id="label-example-2"> <span class="field-label">Label</span> </label> <select id="example-2" name="input-example-2" required="" aria-labelledby="label-example-2" > <option>- Select -</option> <option value="option-a">Option A</option> <option value="option-b">Option B</option> <option value="option-c">Option C</option> </select></div><div class="field-group" data-required="long" data-layout="FieldGroup" data-component="Select"> <label for="example-3" id="label-example-3"> <span class="field-label">Label</span> </label> <select id="example-3" name="input-example-3" required="" aria-labelledby="label-example-3" > <option>- Select -</option> <option value="option-a">Option A</option> <option value="option-b">Option B</option> <option value="option-c">Option C</option> </select></div>
Disabled
Use the disabled
prop to disable the select.
<Select label="Label" name="example-4" options={[ { value: null, label: '- Select -' }, { value: 'option-a', label: 'Option A' }, { value: 'option-b', label: 'Option B' }, { value: 'option-c', label: 'Option C' }, ]} disabled/>
<div class="field-group" data-layout="FieldGroup" data-component="Select"> <label for="example-4" id="label-example-4"> <span class="field-label">Label</span> </label> <select id="example-4" name="input-example-4" disabled="" aria-labelledby="label-example-4" > <option>- Select -</option> <option value="option-a">Option A</option> <option value="option-b">Option B</option> <option value="option-c">Option C</option> </select></div>
With Helper Text
Use the sublabel
and instructions
props to add helper text to the select.
<Select label="Label" name="example-5" options={[ { value: null, label: '- Select -' }, { value: 'option-a', label: 'Option A' }, { value: 'option-b', label: 'Option B' }, { value: 'option-c', label: 'Option C' }, ]} sublabel="Sublabel lorem ipsum dolor sit amet." instructions="Instructions lorem ipsum dolor."/>
<div class="field-group" data-layout="FieldGroup" data-component="Select"> <label for="example-5" id="label-example-5"> <span class="field-label">Label</span> <span class="field-sublabel"> Sublabel lorem ipsum dolor sit amet. </span> </label> <select id="example-5" name="input-example-5" aria-labelledby="label-example-5 instructions-example-5" > <option>- Select -</option> <option value="option-a">Option A</option> <option value="option-b">Option B</option> <option value="option-c">Option C</option> </select> <span class="field-instructions" id="instructions-example-5"> Instructions lorem ipsum dolor. </span></div>
With Errors
Use the errorMessages
prop to display error messages below the select.
- Error message 1
- Error message 2
<Select label="Label" name="example-6" options={[ { value: null, label: '- Select -' }, { value: 'option-a', label: 'Option A' }, { value: 'option-b', label: 'Option B' }, { value: 'option-c', label: 'Option C' }, ]} errorMessages={['Error message 1', 'Error message 2']}/>
<div class="field-group" data-state="error" data-layout="FieldGroup" data-component="Select"> <label for="example-6" id="label-example-6"> <span class="field-label">Label</span> </label> <select id="example-6" name="input-example-6" aria-labelledby="label-example-6" > <option>- Select -</option> <option value="option-a">Option A</option> <option value="option-b">Option B</option> <option value="option-c">Option C</option> </select> <ul class="field-errors"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="absolute left-0 top-2 size-16 shrink-0" > <line x1="12" y1="9" x2="12" y2="13"></line> <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path> <line x1="12" y1="17" x2="12.01" y2="17"></line> </svg> <li>Error message 1</li> <li>Error message 2</li> </ul></div>
With Hidden Label
Use the labelHidden
prop to visually hide the label. When hidden, the label will still be available to screen readers.
<Select label="Label" name="example-6" options={[ { value: null, label: '- Select -' }, { value: 'option-a', label: 'Option A' }, { value: 'option-b', label: 'Option B' }, { value: 'option-c', label: 'Option C' }, ]} labelHidden/>
<div class="field-group" data-layout="FieldGroup" data-component="Select"> <label for="example-6" id="label-example-6"> <span class="field-label sr-only">Label</span> </label> <select id="example-6" name="input-example-6" aria-labelledby="label-example-6" > <option>- Select -</option> <option value="option-a">Option A</option> <option value="option-b">Option B</option> <option value="option-c">Option C</option> </select></div>
Astro Component
It’s recommended that an element like this is made as a reusable component. In this case, we have put together the following Astro component to serve as a blueprint for how you could possibly set up a select component, and what properties to consider.
---import type { ComponentProps, HTMLAttributes } from 'astro/types'import FieldGroup from '@/components/forms/FieldGroup.astro'
interface Props extends ComponentProps<typeof FieldGroup> { /** The array of options to display in the dropdown */ options: [{ label: string; value: string }] /** Whether the input field is disabled or not */ disabled?: boolean /** Additional props to pass into the input field */ inputProps?: HTMLAttributes<'select'>}
const { options, disabled = false, inputProps, ...fieldGroupProps} = Astro.props---
<FieldGroup data-component="Select" {...fieldGroupProps}> <select id={fieldGroupProps.name} name={`input-${fieldGroupProps.name}`} disabled={disabled} required={fieldGroupProps.required === true || fieldGroupProps.required === 'long'} aria-labelledby={`label-${fieldGroupProps.name}${ fieldGroupProps.instructions ? ` instructions-${fieldGroupProps.name}` : '' }`} {...inputProps} > { options.map((option) => ( <option value={option.value}>{option.label}</option> )) } </select></FieldGroup>