A two-dimensional control for two parameters at once, with pointer, wheel and keyboard input.
Base UI
"use client";
import { useState } from "react";Controls two values at once, such as filter cutoff and resonance, pan and mix, or two macros. The registry component wraps the XYPad primitive from @audio-ui/react and adds a grid, a crosshair, a cursor and a value display.
minX, maxX, stepX; minY, maxY, stepY).--xy-pad-x (from the left) and --xy-pad-y (from the top).<input type="range"> per axis. Both carry the accessible name (aria-label becomes "… X" and "… Y", or set each with getAriaLabel on the primitive's Thumb). The X input takes focus, and the arrow keys move both axes.Import the primitive and assemble its parts.
import { XYPad } from "@audio-ui/react";
<XYPad.Root>
<XYPad.Label />
<XYPad.Control>
<XYPad.Thumb />
</XYPad.Control>
<XYPad.Value />
</XYPad.Root>import { XYPad } from "@/components/audio/xypad";Uncontrolled: set only the initial value.
<XYPad
defaultValue={{ x: 0, y: 0 }}
maxX={100}
maxY={1}
minX={-100}
minY={-1}
stepX={1}
stepY={0.01}
/>Controlled: drive the value from state.
const [position, setPosition] = useState({ x: 50, y: 50 });
<XYPad
maxX={100}
maxY={100}
minX={0}
minY={0}
onValueChange={setPosition}
onValueCommitted={(value, details) => console.log("Committed:", value, details.reason)}
value={position}
/>Behavior · 4
eventDetails.reason "press" then "drag".stepX / stepY.onValueCommitted fires when a gesture that changed the value ends.value updates late. Reject a value with eventDetails.cancel().On the focused pad:
Keys · 5
stepXstepYstepY × 10minX / maxXWheel and trackpad input over the pad moves the point by the scrolled distance: scrolling up raises Y, scrolling right raises X. Reported as eventDetails.reason === "wheel".
Groups all parts of the pad and owns its two-dimensional value. Exposes the value position as CSS variables for crosshairs and guides: --xy-pad-x (from the left) and --xy-pad-y (from the top), as percentages. Renders a <div> element.
Props · 14
XYPad.Value and the inputs' aria-valuetext.name.x and name.y.Data attributes · 2
data-disableddata-draggingThe pad surface: a press jumps the value to the pointer and a drag follows it; the mouse wheel / trackpad moves it too. Sets touch-action: none so touch drags don't scroll the page. Renders a <div> element.
Data attributes · 2
data-disableddata-draggingMarks the value on the pad (left/top as percentages, centered with translate). Holds two native <input type="range">s, one per axis: the X input takes focus, both carry the accessible name, and the arrow keys move both axes. Renders a <div> element.
Props · 2
aria-label followed by "X" / "Y".aria-valuetext. Defaults to the formatted value.Data attributes · 2
data-disableddata-draggingThe formatted value (format/locale on Root), "x, y" by default. Renders a <output> element.
Props · 1
Data attributes · 2
data-disableddata-draggingAccessible label, associated with both axis inputs. Renders a <div> element.
Data attributes · 2
data-disableddata-draggingXYPad accepts style props (size, formatValue, valueDisplay, className) plus primitive props from XYPadPrimitive.Root.Props. aria-label, aria-labelledby, and aria-describedby are forwarded to the axis inputs.
Props · 12
format.eventDetails.reason is "press", "drag", "keyboard", "wheel", or "input-change"; call eventDetails.cancel() to reject it.Props · 4
"hidden" to hide the overlay.@audio-ui/react/xypad exposes XYPad.Root, XYPad.Control (the pad surface), XYPad.Thumb (positioned at the value, holds the axis inputs), XYPad.Value (formatted <output>), and XYPad.Label. Every part accepts a render prop, className / style as functions of state, and exposes data-disabled / data-dragging. Draw grids and crosshairs with your own elements and the --xy-pad-x / --xy-pad-y variables.
Base UI
"use client";
import { useState } from "react";Base UI
"use client";
import { useState } from "react";Browse 4 production-ready audio/ui XY Pad components for players, mixers, and synth interfaces. These examples use Base UI primitives from @base-ui/react and stay fully compatible with Shadcn Create so radius, color, and typography match your configured theme.
Browse all 4 Shadcn XY Pad components for copy-ready layouts, dashboards, and forms built with Tailwind CSS in the audio/ui library.