# pad

> The drum pads' controller from @audio-ui/core: which pads sound, struck by pointer or keyboard, how hard, which ones choke each other, and the grid's one tab stop.

```bash
npm install @audio-ui/core
```

```ts
import { createPadController, KEYBOARD_VELOCITY, MIN_VELOCITY, padTarget, strikeVelocity } from "@audio-ui/core/pad";
```

- Adapters: `@audio-ui/react/pad`, `@audio-ui/elements/pad`

| Export | Kind | What it is |
| --- | --- | --- |
| `createPadController` | function | A grid of pads with no view attached: which pads sound, struck by pointer or keyboard, how hard, which ones choke each other, and where the grid's one tab stop is. |
| `KEYBOARD_VELOCITY` | const | What a pad struck from the keyboard sounds at. |
| `MIN_VELOCITY` | const | The softest a pointer strike plays: the very bottom of a pad, not silence. |
| `PadController` | interface | What `createPadController` returns: the snapshot to draw from, and the strikes, keys and focus moves of the grid. |
| `PadOffEventDetails` | type | What `onPadOff` receives when a pad stops: the reason (`"press"`, `"keyboard"`, or `"choke"` when another pad of its choke group cut it) and the event. |
| `PadOnEventDetails` | type | What `onPadOn` receives with a strike: its `velocity`, from 0 to 1, the reason (`"press"` or `"keyboard"`), the event, and `cancel()` to refuse it. |
| `PadOptions` | interface | The options of `createPadController`: the pads in reading order, the columns of the grid, the pads lit or disabled from elsewhere, and the callbacks. |
| `PadSnapshot` | interface | What a view draws the pads from: the ones sounding and how hard, the tab stop, and whether the grid is disabled. |
| `PadTarget` | interface | A pad as a strike sees it. |
| `padTarget` | function | The index the arrow and Home/End keys move to from `index` in a grid of `count` pads, `columns` to a row: left and right step through the reading order, up and down by a row. |
| `strikeVelocity` | function | How hard a pointer strikes: the force it reports when it can measure one, such as a pen or a pressure-sensitive screen, else where it lands, harder toward the top of the pad. |

## Usage

A pad grid has no value to drag: it reports strikes. The controller holds which pads are sounding and how hard each was struck, and moves the focus around the grid:

```ts
import { createPadController } from "@audio-ui/core/pad";

const pads = createPadController({
  values: ["kick", "snare", "closed-hat", "open-hat"],
  columns: 2,
  onPadOn: (value, details) => drums.hit(value, details.velocity),
  onPadOff: (value) => drums.release(value),
});

element.addEventListener("pointerdown", (event) =>
  pads.press({ value: "open-hat", chokeGroup: "hats" }, event, element)
);
```

`press(pad, event, element)` strikes a pad and holds it until the pointer is released. A pointer strike sounds as hard as the pointer reports, for a pen or a pressure-sensitive screen, or else by where it lands, harder toward the top of the pad and `MIN_VELOCITY` at the very bottom. From the keyboard, Enter or Space strikes the focused pad (`keyOn`) at `KEYBOARD_VELOCITY` until the key is released or the pad loses focus (`keyOff`). Pads that share a `chokeGroup` cut each other off, as an open hi-hat is cut by the closed one.

`navigate(value, event)` moves the focus with the arrows, Home and End, `columns` pads to a row, and returns the pad it moved to; the snapshot's `tabStop` is the one pad in the tab order. `activePads` lights pads from elsewhere, such as the notes a sequence plays, on top of the ones held, and `disabledValues` takes pads out: the arrows step over them.

**In React**

The [Pad](/docs/components/base/pad) draws this controller in React.

**In Vue, Svelte and Web**

[`<audio-ui-pad>`](/docs/elements/pad) draws this controller in your framework.

