Pad Grid
pad-gridControlsRows of rubber pads are labelled and lit from the state you pass in. Velocity depends on where the press lands: the top edge gives a full-force hit and the bottom edge the softest, so a player can aim a tap. Choke groups are both drawn and obeyed. Pads that cut each other share a tie mark based on the same membership function the engine uses to decide what to silence. A pad can be deliberately silent (pressed, no voice) or empty (drawn, not playable); both look different from idle. Layout, hit testing and the velocity law live in a pure geometry module beside the component.
Install
Copies the source into your project. Anything it depends on comes with it.
$ pnpm dlx shadcn@latest add @pluginui/core-pad-gridPulls in
First time? Add the registry to your components.json once:
{
"registries": {
"@pluginui": "https://pluginui.com/r/{name}.json"
}
}Usage
Connect the documented props to your application or host.
import { PadGrid } from "@/components/ui/pad-grid"
<PadGrid
rows={4}
columns={4}
pads={pads.map((pad) => ({
label: pad.role,
sublabel: String(pad.note),
state: held.get(pad.note) ? "active" : "idle",
chokeGroup: pad.chokeGroup,
}))}
onPadDown={(index, strike) => noteOn(pads[index].note, strike.velocity)}
onPadUp={(index) => noteOff(pads[index].note)}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
| rows / columns | number | — | The layout; pads are index-aligned row-major from the top-left. |
| pads | { label?, sublabel?, state?, chokeGroup?, ariaLabel? }[] | — | Pad content and state: idle, active, silent or empty. Short arrays leave the rest empty. |
| onPadDown / onPadUp | (index, strike) => void / (index) => void | — | Strike with velocity and landing position; release. |
| width / height / gap / padding / radius | number | — | viewBox geometry; the rendered size is CSS's business. |
| showChoke | boolean | — | Draw the choke-group tie marks. |
Interaction
- Drag with pointer capture, so the gesture keeps tracking past the edge of the control.
- Shift while dragging for a fine pass; release it mid-gesture and coarse tracking resumes.
- Double-click resets to
defaultValue. - Arrow keys step normally, Shift+arrow steps finely, PageUp/PageDown jump by ten, Home/End go to the extremes.
- Proper
sliderandswitchroles with livearia-valuetext, so a screen reader announces the formatted value rather than the raw number. - The scroll wheel adjusts the value while the pointer is over the control; stepped ranges move at least one declared step per notch by default.