Holo Select
The <holo-select> component is a form-associated custom element that wraps a native <select> in
its shadow root, styled to match the design system. Wrapping (rather than reimplementing) a native
listbox gives full native keyboard, screen-reader, and mobile picker-UI behavior for free. Set the
options property (an array of { value, label, disabled? } objects) from JavaScript.
When to use
Section titled “When to use”Use it for:
- Choosing one value from a medium to long list (roughly eight or more options) where showing every option would be heavy.
- A form field that submits with a form and needs native pickers on mobile.
Don’t use it for:
- Short sets where seeing all options helps. Use Radio.
- Selecting several values. Use Checkboxes.
- Command lists. Use Menu.
Live Previews
Section titled “Live Previews”Default
Section titled “Default”<holo-select label="Favorite fruit" placeholder="Choose a fruit"></holo-select><script> const select = document.querySelector('holo-select'); select.options = [ { value: 'apple', label: 'Apple' }, { value: 'banana', label: 'Banana' }, { value: 'pear', label: 'Pear', disabled: true }, ];</script>Invalid
Section titled “Invalid”<holo-select label="Favorite fruit" placeholder="Choose a fruit" invalid error-message="Please select a fruit."></holo-select>Disabled
Section titled “Disabled”<holo-select label="Favorite fruit" value="apple" disabled></holo-select>Accessibility
Section titled “Accessibility”The component renders a native <select> with a <label> and <option>s from the options array, so role, popup and typing behaviour come from the browser. The label is linked with aria-labelledby. Without a label the select falls back to aria-label="Select". required, disabled and aria-invalid are applied to the native element, and the component is form-associated through ElementInternals. When invalid with an errorMessage, the message is shown in a role="alert" element referenced by aria-describedby. A placeholder is a hidden first option (disabled when required).
| Key | Action |
|---|---|
Tab |
Moves focus to or from the select |
ArrowDown, ArrowUp |
Changes the value (or moves through the open list, depending on browser) |
Enter, Space |
Opens the list and confirms a choice (browser dependent) |
| Letter keys | Jump to a matching option |
Esc |
Closes the open list |
- Key behaviour follows the browser’s native
<select>. It varies by platform. - A visible focus ring is shown with
:focus-visible. - The required marker is
aria-hidden. Required state is exposed through the nativerequiredattribute.
You provide:
- A
label. Thearia-label="Select"fallback is not a useful name. - A clear
errorMessagewheninvalid. - Option labels that are unique and readable.
API Reference
Section titled “API Reference”Importing
import '@philbob-sideprojects/hololink-ui/holo-select';Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
disabled | disabled | boolean | false | If true, the select is disabled and non-interactive. |
errorMessage | error-message | string | — | Error message shown (and announced) when invalid is true. |
invalid | invalid | boolean | false | Marks the select as invalid, applying invalid styling and ARIA attributes. |
label | label | string | — | The visible label text for the select. |
name | name | string | — | The form field name submitted with the owning form. |
options | — | SelectOption[] | [] | The list of selectable options, each { value: string; label: string; disabled?: boolean }.
Set it as a JavaScript property; it has no attribute. |
placeholder | placeholder | string | — | Placeholder text shown as a disabled first option when no value is selected. |
required | required | boolean | false | If true, a value must be selected for the owning form to submit. |
value | value | string | '' | The value of the currently selected option. |
Events
| Event | Detail | Description |
|---|---|---|
holoChange | string | Emitted when the user selects a different option. detail is the new value. |
CSS custom properties
| Property | Description |
|---|---|
--holo-select-bg | Background color of the select. |
--holo-select-border-color | Border color of the select. |
--holo-select-border-focus | Border color when focused. |
--holo-select-border-hover | Border color on hover. |
--holo-select-color | Text color of the select. |
--holo-select-error-color | Text color of the error message. |
--holo-select-focus-ring | Focus ring color. |
--holo-select-invalid-border | Border and focus ring color when invalid is true. |
--holo-select-label-color | Text color of the label. |
--holo-select-label-gap | Space between the label and the select. |
--holo-select-radius | Corner radius of the select. |
--holo-select-required-color | Color of the required indicator. |