Lab

Piano

The <audio-ui-piano> custom element of @audio-ui/elements: its attributes, its parts and a live preview.

<audio-ui-piano> is a playable keyboard with role="group". A key sounds while pressed, by pointer or with Enter and Space. Dragging glides across keys, and each pointer holds its own key, so chords can be played on touch screens. The keys share one tab stop and are navigated with the arrow keys, by octave with Shift.

Usage

The styles read the theme's CSS variables, which Styling sets.

<style>
  audio-ui-piano {
    position: relative;
    display: block;
    width: 100%;
    max-width: 32rem;
    height: calc(var(--spacing, 0.25rem) * 28);
  }

  audio-ui-piano-key {
    z-index: 0;
    top: 0;
    box-sizing: border-box;
    height: 100%;
    border: 1px solid var(--border, oklch(0.922 0 0));
    border-radius: 0 0 4px 4px;
    background: var(--background, oklch(1 0 0));
    cursor: pointer;
    outline: none;
  }

  audio-ui-piano-key[data-color="black"] {
    z-index: 1;
    height: 62%;
    border-color: var(--foreground, oklch(0.145 0 0));
    background: var(--foreground, oklch(0.145 0 0));
  }

  audio-ui-piano-key[data-active] {
    border-color: var(--primary, oklch(0.205 0 0));
    background: var(--primary, oklch(0.205 0 0));
  }
</style>

<audio-ui-piano aria-label="Keys" min-pitch="48" max-pitch="71">
  <audio-ui-piano-keys></audio-ui-piano-keys>
</audio-ui-piano>

<script type="module">
  import "@audio-ui/elements/piano";

  const piano = document.querySelector("audio-ui-piano");
  piano.addEventListener("noteon", (event) =>
    console.log(event.detail.pitch)
  );
</script>

API reference

pnpm add @audio-ui/elements
import "@audio-ui/elements/piano";
ExportKindWhat it is
PIANO_TAGSconstThe names the piano's elements are registered under, frozen: a page cannot rename them by accident.
PianoElementclassThe root of a playable keyboard, with role="group".
PianoElementEventMapinterfaceThe events a piano fires, as addEventListener types them.
PianoKeyElementclassA key, positioned for its pitch.
PianoKeyLabelElementclassThe name of its key, such as "C4".
PianoKeysElementclassGenerates an <audio-ui-piano-key> per pitch, lowest first, filled from its <template>, such as with an <audio-ui-piano-key-label>.
PianoNoteOffDetailinterfaceWhat a noteoff event carries: the pitch released, and why.
PianoNoteOffEventtypeFired when a key stops sounding.
PianoNoteOnDetailinterfaceWhat a noteon event carries: the pitch played, how hard, and how.
PianoNoteOnEventtypeFired when a key starts sounding.

Props · 7

EventDetailDescription
noteon{ pitch, velocity, reason, event }A key starts sounding. event is the originating pointer or keyboard event. preventDefault() keeps it silent
noteoff{ pitch, reason, event }A key stops sounding
PartDescription
<audio-ui-piano-keys>Generates an <audio-ui-piano-key> per pitch, lowest first, from its <template>. Renders with display: contents
<audio-ui-piano-key>A key, a button positioned for its pitch and labelled with its name ("C4"). data-color is black or white
<audio-ui-piano-key-label>The name of its key, hidden from assistive technology

The same control in React, and its parts' props: Piano.

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