# filterMenuKeys

> Why JS: a filterable picker is typed into and steered from its filter field, and only script hears those keys.

```ts
import { filterMenuKeys } from "@sdxc/ui/app";
```

Applied to the list's root: listens for typing and keys in the filter field, changes to the
row and tab inputs, and pointer moves over rows, and hands each to `handlers`. Escape is
taken from the search field, so it closes the menu instead of only clearing the text.

## Signature

```ts
filterMenuKeys(handlers: FilterMenuKeys.Handlers): MixinDescriptor<HTMLElement>
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| `handlers` | `FilterMenuKeys.Handlers` |  |

## Examples

```tsx
<div mix={[filterMenuKeys({ input: "refs-filter", onFilter, onMove, onChoose, onClose, onTab, onPick, onHover })]}>…</div>
```

## Used with it

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

### FILTER_MENU_ROW_SLOT

The slot every row of the list carries, with its entry's key in `data-key`.

#### Signature

```ts
const FILTER_MENU_ROW_SLOT = "filter-menu-row"
```

### FilterMenuKeys.Handlers

What the list does for each gesture; the latest handlers always answer.

#### Members

| Member | Type | Description |
| --- | --- | --- |
| `input` | `string` | The filter field's id; typing and keys count only there. |
| `onFilter` | `void` | The filter field's text changed. |
| `onMove` | `void` | ↓ (`1`) or ↑ (`-1`) moved the highlighted row. |
| `onChoose` | `void` | Enter picked the highlighted row. |
| `onClose` | `void` | Escape closed the menu, whatever the field holds. |
| `onTab` | `void` | A tab radio, marked `data-tab-index`, was chosen. |
| `onPick` | `void` | A row's radio or checkbox changed. |
| `onHover` | `void` | The pointer moved onto the row whose key this is. |
