first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
# `<TrackRow>`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## 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
```tsx
import { TrackRow } from "@suaveplan/react-audio";
export function OneRow({ trackId }: { trackId: string }) {
return (
<ul>
<TrackRow trackId={trackId} />
</ul>
);
}
```
## Usage: Advanced Example
```tsx
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 `useCallback`s). The tombstone collapses
to a minimal `<li>` so list keying remains stable while the engine is
mid-mutation.