pnpm add @audio-ui/react
import { PianoRoll } from "@audio-ui/react/piano-roll";| Export | Kind | What it is |
|---|---|---|
PianoRoll.Key | function | One key, placed along the keyboard for its pitch. |
PianoRoll.KeyLabel | function | The name of the key it sits in, such as "C4". |
PianoRoll.Grid | function | The surface notes are drawn on: a timeline lane, with the roll's rows stacked down it. |
PianoRoll.Keys | function | The keyboard down the side of the roll: a Piano laid out on the roll's rows, low end at the bottom. |
PianoRoll.Marquee | function | The selection rectangle being dragged across the grid; renders nothing the rest of the time. |
PianoRoll.Note | function | One note, placed at its start and pitch: on the timeline's units across and on its row down. |
PianoRoll.NoteHandle | function | One edge of the note it sits in, dragged to change the note's length: the end makes it longer or shorter, the start trims it from the front while its end stays put. |
PianoRoll.Notes | function | Renders children once per note, in the order they are read: by start, then from the highest pitch down. |
PianoRoll.Root | function | Groups the parts of a piano roll and owns its notes, its selection and the pitches it draws. |
PianoRoll.Row | function | The band a pitch takes across the grid, for shading black-key rows, the rows of the roll's scale and of its root, or ruling where an octave starts. |
PianoRoll.Rows | function | Renders children once per row, highest pitch first: the place to put a PianoRoll.Row on the grid, or a PianoRoll.Key in the keys. |
PianoRoll.SelectionSpan | function | The time the selected notes cover, from the earliest start to the latest end, as a band from top to bottom of what it sits in: the grid, the velocity lane or the ruler. |
PianoRoll.StretchHandle | function | One edge of the selection's span, for its SelectionSpan: a drag stretches the selected notes in time from the other edge, on the grid unless Cmd/Ctrl is held. |
PianoRoll.Velocity | function | One note's velocity, or its chance in a level="chance" lane, as a bar from the bottom of the lane: its height is the value, through the --piano-roll-level CSS variable. |
PianoRoll.VelocityLane | function | A strip under the grid where each note's velocity, or with level="chance" its chance to play, stands as a bar placed at the note's start: a timeline lane, like the grid. |
Anatomy
Import the registry components for the ready-made look, or compose the primitive's parts yourself.
import { PianoRoll, Timeline } from "@audio-ui/react";
<Timeline.Root duration={16} snapStep={1}>
<PianoRoll.Root>
<PianoRoll.Keys>
<PianoRoll.Rows>
{(pitch) => (
<PianoRoll.Key pitch={pitch}>
<PianoRoll.KeyLabel />
</PianoRoll.Key>
)}
</PianoRoll.Rows>
</PianoRoll.Keys>
<PianoRoll.Grid aria-label="Notes">
<PianoRoll.Rows>{(pitch) => <PianoRoll.Row pitch={pitch} />}</PianoRoll.Rows>
<PianoRoll.SelectionSpan>
<PianoRoll.StretchHandle edge="start" />
<PianoRoll.StretchHandle edge="end" />
</PianoRoll.SelectionSpan>
<PianoRoll.Notes>
{(note) => (
<PianoRoll.Note key={note.id} note={note}>
<PianoRoll.NoteHandle edge="start" />
<PianoRoll.NoteHandle edge="end" />
</PianoRoll.Note>
)}
</PianoRoll.Notes>
<PianoRoll.Marquee />
</PianoRoll.Grid>
<PianoRoll.VelocityLane aria-label="Velocity">
<PianoRoll.Notes>
{(note) => <PianoRoll.Velocity key={note.id} note={note} />}
</PianoRoll.Notes>
</PianoRoll.VelocityLane>
</PianoRoll.Root>
</Timeline.Root>;API reference
Root
Groups the parts of a piano roll and owns its notes and selection. Must be used within a Timeline. Renders a <div> element.
Props · 20
"scale" those in scale too. A roll with nothing to fold onto keeps them all.data-in-scale, as its pitch classes and its root: { pitchClasses: [0, 2, 4, 5, 7, 9, 11], root: 0 } for C major."note-<n>", skipping ids in use.eventDetails.cancel() keeps it silent.Data attributes · 5
data-disableddata-editingdata-foldeddata-has-selectiondata-mode"draw" or "select".Keys
The keyboard down the side: a Piano laid out on the roll's rows, low end at the bottom. Pressing a key sounds it through the roll's onNoteOn; with Shift, pressing it (or Shift + Enter) selects every note on its row, or deselects them when they all are. Put a PianoRoll.Key per row inside, with PianoRoll.Rows. Renders a <div> element.
Rows
Renders children once per row, from the highest pitch down: the place to put a PianoRoll.Key or a PianoRoll.Row. Renders no element of its own.
Props · 1
Key and KeyLabel
The same parts as Piano: a key of the keyboard, and its label.
Grid
The surface notes are drawn on: a timeline lane, with the roll's rows stacked down it. A press on empty grid draws a note (mode="draw"), whose end then follows the pointer, or starts a selection rectangle, Shift adding to what is selected; in that mode a double-click draws. Focused, Enter adds a note at the playback position, Escape clears the selection and Cmd/Ctrl+A selects every note. From the grid or a note, Cmd/Ctrl+D repeats the selection right after itself, Cmd/Ctrl+C, X and V copy, cut and paste at the playback position, and Q snaps the starts of the selection (every note, with none selected) to the grid. Renders a <div> element.
Row
The band a pitch takes across the grid, for shading black-key rows, the rows of the roll's scale, or ruling where an octave starts. It lets presses through to the grid and is hidden from assistive technology. Renders a <div> element.
Props · 1
Data attributes · 7
data-activedata-color"black" or "white".data-foldeddata-in-scalescale.data-out-of-scalescale and the pitch is not in it.data-scale-rootscale: a C in C major.data-octaveNotes
Renders children once per note, in the order they are read: by start, then from the highest pitch down. That order is also the tab order. Renders no element of its own.
Props · 1
Note
One note, placed on its row from its start, as long as its length. A toggle button named after its pitch and span (getNoteLabel on Root). Its --piano-roll-velocity and --piano-roll-chance CSS variables are its velocity and how likely it is to play. Renders a <div> element.
Props · 1
Data attributes · 3
data-selectedaria-pressed.data-muteddata-disabledNoteHandle
One edge of the note it sits in, dragged to change the note's length: the end makes it longer or shorter, the start trims it from the front while its end stays put. On the grid unless Cmd/Ctrl is held, and for the whole selection when the note is part of it. Shift + Left and Right on the note do the same from the keyboard, so the handle is hidden from assistive technology. Renders a <div> element.
Props · 1
Marquee
The selection rectangle being dragged across the grid; renders nothing the rest of the time. Hidden from assistive technology. Renders a <div> element.
SelectionSpan
The time the selected notes cover, from the earliest start to the latest end, as a band from top to bottom of what it sits in: the grid, the velocity lane or the ruler. Renders nothing with no note selected. It lets presses through, all but its PianoRoll.StretchHandles, and is hidden from assistive technology. Renders a <div> element.
StretchHandle
One edge of the selection's span, for its SelectionSpan: a drag stretches the selected notes in time from the other edge, on the grid unless Cmd/Ctrl is held. The Notes edits that double and halve lengths do the same from the keyboard, so it is hidden from assistive technology. Renders a <div> element.
Props · 1
VelocityLane
A strip under the grid where each note's velocity, or with level="chance" its chance to play, stands as a bar placed at the note's start: a timeline lane, like the grid. In draw mode it is a brush: a drag across it sets every bar under the pointer, in the grid cell it is over, to the pointer's height. Put a PianoRoll.Velocity per note inside, with PianoRoll.Notes. Renders a <div> element.
Props · 1
Data attributes · 2
data-level"velocity" or "chance".data-mode"draw" or "select": in draw mode the lane is a brush.Velocity
One note's velocity, or its chance in a level="chance" lane, as a bar from the bottom of the lane: its height is the value, through the --piano-roll-level CSS variable. Dragging it up or down changes the value of the selection by the same amount when the note is part of it, so a phrase keeps its dynamics; Shift + click toggles the note in the selection. On a velocity bar, Cmd/Ctrl + drag sets how far the velocity may stray each time the note plays, its --piano-roll-deviation. A native <input type="range"> inside takes the arrow keys (Page Up/Down for larger steps, Home/End for none and full) and carries the accessible name, which defaults to the note's. The next drawn note gets the velocity set last. Renders a <div> element.
Props · 2
Data attributes · 2
data-selecteddata-mutedStyled
The registry's styled Piano roll, its usage and interaction: Piano roll.