# comboboxFilter

> Adapts `@remix-run/ui/combobox`'s input behavior onto a ComboBox's text input: narrows the popup's options to the typed text, moves the active option with arrow keys, and commits or clears the draft on blur and `Escape`, mirroring the result as `aria-activedescendant` and `aria-expanded`.

```ts
import { comboboxFilter } from "@sdxc/ui/mixins";
```

Turns a ComboBox's text input into the as-you-type filter for its popup
option list by delegating typing, arrow-key movement, and blur/`Escape`
commit to `@remix-run/ui/combobox`'s `input()` primitive.

## Signature

```ts
comboboxFilter(): MixinDescriptor<HTMLInputElement>
```

## Examples

```tsx
<combobox.Context name="airport">
  <input mix={[inputStyle, comboboxFilter()]} placeholder="Search airports" />
  <div mix={[popoverStyle, combobox.popover()]}>
    <div mix={[listStyle, combobox.list()]}>
      {airports.map((airport) => (
        <div key={airport.value} mix={[optionStyle, combobox.option(airport)]}>{airport.label}</div>
      ))}
    </div>
  </div>
</combobox.Context>
```

## Used with it

The events, constants and types its module publishes, each imported from `@sdxc/ui/mixins` too.

### ComboboxFilterChangeEvent

Dispatched on a ComboBox's input by comboboxFilter whenever the
filter text, active option, or open state moves, letting a consumer
react to live narrowing without reading `@remix-run/ui/combobox`'s context.

#### Signature

```ts
new ComboboxFilterChangeEvent(init: { activeOptionId: string | null; filterText: string; isOpen: boolean })
```

#### Properties

| Property | Type | Description |
| --- | --- | --- |
| `activeOptionId` | `readonly string \| null` | Id of the option `Enter` would commit right now, or `null` when none is active. |
| `filterText` | `readonly string` | Draft text the popup's options are currently narrowed by. |
| `isOpen` | `readonly boolean` | `true` while the popup is open and showing the narrowed option list. |
