hx components Select - bradwoo8621/hx GitHub Wiki
HxSelect / HxWithCheckSelect
Dropdown select with optional filtering, sorting, and clearing. Uses HxPopup internally for positioning.
HxWithCheckSelect adds validation (see WithCheck).
Long selected labels truncate with an ellipsis (single line).
// Static options
<HxSelect $model={form} $field="country" options={[
{ value: 'us', label: 'United States' },
{ value: 'cn', label: 'China' },
]} />
// Async with filter and clear button
<HxSelect
$model={form} $field="user"
options={async (search) => fetchUsers(search)}
filter
clearable
/>
// Auto-show filter when options exceed 5
<HxSelect
$model={form} $field="city"
options={cityList}
filterWhenOptionExceed={5}
/>
// Full configuration
<HxSelect
$model={form} $field="product"
options={productOpts}
filter
sort
clearable
placeholder="Select a product..."
minPopupWidth={300}
maxPopupHeight={400}
zIndex={1050}
gapToEdge={4}
/>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
$model |
HxObject<T> |
— | Reactive model |
$field |
ModelPath<T> | HxDataPath |
— | Model field path |
options |
HxSelectOptions<T> |
— | Options source (see Common) |
clearable |
boolean |
— | Show a clear/X button to reset the value |
filter |
boolean |
— | Show filter text input inside the popup |
sort |
boolean |
— | Sort options alphabetically by label |
selectedLabel |
(option: HxSelectOption) => ReactNode |
— | Render the closed control's label from the selected option (an option's own selectedLabel field still takes precedence) |
placeholder |
boolean |
true |
Show the placeholder when nothing selected (true uses the default i18n key; custom text goes through placeholderKey) |
showSelectedOnPopupOpen |
boolean |
true |
Scroll to / highlight the current selection on open |
filterWhenOptionExceed |
number |
8 |
Auto-enable filter when total options > this count |
minPopupWidth |
number |
— | Minimum popup width (px) |
maxPopupHeight |
number |
258 |
Maximum popup height (px) |
zIndex |
number |
— | Popup z-index |
gapToEdge |
number |
— | Gap between trigger and popup (px) |
Popup Props (HxSelectPopup)
| Prop | Type | Default | Description |
|---|---|---|---|
optionsOnLoadKey |
i18n key | '~HxCommon.OnLoading' |
Label while async options load |
noOptionsKey |
i18n key | '~HxCommon.NoOptions' |
Label when no options match |
filterPlaceholderKey |
i18n key | '~HxCommon.Filter' |
Filter input placeholder |
Keyboard Navigation
- Arrow Up / Down — Navigate options (uses DOM attribute manipulation to avoid re-renders on large lists)
- Enter — Select highlighted option
- Escape — Close popup
- Tab — Focus trapped within popup (cycles between filter input and options)
Internal Event System
The select uses EventEmitter for trigger-popup communication:
EvtHxSelect_OptionSelect— option clicked/selectedEvtHxSelect_HoverPreviousOption— Arrow UpEvtHxSelect_HoverNextOption— Arrow DownEvtHxSelect_SelectHoverOption— Enter on highlightedEvtHxSelect_ClosePopup— Escape or click outside
Native DOM Events
The trigger input and popup forward all standard DOM events, but in practice you rarely need them — selection is managed by $model/$field binding, and keyboard navigation is handled internally. Use onFocus/onBlur if you need to track focus state.
Global Config
import { configHxSelect } from '@hx/components';
configHxSelect({
filterWhenOptionExceed: 8,
maxPopupHeight: 258,
showSelectedOnPopupOpen: true,
});