hono-preact
Overview
Quick Start
The Route Table
Layouts & Nesting
Adding Pages
Head Management
Active Links
Server Loaders
Loading States
Reloading Data
Prefetching
Streaming
Live Loaders
Realtime Channels
Server Actions
Validation
Optimistic UI
Server Caller
View Transitions
Middleware
CSRF Protection
CLI
Vite Config
Project Structure
Styling
Composing Hono Middleware
WebSockets
Rooms & Presence
renderPage
Link Prefetch
Build & Deploy
Overview
Dialog
Popover
Tooltip
Menu
Context Menu
Select
Combobox
Toast
renderElement
useControllableState
mergeRefs
useListNavigation
useTypeahead
useListboxSelection
usePosition
usePositioner
useDismiss
useFocusReturn

useListboxSelection#

useListboxSelection is the selection core shared by Select and Combobox. It owns single- and multi-select value tracking, an option registry that resolves display labels in DOM order (so a closed control can show the selected label without rendering its list), and hidden form-field serialization. Reach for it when building a custom listbox-style control that needs the same selection semantics as the built-in components.

See also: useListNavigation, Select, Combobox.

Demo#

  • Apple
  • Banana
  • Cherry
  • Date

selected: (none)

Signature#

import { useListboxSelection } from 'hono-preact-ui';

function useListboxSelection<Value = string>(
  opts: UseListboxSelectionOptions<Value>
): ListboxSelection;

Options#

OptionTypeNotes
valuesreadonly Value[]The selected values; [] when nothing is selected.
setValues(next: Value[]) => voidCalled with the next selection array (a one-element array on a single-select pick).
multiplebooleanWhether multiple options can be selected.
setOpen(open: boolean) => voidCalled to close the control after a single-select choice.
isValueEqual(a: Value, b: Value) => booleanOptional. Custom equality; defaults to Object.is.
serializeValue(value: Value) => stringOptional. Serializes a value for the hidden form field.
itemToString(value: Value) => stringOptional. Resolves a display label when no option is registered for a value.
namestringOptional. Hidden form-field name; enables native form submission.
disabledbooleanOptional. Disables selection.

Result#

MemberTypeNotes
isSelected(optionValue: unknown) => booleanWhether a value is currently selected.
toggle(optionValue: unknown) => voidSelect or deselect a value (closes the control in single-select).
registerOption(id, value, label) => () => voidRegister an option in the label registry; returns a cleanup fn.
selectedLabels() => string[]Selected labels in registry (DOM) order.
selectedItems() => OptionEntry[]Selected options in value order, labels resolved via the registry.
labelFor(value: unknown) => stringResolve a single value's display label.
optionCountnumberNumber of currently-registered options.
hiddenFieldsComponentChild[] | nullHidden <input>s for native form submission, or null.

normalizeSelectionProps#

normalizeSelectionProps is the pure helper that maps Select's and Combobox's public value / defaultValue / onValueChange props (discriminated on multiple, see Select's Usage section) onto the array-shaped values / setValues that useListboxSelection consumes. Reach for it when building a custom control that wants the same single/multiple discriminated prop contract as the built-in components, feeding the result into your own useListboxSelection call.

import { normalizeSelectionProps } from 'hono-preact-ui';
import type { SelectionProps, NormalizedSelection } from 'hono-preact-ui';

function normalizeSelectionProps<Value>(
  p: SelectionProps<Value>
): NormalizedSelection<Value>;

NormalizedSelection<Value> always represents selection as an array: values/defaultValues are readonly Value[] (undefined values means uncontrolled), and onValuesChange wraps the caller's onValueChange so a single-mode caller still gets Value | null ([] -> null) while a multiple-mode caller gets the Value[] it passed in. Memoize the result per render: a single-mode value wraps into a fresh array each call, which would otherwise churn downstream callback identities.