Files
skills/docs/ui/react/react-audio/src/components/track-row/track-row.md
2026-05-29 08:20:56 +01:00

2.9 KiB

<TrackRow>

(no submodules)

Purpose

<TrackRow> is the per-track row primitive consumed by <TrackList>. It subscribes to a single Track through the foundation useTrack hook and renders the canonical row controls: editable name, mute / solo toggles, volume + pan sliders, and a remove button. The row collapses to a tombstone marker when the referenced track is removed so the surrounding <ul> does not visually re-layout in the intervening render frame.

<TrackRow> can also be used standalone — anywhere you have a track id and a provider mounted you can drop it into a list to render exactly one row.

Features

  • Re-renders on trackChange for the bound track id via useTrack.
  • Mute / solo as aria-pressed toggles with live "Mute" / "Muted" labels (and analogous Solo).
  • Volume slider clamped [0, 1] and pan slider clamped [-1, 1], both step 0.01. Non-numeric input is ignored.
  • Name input writes through to timeline.updateTrack({ name }).
  • Remove button calls useTrack().remove() and the row immediately collapses to the tombstone.
  • hideRemove suppresses the remove button.
  • data-muted / data-soloed attributes for theming hooks.

Usage: Basic Example

import { TrackRow } from "@suaveplan/react-audio";

export function OneRow({ trackId }: { trackId: string }) {
    return (
        <ul>
            <TrackRow trackId={trackId} />
        </ul>
    );
}

Usage: Advanced Example

import { TrackRow } from "@suaveplan/react-audio";

export function ReadOnlyRow({ trackId }: { trackId: string }) {
    return (
        <ul>
            <TrackRow trackId={trackId} hideRemove className="row-tight" />
        </ul>
    );
}

API Reference

Prop Type Default Notes
trackId string — Required. The id of the track to render.
className string | undef — Forwarded to the outer <li> (both active and tombstone).
hideRemove boolean | undef false Suppresses the remove button when true.

Implementation Notes

The active row is rendered by an inner ActiveRow sub-component so the mute / solo / volume / pan / name callbacks are only defined when the track exists. This keeps the hooks call sequence stable across the "track exists → tombstone" transition without violating the Rules of Hooks: the parent always calls useTrack first, then either returns the tombstone JSX (no further hooks) or renders <ActiveRow> (which calls its own bag of useCallbacks). The tombstone collapses to a minimal <li> so list keying remains stable while the engine is mid-mutation.