Skip to content

ComboBox

A text input that filters a list of options.

ComboBox.tsx
import {ComboBox, ComboBoxItem} from 'alinea/components'

export function ComboBoxExample() {
  return (
    <ComboBox label="Related product" defaultValue="chair" style={{width: 280}}>
      <ComboBoxItem value="shirt">Linen shirt</ComboBoxItem>
      <ComboBoxItem value="chair">Oak dining chair</ComboBoxItem>
      <ComboBoxItem value="throw">Wool throw</ComboBoxItem>
      <ComboBoxItem value="table">Walnut side table</ComboBoxItem>
    </ComboBox>
  )
}

Groups and descriptions

Group items under a label with ComboBoxGroup. Like SelectItem, a ComboBoxItem can show an icon and a description below its label. Values are strings or numbers: onValueChange receives the value of the picked item, typed like the value you pass.

ComboBoxGroups.tsx
import {ComboBox, ComboBoxGroup, ComboBoxItem} from 'alinea/components'
import {
  IcRoundDescription,
  IcRoundFeed,
  IcRoundImage
} from 'alinea/dashboard/icons'

export function ComboBoxGroupsExample() {
  return (
    <ComboBox label="Link to" style={{width: 280}}>
      <ComboBoxGroup label="Pages">
        <ComboBoxItem value="about" icon={IcRoundDescription}>
          About us
        </ComboBoxItem>
        <ComboBoxItem
          value="collection"
          icon={IcRoundImage}
          description="Products of the summer collection"
        >
          Summer collection
        </ComboBoxItem>
      </ComboBoxGroup>
      <ComboBoxGroup label="Blog">
        <ComboBoxItem
          value="care"
          icon={IcRoundFeed}
          description="Published last week"
        >
          Caring for linen
        </ComboBoxItem>
      </ComboBoxGroup>
    </ComboBox>
  )
}

Load items as you type

To search on a server, pass filter={false} so every item you render is shown, and loading while a request runs: it shows a spinner in the input, and in the list while it is empty. useAsyncList loads the items for the text in the input and cancels a request when a newer one replaces it. A function as filter replaces the default matching instead: (textValue, inputValue) => boolean.

ComboBoxAsync.tsx
import {ComboBox, ComboBoxItem, useAsyncList} from 'alinea/components'

const products = [
  {id: 'shirt', title: 'Linen shirt'},
  {id: 'chair', title: 'Oak dining chair'},
  {id: 'throw', title: 'Wool throw'},
  {id: 'table', title: 'Walnut side table'},
  {id: 'lamp', title: 'Ceramic table lamp'}
]

// Stands in for a search request to your own API
async function searchProducts(text: string) {
  await new Promise(resolve => setTimeout(resolve, 400))
  const query = text.toLowerCase()
  return products.filter(product => product.title.toLowerCase().includes(query))
}

export function ComboBoxAsyncExample() {
  const list = useAsyncList({
    async load({filterText}) {
      return {items: await searchProducts(filterText)}
    }
  })
  return (
    <ComboBox
      label="Related product"
      inputValue={list.filterText}
      onInputValueChange={list.setFilterText}
      filter={false}
      loading={list.loading}
      emptyMessage="No products found"
      style={{width: 280}}
    >
      {list.items.map(product => (
        <ComboBoxItem key={product.id} value={product.id}>
          {product.title}
        </ComboBoxItem>
      ))}
    </ComboBox>
  )
}

Props

<ComboBox>

A labelled text input that filters a list of options to pick from

PropTypeDefaultDescription
valueV | nullDefault –The value of the selected ComboBoxItem
defaultValueV | nullDefault –
onValueChange(value: V | null) => voidDefault –Called with the selected value, or null when the selection is cleared
inputValuestringDefault –
defaultInputValuestringDefault –
onInputValueChange(value: string) => voidDefault –
placeholderstringDefault –
allowsCustomValuebooleanDefault –Keep text that does not match an item instead of reverting it on blur
emptyMessageReactNodeDefault –Shown in the list when no item matches, the list stays closed if unset
filterfalse | ((textValue: string, inputValue: string) => boolean)Default –Whether an item is shown for the typed text, defaults to a case and accent insensitive match anywhere in its text. Pass false to show every item, eg. when the server already filtered them.
loadingbooleanDefault –Shows a spinner, eg. while the items for the typed text load
namestringDefault –Name of the hidden form input carrying the value
autoFocusbooleanDefault –

<ComboBoxItem>

PropTypeDefaultDescription
value*KeyDefault –
textValuestringDefault –Text used for filtering and the input, defaults to string children
disabledbooleanDefault –
iconIconType | ReactElementDefault –Icon shown before the label in the list
descriptionReactNodeDefault –Secondary text shown below the label in the list

Also accepts className and style.

<ComboBoxGroup>

PropTypeDefaultDescription
labelReactNodeDefault –

Also accepts id and aria-* labelling attributes.