Skip to content

HySelect

Usage examples on this page are written for Lit / plain HTML (<hy-select>). The same component ships as HySelect in @whitespaceux/harmony-react (native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.

A customizable select dropdown component that wraps the native HTML select element.

This component accepts slotted native <option> elements which are rendered within a standard <select>. This approach provides enhanced styling, validation states, and accessibility features while maintaining native select behavior.

Examples

html
<hy-select label="Choose a color" placeholder="Select a color">
  <option value="red">Red</option>
  <option value="green">Green</option>
  <option value="blue">Blue</option>
</hy-select>
html
<hy-select label="Country" helper-text="Select your country of residence" required size="large">
  <option value="us">United States</option>
  <option value="ca">Canada</option>
  <option value="uk">United Kingdom</option>
</hy-select>
html
<hy-select label="Priority Level" value="medium" name="priority" size="small">
  <option value="low">Low Priority</option>
  <option value="medium">Medium Priority</option>
  <option value="high">High Priority</option>
  <option value="urgent" disabled>Urgent</option>
</hy-select>
html
<hy-select label="Account Type" invalid error-message="Please select an account type" required>
  <option value="personal">Personal Account</option>
  <option value="business">Business Account</option>
  <option value="enterprise">Enterprise Account</option>
</hy-select>
html
<hy-select
  label="Subscription Plan"
  disabled
  value="free"
  helper-text="Upgrade options are temporarily unavailable"
>
  <option value="free">Free Plan</option>
  <option value="pro">Pro Plan</option>
  <option value="enterprise">Enterprise Plan</option>
</hy-select>
html
<form>
  <hy-select name="department" label="Department" required>
    <option value="sales">Sales</option>
    <option value="marketing">Marketing</option>
    <option value="engineering">Engineering</option>
    <option value="support">Customer Support</option>
  </hy-select>

  <hy-select name="experience" label="Years of Experience" placeholder="Select experience level">
    <option value="0-2">0-2 years</option>
    <option value="3-5">3-5 years</option>
    <option value="6-10">6-10 years</option>
    <option value="10+">10+ years</option>
  </hy-select>
</form>

API

Properties

PropertyAttributeTypeDefaultDescription
labellabelstring''The label text displayed above the select.
helperTexthelper-textstring''Helper text displayed below the select.
valuevaluestring''The current value of the select.
namenamestring''The name attribute for the select.
placeholderplaceholderstring''Placeholder text when no option is selected.
sizesize'small' | 'medium' | 'large''medium'The size variant of the select (small, medium, or large).
layoutlayout'block' | 'inline''block'Row layout: block (default) stacks label above the select; inline puts label on the left and select on the right. Helper/error always sit under the control (col 2–end), never under the label. Set --hy-select-label-column-width on a wrapping container so stacked selects align.
widthwidthstring | undefinedWidth of the select container. Accepts any valid CSS width value (e.g. '400px', '100%', '20rem'). The host fills its container by default; set width to constrain the field. Mirrors hy-text-input.
disableddisabledbooleanfalseDisables the select.
requiredrequiredbooleanfalseMarks the select as required.
clearableclearablebooleanfalseShow a clear button on the trigger once a value is set, so an optional field can return to "nothing selected" with the pointer. Off by default (every surveyed select defaults off), and never shown on a required or disabled select. Keyboard users clear through the placeholder option, which is selectable whenever the select is not required.
clearLabelclear-labelstring'Clear selection'Accessible name of the clear button.
invalidinvalidbooleanfalseMarks the select as invalid.
errorMessageerror-messagestring''Error message displayed when invalid.
autofocusautofocusbooleanfalseMarks this select as the auto-focus target. Read by hy-dialog (and other overlay containers) on show to choose initial focus. Also focuses on first connect when used outside an overlay, mirroring native HTML autofocus but routed through JS so SSR'd HTML doesn't pull focus during hydration.
formHTMLFormElement | null
validityValidityState
validationMessagestring

Events

EventDetailDescription
changeFired when the selected value changes. Detail:
inputFired during value input. Detail:

Slots

SlotDescription
defaultSlot for native option elements that define the available choices
expand-iconCustom dropdown indicator icon (overrides the default chevron)
clear-iconCustom clear-button icon (overrides the default close glyph)

CSS Parts

PartDescription
baseThe select's base wrapper element
labelThe label element
containerThe select input container
selectThe native select element
iconThe dropdown indicator icon
clear-buttonThe clear affordance (rendered when clearable, a value is set, and the select is neither required nor disabled)
helper-textThe helper text element
error-messageThe error message element

CSS Custom Properties

PropertyDescription
--hy-select-focus-ring-widthFocus ring width override
--hy-select-clear-radiusClear-button corner radius
--hy-select-label-column-widthWidth of the label column in layout="inline" mode. No default — set on a wrapping container so stacked selects align.
--hy-select-height-smOuter height for small size variant. Per-component override in the form-control height contract (see .claude/rules/control-heights.md). Default: var(--hy-control-height-sm)
--hy-select-height-mdOuter height for medium size variant. Default: var(--hy-control-height-md)
--hy-select-height-lgOuter height for large size variant. Default: var(--hy-control-height-lg)
--hy-select-hover-durationTransition duration for hover and focus state feedback
--hy-select-hover-easingTransition easing for hover and focus state feedback

Methods

focus()

Sets focus on the select.

Parameters:

  • options - Optional focus options
javascript
const select = document.querySelector('hy-select');
select.focus();

blur()

Removes focus from the select.

javascript
const select = document.querySelector('hy-select');
select.blur();

Built with Lit. Documented with VitePress.