# xypad

> The XY pad's controller from @audio-ui/core: two parameters on one gesture, a point dragged, stepped per axis, typed per axis and reset.

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

```ts
import { createXYPadController, LARGE_STEP_MULTIPLIER, STATE_ATTRIBUTES_MAPPING, toPercent } from "@audio-ui/core/xypad";
```

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

| Export | Kind | What it is |
| --- | --- | --- |
| `createXYPadController` | function | A pad's behavior with no view attached: its point, held or controlled, every way of moving it, and what it looks like as a snapshot. |
| `XYPadChangeEventDetails` | type | What `onValueChange` receives with each change: the reason, the event behind it, and `cancel()` to refuse the change. |
| `XYPadChangeEventReason` | type | Why the value changed: `"press"`, `"drag"`, `"keyboard"`, `"wheel"`, `"input-change"` (a typed value) or `"reset"`. |
| `XYPadCommitEventDetails` | type | What `onValueCommitted` receives once a gesture ends: the reason and the event behind it. |
| `XYPadCommitEventReason` | type | Why the value was committed: the same reasons as a change. |
| `XYPadController` | interface | What `createXYPadController` returns: the snapshot to draw from, and the press, keys, wheel, typed values and reset that move the point. |
| `XYPadOptions` | interface | The options of `createXYPadController`: the point, held or controlled, each axis's range and step, the formatting and the callbacks. |
| `XYPadPoint` | interface | A point on the pad, in the units of each axis. |
| `XYPadSnapshot` | interface | What a view draws a pad from. |
| `Axis` | type | One of the pad's two axes. |
| `LARGE_STEP_MULTIPLIER` | const | Shift + arrows and Page Up/Down move this many steps at once. |
| `STATE_ATTRIBUTES_MAPPING` | const | Only `disabled` and `dragging` become data attributes; the numbers stay in `state`. |
| `toPercent` | function | Where `value` sits between `min` and `max`, from 0 to 1. |

## Usage

The controller follows the [contract](/docs/core/controllers) every controller shares: create it once, draw from its snapshot, send it the input.

```ts
import { createXYPadController } from "@audio-ui/core/xypad";

const pad = createXYPadController({ minX: 0, maxX: 1, minY: 0, maxY: 1, value: { x: 0.5, y: 0.5 }, stepX: 0.01, stepY: 0.01 });
```

| Option | Meaning |
| --- | --- |
| `value`, `defaultValue` | A point, `{ x, y }` |
| `minX`, `maxX`, `stepX`, `minY`, `maxY`, `stepY` | Each axis's range and grid |
| `format`, `locale`, `disabled` | Formats each axis separately, as `formatted.x` and `formatted.y` |

A pad has two parameters on one gesture. `type(axis, value, event)` takes the axis first, because a text input is per axis. Shift with the arrows, and Page Up and Page Down, move ten steps at once (`LARGE_STEP_MULTIPLIER`). `reset(event)` returns both axes to their defaults: the element calls it on a double-click, and the controller itself resets on Alt with a press and on Delete or Backspace. A double tap is not a reset here, since a tap on a pad places the point, so two quick taps are two points and not a request to go back.

**In React**

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

**In Vue, Svelte and Web**

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

