Skip to content
Alpha

Hololink UI is under active development. Components, APIs and these docs may change without notice.

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.

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.
<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>
<holo-select label="Favorite fruit" placeholder="Choose a fruit" invalid error-message="Please select a fruit."></holo-select>
<holo-select label="Favorite fruit" value="apple" disabled></holo-select>

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 native required attribute.

You provide:

  • A label. The aria-label="Select" fallback is not a useful name.
  • A clear errorMessage when invalid.
  • Option labels that are unique and readable.

Importing

import '@philbob-sideprojects/hololink-ui/holo-select';

Properties

PropertyAttributeTypeDefaultDescription
disableddisabledbooleanfalseIf true, the select is disabled and non-interactive.
errorMessageerror-messagestring—Error message shown (and announced) when invalid is true.
invalidinvalidbooleanfalseMarks the select as invalid, applying invalid styling and ARIA attributes.
labellabelstring—The visible label text for the select.
namenamestring—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.
placeholderplaceholderstring—Placeholder text shown as a disabled first option when no value is selected.
requiredrequiredbooleanfalseIf true, a value must be selected for the owning form to submit.
valuevaluestring''The value of the currently selected option.

Events

EventDetailDescription
holoChangestringEmitted when the user selects a different option. detail is the new value.

CSS custom properties

PropertyDescription
--holo-select-bgBackground color of the select.
--holo-select-border-colorBorder color of the select.
--holo-select-border-focusBorder color when focused.
--holo-select-border-hoverBorder color on hover.
--holo-select-colorText color of the select.
--holo-select-error-colorText color of the error message.
--holo-select-focus-ringFocus ring color.
--holo-select-invalid-borderBorder and focus ring color when invalid is true.
--holo-select-label-colorText color of the label.
--holo-select-label-gapSpace between the label and the select.
--holo-select-radiusCorner radius of the select.
--holo-select-required-colorColor of the required indicator.