Pad

A grid of drum pads struck by pointer, touch or keyboard, with velocity and choke groups.

Audio UI

Triggers sounds, for a drum machine, a sampler or a clip launcher. The registry component wraps the Pad primitive from @audio-ui/react and lays the pads out in a grid of columns.

Overview

  • Events: onPadOn(value, eventDetails) and onPadOff(value, eventDetails) report the pad's value, ready for an audio engine. eventDetails.velocity says how hard it was struck, from 0 to 1, and eventDetails.cancel() in onPadOn keeps the pad silent.
  • Velocity: a pen or a pressure-sensitive screen strikes as hard as it presses. Other pointers strike harder toward the top of the pad. The keyboard strikes at 0.8. Each pad exposes its last velocity as --pad-velocity, so the flash can follow it.
  • Choke groups: pads sharing a chokeGroup stop each other, like a closed hihat cutting an open one. Striking one fires onPadOff with reason: "choke" for the last pad struck in its group, held or still ringing.
  • Pointer: each pointer holds its own pad, so several play at once on a touch screen. Sliding off a pad does not strike the next one.
  • External pads: activePads lights pads from outside, such as the steps of a sequencer, without calling onPadOn or onPadOff.
  • Accessibility: each pad is a button named by its content, behind one tab stop. The arrow keys move between pads, and Space or Enter holds the focused pad until it is released.

Installation

pnpm dlx shadcn@latest add @audio-ui/pad

Anatomy

Import the primitive and assemble its parts.

import { Pad } from "@audio-ui/react";

<Pad.Root>
  <Pad.Item value="kick">Kick</Pad.Item>
</Pad.Root>

Usage

import { Pad, PadItem } from "@/components/audio-ui/pad";

Pad events:

<Pad
  aria-label="Drum pads"
  columns={2}
  onPadOn={(value, { velocity }) => sampler.trigger(value, velocity)}
>
  <PadItem value="kick">Kick</PadItem>
  <PadItem value="snare">Snare</PadItem>
</Pad>

Choke groups (a closed hat cuts the open one):

<Pad
  aria-label="Hats"
  columns={2}
  onPadOff={(value, { reason }) => {
    if (reason === "choke") {
      sampler.stop(value);
    }
  }}
  onPadOn={(value, { velocity }) => sampler.trigger(value, velocity)}
>
  <PadItem chokeGroup="hat" value="closed-hat">
    Closed hat
  </PadItem>
  <PadItem chokeGroup="hat" value="open-hat">
    Open hat
  </PadItem>
</Pad>

Interaction

Pointer

Behavior · 3

Press a pad
Fires onPadOn with a velocity; the pad stays active while held.
Release
Fires onPadOff.
Multiple pointers
Each pointer (finger) holds its own pad, so several play at once on touch devices.

Keyboard

The pads share one tab stop. On the focused pad:

Keys · 4

ArrowLeft / ArrowRight
Move focus to the previous / next pad in reading order
ArrowUp / ArrowDown
Move focus a row up / down
Space / Enter
Hold the focused pad: onPadOn on press, onPadOff on release
Home / End
Move focus to the first / last pad

API reference

Root

A grid of pads to strike: each one sounds while held, by pointer or from the keyboard, and each pointer holds its own pad, so several can be played at once on a touch screen. A strike is harder where a pen or screen presses harder, or else toward the top of the pad. The pads are one tab stop: the left and right arrows walk them in reading order, the up and down arrows by a row of columns. Renders a <div> element.

Props · 5

Data attributes · 1

data-disabled
Present when disabled.

Item

One pad. It sounds while held: by pointer, or with Enter or Space while focused. Its accessible name comes from its content, or aria-label. How hard it was last struck is the --pad-velocity CSS variable, from 0 to 1. Renders a <button> element.

Props · 3

Data attributes · 2

data-active
Whether the pad is sounding: held here, or listed in activePads.
data-disabled
Present when disabled.

Registry component

Pad accepts className and style plus primitive props from PadPrimitive.Root.Props, and sets the grid's columns from columns. PadItem accepts the props of PadPrimitive.Item.

Additional valid HTML attributes passed to Pad.Root and Pad.Item are forwarded.

Examples

Drum rack

Sixteen pads, each its own sound: strike a pad to play and select it, then shape it with the knobs. The three hihats share a choke group.

Audio UI

More Shadcn Pad components

Browse 2 production-ready audio/ui Pad components for players, mixers, and synth interfaces. These examples use the headless primitives from @audio-ui/react and stay fully compatible with Shadcn Create so radius, color, and typography match your configured theme.

Browse all 2 Shadcn Pad components for copy-ready layouts, dashboards, and forms built with Tailwind CSS in the audio/ui library.

Built by Ouest Labs, the source code is available on GitHub.
RSS