43 lines
3.7 KiB
Markdown
43 lines
3.7 KiB
Markdown
<!-- markdownlint-disable MD024 -->
|
|
|
|
# Capability Spec Delta: react-audio (enterprise-react-audio-components-extras)
|
|
|
|
**Package**: `@suaveplan/react-audio`
|
|
**Status**: PROPOSED — supplementary to Phase 2
|
|
**Blocked on**: `enterprise-react-audio-components` shipping first.
|
|
|
|
> Every requirement carries `**Verified by:**`.
|
|
|
|
## ADDED Requirements
|
|
|
|
### Requirement: Composed-plugin UI components
|
|
|
|
The package SHALL export `<TransportControls>`, `<TrackList>`, `<TrackRow>`, `<MasterMeter>`, `<Mixer>`, `<AudioVisualizer>`, `<AudioPlayer>`, `<BasicPlayer>`, `<PremiumPlayer>`, `<MicrophoneControls>`, `<GLaDOSControls>`, and `<PluginLoader>`. Each component SHALL compose against the foundation hooks (Phase 1) and the appropriate concrete plugin package: `<Mixer>` against `@suaveplan/audio-fx-plugin-mixer`, `<AudioPlayer>` family against `@suaveplan/audio-fx-plugin-audio-player`, `<MicrophoneControls>` against `@suaveplan/audio-fx-plugin-microphone`, `<GLaDOSControls>` against `@suaveplan/audio-fx-plugin-glados`. Each component SHALL satisfy the Storybook coverage gate (default + interactive + edge-case stories) and the accessibility requirement from Phase 2. Each SHALL have a `./components/<name>` subpath export.
|
|
|
|
#### Scenario: every composed-plugin component renders against a real instance
|
|
|
|
- **WHEN** a test renders `<Mixer>` with a real `MixerPlugin` from `@suaveplan/audio-fx-plugin-mixer` registered on the provider
|
|
- **THEN** the component renders strip controls bound to the real plugin's parameters; setting a strip's gain calls `mixerPlugin.setParameter` and the new value is reflected on the next sample tick
|
|
|
|
#### Scenario: subpath export per component
|
|
|
|
- **WHEN** a consumer imports `@suaveplan/react-audio/components/transport-controls`
|
|
- **THEN** the import resolves and pulls in only that component's bundle (verified by `tests/exports.test.ts`)
|
|
|
|
**Verified by:** `src/components/transport-controls/transport-controls.test.tsx::"renders against a real transport"` AND `src/components/track-list/track-list.test.tsx::"renders against a real TimelineEngine"` AND `src/components/mixer/mixer.test.tsx::"renders against a real MixerPlugin"` AND `src/components/audio-player/audio-player.test.tsx::"renders against a real AudioPlayerPlugin"` AND `src/components/microphone-controls/microphone-controls.test.tsx::"renders against a real MicrophonePlugin"` AND `src/components/glados-controls/glados-controls.test.tsx::"renders against a real GLaDOSPlugin"` AND `src/components/audio-visualizer/audio-visualizer.test.tsx::"renders a canvas bound to useAnalyser"` AND `src/components/master-meter/master-meter.test.tsx::"renders against a master analyser"` AND `src/components/plugin-loader/plugin-loader.test.tsx::"lists every registered plugin from PluginRegistry"` AND `tests/exports.test.ts::"every extras component has a subpath export entry"`
|
|
|
|
---
|
|
|
|
### Requirement: Main-branch parity restored
|
|
|
|
After this change archives, every component on `/mnt/s/web/suaveplan/packages/react/react-audio/src/components/` SHALL have a genesis equivalent exported from `@suaveplan/react-audio`. The parity test SHALL fail if any main-branch component family is missing on genesis.
|
|
|
|
#### Scenario: parity test enumerates every main-branch component family
|
|
|
|
- **WHEN** `tests/parity.test.ts::"every main-branch component family has a genesis equivalent"` runs
|
|
- **THEN** for every top-level directory under `/mnt/s/web/suaveplan/packages/react/react-audio/src/components/` (the test reads this list from a checked-in fixture so it stays runnable offline) there is a corresponding genesis component reachable via `@suaveplan/react-audio/components/<name>`
|
|
|
|
**Verified by:** `tests/parity.test.ts::"every main-branch component family has a genesis equivalent"`
|
|
|
|
<!-- markdownlint-enable MD024 -->
|