brumate/ui

ComboBox

A text field with a list of suggestions, which shows the items that match what was typed.

Selected: none.

<script>
  import { $bind, $signal } from 'brumate/signals';
  import Button from '@brumate/ui/Button.brm';
  import ComboBox from '@brumate/ui/ComboBox.brm';
  import Input from '@brumate/ui/Input.brm';
  import Label from '@brumate/ui/Label.brm';
  import ListBox from '@brumate/ui/ListBox.brm';
  import ListBoxItem from '@brumate/ui/ListBoxItem.brm';
  import Popover from '@brumate/ui/Popover.brm';
  import type { Key } from '@brumate/ui/collection.ts';

  let animal = $signal<Key | null>(null);
  const animals = ['Aardvark', 'Cat', 'Dog', 'Kangaroo', 'Koala', 'Panda', 'Penguin', 'Snake'];
</script>

<ComboBox class="ui-select" name="animal" selectedKey=$bind(animal)>
  <Label>Favorite animal</Label>
  <div class="ui-combobox-box">
    <Input class="ui-input" placeholder="Type to search" />
    <Button class="ui-button ui-select-button" />
  </div>
  <Popover class="ui-popover ui-select-popover">
    <ListBox class="ui-listbox">
      #for (name of animals by name) {
        <ListBoxItem id=(name.toLowerCase()) class="ui-option">{name}</ListBoxItem>
      }
    </ListBox>
  </Popover>
</ComboBox>
<p>Selected: {animal ?? 'none'}.</p>
<ComboBox name="animal" selectedKey=$bind(animal)>
  <Label>Favorite animal</Label>
  <Input />
  <Button />
  <Popover>
    <ListBox>
      <ListBoxItem id="cat">Cat</ListBoxItem>
      <ListBoxItem id="dog">Dog</ListBoxItem>
    </ListBox>
  </Popover>
</ComboBox>

Typing and choosing

Closing

Forms

name sends the key of the selected item with its form, or the text of the input with allowsCustomValue. formValue="key" or "text" chooses. The value goes with the form also before the code of the page loads. A server error for the name in a Form shows in the FieldError until the selection changes.

How it filters

The items are on the page while the list is open, so the ComboBox hides those that do not match, and the keys skip hidden items. A section with no item left is hidden too. To filter the items yourself, such as from a server, bind inputValue and render only the items that you want in a #for.