Framework wrappers
The thin framework wrappers version independently of the core libraries they wrap.
@arraypress/waveform-player-astro
Section titled “@arraypress/waveform-player-astro”[Unreleased]
Section titled “[Unreleased]”[0.7.0] — 2026-07-22
Section titled “[0.7.0] — 2026-07-22”crossOriginprop. Exposes the option added in@arraypress/waveform-player@1.23.0, emitted asdata-cross-origin('anonymous'|'use-credentials'). Omitted by default so the player behaves like a native<audio>and never forces a CORS request that would break CDN media withoutAccess-Control-Allow-Origin.
[0.6.0] — 2026-07-17
Section titled “[0.6.0] — 2026-07-17”-
buttonRadiusandartworkPositionprops. Exposes the two options added in@arraypress/waveform-player1.22.0:buttonRadiussets the play button’s corner radius (0for square, or any CSS length), andartworkPosition('info'|'button') chooses whether the cover renders in the info row or becomes the play button itself.Both prop types already flowed through automatically, since the props derive from the core’s
WaveformPlayerOptions— but thedata-*emission is written by hand, so until now they would have type-checked and then silently done nothing. Tests now cover the mapping for exactly that reason.The peer range stays
^1.20.0: the props only appear once the consumer’s own core is on 1.22.0, so nothing breaks on an older one.
[0.5.0] — 2026-07-05
Section titled “[0.5.0] — 2026-07-05”- Forward the core player’s new localizable UI-string options —
seekValueText,playPauseLabel,speedLabel,artworkAlt, andunknownTrackText— through to the underlying player. Requires@arraypress/waveform-player@^1.20.0.
Removed
Section titled “Removed”- BREAKING: the six DOM-chrome colour props —
buttonColor,buttonHoverColor,textColor,textSecondaryColor,backgroundColor, andborderColor— are gone (the core library moved this chrome to CSS variables). Theme the button and text via--wfp-button-color,--wfp-text-color,--wfp-text-secondary-color, etc. in your own CSS instead.waveformColor,progressColor,colorPreset, andwaveformGradientremain props.
Changed
Section titled “Changed”- Types are now sourced directly from the core
@arraypress/waveform-playerpackage — a single source of truth. The shared option types (WaveformStyle,ColorPreset,AudioMode,AudioPreload,ButtonAlign,WaveformMarker,WaveformPeaks) are re-exported from the core, andWaveformPlayerPropsnowextendsthe core’sWaveformPlayerOptionsinstead of re-declaring every option, so the two packages can no longer drift. Every previously-exported type name is preserved. - Bumped the
@arraypress/waveform-playerpeer (and dev) dependency to^1.8.0, which ships the hand-authoredindex.d.tsthese types adopt.
accessibleSeek,seekLabel,barRadius, and the gradient-array forms ofwaveformColor/progressColorare now exposed onWaveformPlayerProps(inherited from the core option surface), filling gaps where the previous hand-maintained copy had missed or drifted.
[0.1.2] — 2026-06-27
Section titled “[0.1.2] — 2026-06-27”Changed
Section titled “Changed”- Bumped the
@arraypress/waveform-playerpeer (and dev) dependency to^1.7.2. Consumers now get the native accessible keyboard / ARIA seek slider by default. No component API changes.
[0.1.1] — Unreleased
Section titled “[0.1.1] — Unreleased”Changed
Section titled “Changed”- Widened the
astropeerDependency to^6.0.0 || ^7.0.0for Astro 7 readiness. No runtime changes — the component is unaffected by the Astro 7 compiler / Vite 8 (Rolldown) upgrade.
[0.1.0] — Unreleased
Section titled “[0.1.0] — Unreleased”Initial release.
<WaveformPlayer>Astro component wrapping every option exposed by@arraypress/waveform-player1.6.x as a typed prop:- Audio source props (
url,audioMode,preload) - Waveform visualisation props (
waveformStyle,height,samples,barWidth,barSpacing,waveform) - Colour props (
colorPreset,waveformColor,progressColor,buttonColor,buttonHoverColor,textColor,textSecondaryColor,backgroundColor,borderColor) - Playback control props (
playbackRate,showPlaybackSpeed,playbackRates) - UI toggle props (
showControls,showInfo,showTime,showHoverTime,showBPM,buttonAlign) - Marker props (
markers,showMarkers) - Content metadata props (
title,artist,artwork,album) - Behaviour flags (
autoplay,singlePlay,playOnSeek,enableMediaSession) - Icon props (
playIcon,pauseIcon)
- Audio source props (
- Astro-specific
lazyprop that switches the init attribute todata-waveform-player-lazyand ships a single deduplicatedIntersectionObserverfor grids of many previews. - Astro-specific
id,class, andstylepass-throughs. - Public TypeScript types:
WaveformPlayerProps,WaveformStyle,WaveformMarker,WaveformPeaks,ColorPreset,AudioMode,AudioPreload,ButtonAlign. - Ambient declaration for
window.WaveformPlayerto type consumer scripts that reach for the global. - Vitest suite (29 tests) covering attribute mapping, omission semantics, JSON serialisation for array props, lazy-mount script presence, and pass-through props.
- Documentation: full prop reference, setup guide, seven usage
examples (
examples/basic.astro).
@arraypress/waveform-player-react
Section titled “@arraypress/waveform-player-react”[Unreleased]
Section titled “[Unreleased]”[0.7.0] — 2026-07-22
Section titled “[0.7.0] — 2026-07-22”crossOriginprop. Exposes the option added in@arraypress/waveform-player@1.23.0: sets the CORS mode of the underlying<audio>('anonymous'|'use-credentials'). Omitted from the options bag by default so the player behaves like a native<audio>and never forces a CORS request that would break CDN media withoutAccess-Control-Allow-Origin.
[0.6.0] — 2026-07-17
Section titled “[0.6.0] — 2026-07-17”-
buttonRadiusandartworkPositionprops. Exposes the two options added in@arraypress/waveform-player1.22.0:buttonRadiussets the play button’s corner radius (0for square, or any CSS length), andartworkPosition('info'|'button') chooses whether the cover renders in the info row or becomes the play button itself.Both prop types already flowed through automatically, since the props derive from the core’s
WaveformPlayerOptions— but the options bag is written by hand, so until now they would have type-checked and then silently done nothing. Tests now cover the mapping for exactly that reason.The peer range stays
^1.20.0: the props only appear once the consumer’s own core is on 1.22.0, so nothing breaks on an older one.
[0.5.0] — 2026-07-05
Section titled “[0.5.0] — 2026-07-05”- Forward the core player’s new localizable UI-string options —
seekValueText,playPauseLabel,speedLabel,artworkAlt, andunknownTrackText— through to the underlying player. Requires@arraypress/waveform-player@^1.20.0.
Changed
Section titled “Changed”- Public types are now adopted from the core
@arraypress/waveform-player(v1.8.0+), which ships a hand-authoredindex.d.ts. The shared option surface (WaveformStyle,ColorPreset,AudioMode,AudioPreload,ButtonAlign,WaveformMarker,WaveformPeaks) is re-exported from the core, andWaveformPlayerPropsnowextendsthe core’sWaveformPlayerOptionsinstead of re-declaring every field. The core is the single source of truth, so the wrapper’s types can no longer drift out of sync. Bumped the@arraypress/waveform-playerpeer (and dev) dependency to^1.8.0. - Callback props (
onLoad,onPlay,onPause,onEnd,onTimeUpdate,onError) and theWaveformPlayerHandle.instanceaccessor are now typed with the core’sWaveformPlayerclass instead ofunknown.
accessibleSeek,seekLabel,barRadius, and gradient-array waveform / progress colours (string[]) are now exposed as typed props — picked up for free by extending the core options and wired through to the underlying player.
Removed
Section titled “Removed”- Deleted
src/core-module-shim.d.ts, the loose ambientdeclare module '@arraypress/waveform-player'shim that only existed while the core had no shipped types.
[0.1.1] — 2026-06-27
Section titled “[0.1.1] — 2026-06-27”Changed
Section titled “Changed”- Bumped the
@arraypress/waveform-playerpeer (and dev) dependency to^1.7.2. Consumers now get the native accessible keyboard / ARIA seek slider by default. No component API changes.
[0.1.0] — Unreleased
Section titled “[0.1.0] — Unreleased”Initial release.
<WaveformPlayer>React component wrapping every option exposed by@arraypress/waveform-player1.6.x as a typed prop:- Audio source (
url,audioMode,preload) - Waveform visualisation (
waveformStyle,height,samples,barWidth,barSpacing,waveform) - Colours (
colorPreset,waveformColor,progressColor,buttonColor,buttonHoverColor,textColor,textSecondaryColor,backgroundColor,borderColor) - Playback (
playbackRate,showPlaybackSpeed,playbackRates) - UI toggles (
showControls,showInfo,showTime,showHoverTime,showBPM,buttonAlign) - Markers (
markers,showMarkers) - Metadata (
title,artist,artwork,album) - Behaviour (
autoplay,singlePlay,playOnSeek,enableMediaSession) - Icons (
playIcon,pauseIcon)
- Audio source (
- Callback props (
onLoad,onPlay,onPause,onEnd,onTimeUpdate,onError) that map to the library’s same-named option fields. Callbacks are deliberately NOT in the effect dep array, so a parent re-rendering with new inline functions doesn’t tear the player down. - React-specific extras:
id,className,style, andrefforwarding viaWaveformPlayerHandle. WaveformPlayerHandleimperative API on the forwarded ref —play(),pause(),togglePlay(),seekTo(),seekToPercent(),setVolume(),setPlaybackRate(),setPlayingState(),setProgress(),loadTrack(), plus the rawinstance.- SSR / RSC safe: the core library is loaded via dynamic
import('@arraypress/waveform-player')inside the effect so the browser-only audio surface never runs server-side. - Identity-prop re-mount: when any library-construction prop
changes (
url,audioMode, etc.), the wrapper destroys the existing instance and creates a new one with the updated options. Simpler and more correct than diffing every option + calling granular updaters. - Public TypeScript types:
WaveformPlayerProps,WaveformPlayerHandle,WaveformStyle,WaveformMarker,WaveformPeaks,ColorPreset,AudioMode,AudioPreload,ButtonAlign. - Ambient module shim for
@arraypress/waveform-playerso the wrapper typechecks cleanly until the core library ships its own.d.ts. - Vitest test suite (17 tests, jsdom +
@testing-library/react) covering mount, unmount destroy, option pass-through, callback forwarding, identity-prop re-mount, callback-churn protection, ref forwarding, and the full imperative handle surface. The core library is mocked at the module boundary because jsdom has no Web Audio API. - Dual ESM (
dist/index.js) + CJS (dist/index.cjs) build viatsup..d.tsfor both. React + the core library are externalised so they resolve to the consumer’s copies. - README with full prop reference, seven usage patterns, and the
imperative-ref control example.
examples/basic.tsxwith seven copy-paste-ready snippets.
@arraypress/waveform-player-vue
Section titled “@arraypress/waveform-player-vue”[0.5.0] — 2026-07-22
Section titled “[0.5.0] — 2026-07-22”crossOriginprop. Exposes the option added in@arraypress/waveform-player@1.23.0: sets the CORS mode of the underlying<audio>('anonymous'|'use-credentials'). Declared as a runtime prop and omitted from the options bag by default so the player behaves like a native<audio>and never forces a CORS request that would break CDN media withoutAccess-Control-Allow-Origin.
[0.4.0] — 2026-07-17
Section titled “[0.4.0] — 2026-07-17”-
buttonRadiusandartworkPositionprops. Exposes the two options added in@arraypress/waveform-player1.22.0:buttonRadiussets the play button’s corner radius (0for square, or any CSS length), andartworkPosition('info'|'button') chooses whether the cover renders in the info row or becomes the play button itself.Both prop types already flowed through automatically, since the props derive from the core’s
WaveformPlayerOptions— but the options mapping is written by hand, so until now they would have type-checked and then silently done nothing. Tests now cover the mapping for exactly that reason.The peer range stays
^1.20.0: the props only appear once the consumer’s own core is on 1.22.0, so nothing breaks on an older one.
buttonSizeaccepts a number again. The prop was declaredtype: String, so:button-size="64"failed Vue’s runtime type check and warned, even though the core accepts a number (px) or a unit string. It now declares[String, Number], matching the core.buttonRadiustakes the same pair.
[0.3.0] — 2026-07-05
Section titled “[0.3.0] — 2026-07-05”- Forward the core player’s new localizable UI-string options —
seekValueText,playPauseLabel,speedLabel,artworkAlt, andunknownTrackText— through to the underlying player. Requires@arraypress/waveform-player@^1.20.0.
[0.1.0] — Unreleased
Section titled “[0.1.0] — Unreleased”Initial release.
<WaveformPlayer>Vue 3 component wrapping every option exposed by@arraypress/waveform-playeras a typed prop:- Audio source (
url,srcalias,audioMode,preload) - Waveform visualisation (
waveformStyle,height,samples,barWidth,barSpacing,barRadius,waveform) - Colours (
colorPreset,waveformColor,progressColor,waveformGradient— strings orstring[]gradients). DOM chrome (button, title, meta text) is themed via CSS variables (--wfp-button-color,--wfp-text-color,--wfp-text-secondary-color), not JS options. - Playback (
playbackRate,showPlaybackSpeed,playbackRates) - UI toggles (
showControls,showInfo,showTime,showHoverTime,showBPM,buttonAlign,accessibleSeek,seekLabel,errorText) - Markers (
markers,showMarkers) - Metadata (
title,artist,artwork,album) - Behaviour (
autoplay,singlePlay,playOnSeek,enableMediaSession) - Icons (
playIcon,pauseIcon)
- Audio source (
- Lifecycle emits (
load,play,pause,end,timeupdate,error), each forwarding the liveWaveformPlayerinstance. Wired through Vue’s stableemit, so listeners can change without tearing the player down. - Imperative API exposed via a template
ref(WaveformPlayerExpose):play(),pause(),togglePlay(),seekTo(),seekToPercent(),setVolume(),setPlaybackRate(),setPlayingState(),setProgress(),loadTrack(), plus the rawinstance. class,style, andidfall through to the host element via Vue’s attribute inheritance; the base classwfp-hostalways applies.- SSR / Nuxt safe: the core library is loaded via dynamic
import('@arraypress/waveform-player')insideonMountedso the browser-only audio surface never runs server-side. - Identity-prop re-mount: when any library-construction prop changes, the wrapper destroys the existing instance and creates a new one with the updated options. A monotonic mount token discards any in-flight async import that a newer mount (or unmount) has superseded.
- Public types are adopted from the core
@arraypress/waveform-player(WaveformStyle,ColorPreset,AudioMode,AudioPreload,ButtonAlign,WaveformMarker,WaveformPeaks), re-exported here so the wrapper’s types can never drift out of sync.WaveformPlayerPropsis derived from the core’sWaveformPlayerOptions. - Dual ESM (
dist/index.js) + CJS (dist/index.cjs) build viatsup, with.d.tsfor both. Vue + the core library are externalised so they resolve to the consumer’s copies. - Vitest test suite (jsdom +
@vue/test-utils) covering mount, option pass-through, thesrc → urlalias, boolean-prop omission, emit forwarding, destroy-on-unmount, identity-prop re-mount, and the exposed imperative API. The core is mocked at the module boundary because jsdom has no Web Audio API. - README with full prop reference, seven usage patterns, and the
imperative-ref control example.
examples/basic.vuewith seven copy-paste-ready snippets.
@arraypress/waveform-player-svelte
Section titled “@arraypress/waveform-player-svelte”[0.5.0] — 2026-07-22
Section titled “[0.5.0] — 2026-07-22”crossOriginprop. Exposes the option added in@arraypress/waveform-player@1.23.0: sets the CORS mode of the underlying<audio>('anonymous'|'use-credentials'). Omitted from the options bag by default so the player behaves like a native<audio>and never forces a CORS request that would break CDN media withoutAccess-Control-Allow-Origin.
[0.4.0] — 2026-07-17
Section titled “[0.4.0] — 2026-07-17”-
buttonRadiusandartworkPositionprops. Exposes the two options added in@arraypress/waveform-player1.22.0:buttonRadiussets the play button’s corner radius (0for square, or any CSS length), andartworkPosition('info'|'button') chooses whether the cover renders in the info row or becomes the play button itself.Both prop types already flowed through automatically, since the props derive from the core’s
WaveformPlayerOptions— but the options mapping is written by hand, so until now they would have type-checked and then silently done nothing. Tests now cover the mapping for exactly that reason.The peer range stays
^1.20.0: the props only appear once the consumer’s own core is on 1.22.0, so nothing breaks on an older one.
[0.3.0] — 2026-07-05
Section titled “[0.3.0] — 2026-07-05”- Forward the core player’s new localizable UI-string options —
seekValueText,playPauseLabel,speedLabel,artworkAlt, andunknownTrackText— through to the underlying player. Requires@arraypress/waveform-player@^1.20.0.
[0.1.0] — Unreleased
Section titled “[0.1.0] — Unreleased”Initial release.
<WaveformPlayer>Svelte 5 component (built with runes) wrapping every option exposed by@arraypress/waveform-playeras a typed prop:- Audio source (
url,srcalias,audioMode,preload) - Waveform visualisation (
waveformStyle,height,samples,barWidth,barSpacing,barRadius,waveform) - Colours (
colorPreset,waveformColor,progressColor— strings orstring[]gradients). DOM chrome (button, title, meta text) is themed via CSS variables (--wfp-button-color,--wfp-text-color,--wfp-text-secondary-color), not JS options. - Playback (
playbackRate,showPlaybackSpeed,playbackRates) - UI toggles (
showControls,showInfo,showTime,showHoverTime,showBPM,buttonAlign,accessibleSeek,seekLabel,errorText) - Markers (
markers,showMarkers) - Metadata (
title,artist,artwork,album) - Behaviour (
autoplay,singlePlay,playOnSeek,enableMediaSession) - Icons (
playIcon,pauseIcon)
- Audio source (
- Lowercase lifecycle callback props (
onload,onplay,onpause,onend,ontimeupdate,onerror), each forwarding the liveWaveformPlayerinstance. Wired through reactive closures, so changing a handler never tears the player down. - Imperative API exported by the component instance (reachable via
bind:this):play(),pause(),togglePlay(),seekTo(),seekToPercent(),setVolume(),setPlaybackRate(),setPlayingState(),setProgress(),loadTrack(), andgetInstance(). class,style,id, and other element attributes fall through to the host element via...rest; the base classwfp-hostalways applies.- SSR / SvelteKit safe: the core library is loaded via dynamic
import('@arraypress/waveform-player')inside a browser-only$effect, so the audio surface never runs server-side. - Identity-prop re-mount: a single
$effectreads every construction prop, so changing any of them destroys the existing instance and creates a new one. A monotonic mount token discards any in-flight async import that a newer mount (or unmount) has superseded. - Public types adopted from the core
@arraypress/waveform-player(WaveformStyle,ColorPreset,AudioMode,AudioPreload,ButtonAlign,WaveformMarker,WaveformPeaks), re-exported here so the wrapper’s types can never drift.WaveformPlayerPropsis derived from the core’sWaveformPlayerOptions. - Built with
svelte-package(dist/ships the preprocessed.svelte+ generated.d.ts). Svelte + the core library are peer dependencies. - Vitest test suite (jsdom +
@testing-library/svelte) covering mount, option pass-through, thesrc → urlalias, boolean-prop omission, callback forwarding, destroy-on-unmount, identity-prop re-mount, and the exported imperative API. The core is mocked at the module boundary because jsdom has no Web Audio API. - README with full prop reference, seven usage patterns, and the
imperative
bind:thiscontrol example.examples/Basic.sveltewith seven copy-paste-ready snippets.
@arraypress/waveform-bar-astro
Section titled “@arraypress/waveform-bar-astro”[0.4.0] — 2026-07-22
Section titled “[0.4.0] — 2026-07-22”crossOriginconfig key. Added toWaveformBarConfigand forwarded verbatim towindow.WaveformBar.init(). Requires@arraypress/waveform-bar@^1.11.0for it to reach the embedded player.
[0.3.0] — 2026-07-05
Section titled “[0.3.0] — 2026-07-05”- Accept the new localizable player-string keys —
seekValueText,playPauseLabel,speedLabel,artworkAlt, andunknownTrackText— in the bar config; they are forwarded to the embedded player. Requires@arraypress/waveform-bar@^1.10.0.
[0.2.0] — 2026-07-01
Section titled “[0.2.0] — 2026-07-01”Changed
Section titled “Changed”- Sync
WaveformBarConfigto the bar’smodeAPI:layout→mode('waveform' | 'classic'), removemaxWidth, addshowShuffle/shuffle. Matches@arraypress/waveform-bar1.7.0.
[0.1.3] — 2026-06-27
Section titled “[0.1.3] — 2026-06-27”Changed
Section titled “Changed”- Bumped the
@arraypress/waveform-playerpeer (and dev) dependency to^1.7.2, which adds the native accessible keyboard / ARIA seek slider to the underlying player. No component API changes.
[0.1.2] — Unreleased
Section titled “[0.1.2] — Unreleased”Changed
Section titled “Changed”- Widened the
astropeerDependency to^6.0.0 || ^7.0.0for Astro 7 readiness. No runtime changes — the component is unaffected by the Astro 7 compiler / Vite 8 (Rolldown) upgrade.
[0.1.1] — Unreleased
Section titled “[0.1.1] — Unreleased”<WaveformBarTrigger>’s default pause-icon SVG no longer carries an inlinestyle="display:none;". The previous value beat the core library’s class-based toggle (.wb-icon-swap.wb-playing .wb-show-pause { display: inline; }), leaving the pause icon permanently hidden once a track started playing. The library’s own CSS already covers the initial-hidden state via.wb-icon-swap .wb-show-pause { display: none; }, so the inline style is redundant as well as harmful.- Added two regression tests pinning the no-inline-display contract so the bug can’t return.
[0.1.0]
Section titled “[0.1.0]”Initial release.
<WaveformBar>— singleton mount component for the persistent bottom bar. Renders atransition:persisthost div and an inline init script that callswindow.WaveformBar.init(config)on everyastro:page-load. Relocates the library’s.waveform-barelement into the persist host so view transitions keep it onscreen between navigations.- Typed
WaveformBarConfigcovering every optionwindow.WaveformBar.init()accepts:- Persistence:
persist,autoResume,continuous,repeat - UI toggles:
showQueue,showPrevNext,showRepeat,showVolume,showMute,showTime,showTrackLink,showMeta,maxMeta - Theming:
theme,defaultArtwork - Waveform visualisation:
waveformStyle,waveformHeight,barWidth,barSpacing,waveformColor,progressColor,markerColor - Volume + persistence keys:
volume,storageKey - Server-side actions:
actions.favorite/actions.cartwithendpointURL + optionalmethod/headers
- Persistence:
<WaveformBarTrigger>— polymorphic click trigger. Renders a<button>by default; override viaas="a" | "div" | "span". Emits the fulldata-wb-*attribute contract:- Track identity:
url,id(falls back tourl),title,artist,album,artwork,link - Display chips:
duration,bpm,key,meta - Audio data:
waveform(peaks array, URL, or inline JSON),markers(DJ-mode chapters) - Initial state:
favorited,inCart - Behaviour:
mode='play' | 'queue',href(whenas="a"),ariaLabel,class,noDefaultIcons
- Track identity:
- Default slot ships the play / pause SVG pair the core library
toggles via
wb-show-play/wb-show-pauseclasses. Passing children replaces them. - Auto-generated
aria-labelwhen one isn’t supplied —Play {title}for play triggers,Add {title} to queuefor queue triggers. - Public TypeScript types:
WaveformBarProps,WaveformBarConfig,WaveformBarTriggerProps,WaveformBarTrackData,WaveformBarMarker,WaveformBarActions,WaveformBarAction,WaveformBarTheme,RepeatMode,TriggerMode,WaveformStyle. - Ambient declaration for
window.WaveformBarcovering the full public surface (play,pause,next,previous,addToQueue,setVolume,setRepeat,seekToMarker, etc.). - Vitest suite of 46 tests via Astro’s
experimental_AstroContainercovering attribute mapping, omission semantics, JSON serialisation for arrays, polymorphicas, default-slot behaviour, aria-label generation, and a kitchen-sink scenario. - Documentation: full README with setup, prop tables, every usage
pattern, and the
waveformbar:*custom-event API.examples/basic.astroreference page with six demonstrations.
@arraypress/waveform-bar-react
Section titled “@arraypress/waveform-bar-react”[0.4.0] — 2026-07-22
Section titled “[0.4.0] — 2026-07-22”crossOriginconfig key. Added toWaveformBarConfigand forwarded verbatim towindow.WaveformBar.init(). Requires@arraypress/waveform-bar@^1.11.0for it to reach the embedded player.
[0.3.0] — 2026-07-05
Section titled “[0.3.0] — 2026-07-05”- Accept the new localizable player-string keys —
seekValueText,playPauseLabel,speedLabel,artworkAlt, andunknownTrackText— in the bar config; they are forwarded to the embedded player. Requires@arraypress/waveform-bar@^1.10.0.
[0.2.0] — 2026-07-01
Section titled “[0.2.0] — 2026-07-01”Changed
Section titled “Changed”- Sync
WaveformBarConfigto the bar’smodeAPI:layout→mode('waveform' | 'classic'), removemaxWidth, addshowShuffle/shuffle. Matches@arraypress/waveform-bar1.7.0.
[0.1.1] — 2026-06-27
Section titled “[0.1.1] — 2026-06-27”Changed
Section titled “Changed”- Bumped the
@arraypress/waveform-playerpeer (and dev) dependency to^1.7.2for the native accessible keyboard / ARIA seek slider. No component API changes.
[0.1.0] — Unreleased
Section titled “[0.1.0] — Unreleased”Initial release.
<WaveformBar>— singleton mount component for the persistent bottom bar. Renders a persist host<div>and runswindow.WaveformBar.init(config)inside an effect. Tears down on unmount (StrictMode-safe) and re-inits only when the structural shape of the config changes — passing a fresh object reference with the same shape doesn’t trigger churn. Relocates the bar element into the persist host so route changes / re-renders don’t tear it down.<WaveformBarTrigger>— polymorphic click trigger. Defaults to<button>; override viaas="a" | "div" | "span". Emits the fulldata-wb-*attribute contract:- Track identity:
url,id,title,artist,album,artwork,link - Display chips:
duration,bpm,musicalKey,meta - Audio data:
waveform(peaks array, URL, or inline JSON),markers(DJ-mode chapters) - Initial state:
favorited,inCart - Behaviour:
mode='play' | 'queue',href(whenas="a"),aria-label,className,style,noDefaultIcons,children
- Track identity:
- Default
play / pauseSVG pair rendered as the trigger’s children when no custom content is passed. The library’swb-icon-swapCSS toggles them based on the active track state. - Auto-generated
aria-labelwhen one isn’t supplied —Play {title}for play triggers,Add {title} to queuefor queue triggers. - Public TypeScript types:
WaveformBarProps,WaveformBarConfig,WaveformBarTriggerProps,WaveformBarTrackData,WaveformBarMarker,WaveformBarActions,WaveformBarAction,WaveformBarTheme,RepeatMode,TriggerMode,WaveformStyle. - Ambient module shim for
@arraypress/waveform-barand@arraypress/waveform-playerso the wrapper typechecks cleanly until the core libraries ship.d.tsof their own. - SSR / RSC safe: the core library loads via dynamic
import()inside the effect, so the browser-only audio surface never evaluates server-side. - 46 Vitest tests via jsdom +
@testing-library/react:- 28 tests for
<WaveformBarTrigger>rendering + attribute mapping (no module mocking needed) - 18 tests for
<WaveformBar>lifecycle (window global mocked since jsdom has no Web Audio)
- 28 tests for
- Dual ESM (
dist/index.js) + CJS (dist/index.cjs) build viatsup..d.tsfor both. React + the two core libraries externalised so they resolve to the consumer’s copies. - README with full prop reference, seven usage patterns, and the
waveformbar:*custom-event API documented as the callback alternative. examples/basic.tsxwith seven copy-paste-ready snippets.
@arraypress/waveform-bar-vue
Section titled “@arraypress/waveform-bar-vue”[0.3.0] — 2026-07-22
Section titled “[0.3.0] — 2026-07-22”crossOriginconfig key. Added toWaveformBarConfigand forwarded verbatim towindow.WaveformBar.init(). Requires@arraypress/waveform-bar@^1.11.0for it to reach the embedded player.
[0.2.0] — 2026-07-05
Section titled “[0.2.0] — 2026-07-05”- Accept the new localizable player-string keys —
seekValueText,playPauseLabel,speedLabel,artworkAlt, andunknownTrackText— in the bar config; they are forwarded to the embedded player. Requires@arraypress/waveform-bar@^1.10.0.
[0.1.0] — Unreleased
Section titled “[0.1.0] — Unreleased”Initial release.
<WaveformBar>— singleton mount for the persistent bottom bar. Render once in your root layout. On mount it dynamically imports@arraypress/waveform-bar(SSR-safe) and callswindow.WaveformBar.init(config); re-inits when the config’s structural shape changes (compared viaJSON.stringify, so a fresh object with the same shape doesn’t churn); relocates the bar element into a persist host<div>; and callsdestroy()on unmount.config,persist,hostIdprops;class/stylefall through to the host (base classwb-host).<WaveformBarTrigger>— polymorphic (as="button" | "a" | "div" | "span", defaultbutton) click trigger that emits thedata-wb-*attribute contract the core library scans for. Maps track-data props (url,id,title,artist,album,artwork,link,duration,bpm,musicalKey,meta,waveform,markers,favorited,inCart) to attributes (arrays JSON-encoded; absent props emit no attribute).mode="play" | "queue",href(foras="a"),noDefaultIcons. Renders default play/pause SVGs unless slot content is provided. Auto-generates anaria-labelfromtitle.class, native listeners (@click), and other attributes fall through; the base classwb-icon-swapis always applied.- No lifecycle callback props — the bar dispatches every state change as a
bubbling
waveformbar:*CustomEvent; listen withaddEventListener. This keeps callbacks from forcing a bar re-init (matching the React wrapper). - Public types mirroring the core surface:
WaveformBarConfig,WaveformBarProps,WaveformBarTriggerProps,WaveformBarTrackData,WaveformBarMarker,WaveformBarActions,WaveformBarAction,WaveformBarTheme,RepeatMode,TriggerMode,WaveformStyle. - Dual ESM + CJS build via
tsupwith.d.tsfor both. Vue + the core libraries are peer dependencies. - Vitest test suite (jsdom +
@vue/test-utils, 13 tests) covering the singleton’s host render +init/ re-init /destroylifecycle, and the trigger’sdata-wb-*contract, polymorphism, modes, default-icon handling, class merge, and click forwarding.
@arraypress/waveform-bar-svelte
Section titled “@arraypress/waveform-bar-svelte”[0.3.0] — 2026-07-22
Section titled “[0.3.0] — 2026-07-22”crossOriginconfig key. Added toWaveformBarConfigand forwarded verbatim towindow.WaveformBar.init(). Requires@arraypress/waveform-bar@^1.11.0for it to reach the embedded player.
[0.2.0] — 2026-07-05
Section titled “[0.2.0] — 2026-07-05”- Accept the new localizable player-string keys —
seekValueText,playPauseLabel,speedLabel,artworkAlt, andunknownTrackText— in the bar config; they are forwarded to the embedded player. Requires@arraypress/waveform-bar@^1.10.0.
[0.1.0] — Unreleased
Section titled “[0.1.0] — Unreleased”Initial release.
<WaveformBar>— singleton mount (Svelte 5 runes) for the persistent bottom bar. Render once in your root layout. A browser-only$effectdynamically imports@arraypress/waveform-bar(SSR-safe) and callswindow.WaveformBar.init(config); a$derivedconfig key re-inits only when the config’s structural shape (orpersist) changes; the bar element is relocated into a persist host<div>;destroy()is called on unmount.config,persist,hostIdprops;class/ attributes fall through to the host (base classwb-host).<WaveformBarTrigger>— polymorphic (as="button" | "a" | "div" | "span"via<svelte:element>, defaultbutton) click trigger that emits thedata-wb-*attribute contract the core library scans for. Maps track-data props (url,id,title,artist,album,artwork,link,duration,bpm,musicalKey,meta,waveform,markers,favorited,inCart) to attributes (arrays JSON-encoded; absent props emit no attribute).mode="play" | "queue",href(foras="a"),noDefaultIcons. Renders default play/pause SVGs unless children are slotted. Auto-generates anaria-labelfromtitle.class, native listeners (onclick), and other attributes fall through via...rest; the base classwb-icon-swapis always applied.- No lifecycle callback props — the bar dispatches every state change as a
bubbling
waveformbar:*CustomEvent; listen withaddEventListener. - Public types mirroring the core surface:
WaveformBarConfig,WaveformBarProps,WaveformBarTriggerProps,WaveformBarTrackData,WaveformBarMarker,WaveformBarActions,WaveformBarAction,WaveformBarTheme,RepeatMode,TriggerMode,WaveformStyle. - Built with
svelte-package(dist/ships the preprocessed.svelte+ generated.d.ts). Svelte + the core libraries are peer dependencies. - Vitest test suite (jsdom +
@testing-library/svelte, 12 tests) covering the singleton’s host render +init/ re-init / no-churn /destroylifecycle, and the trigger’sdata-wb-*contract, polymorphism, modes, default-icon handling, class merge, and click forwarding.
@arraypress/waveform-playlist-astro
Section titled “@arraypress/waveform-playlist-astro”[0.4.0] — 2026-08-07
Section titled “[0.4.0] — 2026-08-07”- Forward the core player’s
crossOriginoption to the embedded player. Added to theAstro.propsdestructure and emitted as thedata-cross-origincontainer attribute. This option shipped across the rest of the waveform family in@arraypress/waveform-player@1.23.0but was missed in the playlist wrappers, so it was previously accepted by the types and silently dropped at runtime. Requires@arraypress/waveform-player@^1.23.0and@arraypress/waveform-playlist@^1.7.2(the version that began forwarding it to each track’s player).
[0.3.0] — 2026-07-05
Section titled “[0.3.0] — 2026-07-05”- Forward the core player’s new localizable UI-string options —
seekValueText,playPauseLabel,speedLabel,artworkAlt, andunknownTrackText— through to the underlying player. Requires@arraypress/waveform-player@^1.20.0.
[0.1.0] — Initial release
Section titled “[0.1.0] — Initial release”<WaveformPlaylist>Astro component wrapping@arraypress/waveform-playlist. Renders the library’s nested markup contract — a[data-waveform-playlist]container with one[data-track]child per track and one[data-chapter]child per chapter — from a single typedtracksarray.- Typed props for the playlist’s own options:
layout('list' | 'minimal'),continuous,expandChapters,showDuration,showChapterMarkers(boolean | null),chapterMarkerColor,showPlayState.
- Typed pass-through of the WaveformPlayer options the playlist forwards
to its embedded player —
waveformStyle,height,samples,barWidth,barSpacing,barRadius,colorPreset, the colour options (including gradient-arraywaveformColor/progressColor),playbackRate,showPlaybackSpeed,playbackRates,showControls,showInfo,showTime,showHoverTime,showBPM,bpm,buttonAlign,buttonStyle,accessibleSeek,seekLabel,errorText,showMarkers,autoplay,singlePlay,playOnSeek,enableMediaSession,preload,playIcon,pauseIcon. The per-track content fields (url,title,artist,artwork,album,markers) live on eachtracksentry instead, and the player’slayout/audioModeare intentionally not exposed (the playlist ownsdata-layoutand always drives a self-mode player). - A typed
tracksarray (WaveformPlaylistTrackInput[]) with per-trackurl,title,artist,artwork,album,duration,markers, andchapters({ time, label, color? }). - Astro-specific
lazyprop that switches the init attribute todata-waveform-playlist-lazyand ships a single deduplicatedIntersectionObserverthat promotes the playlist on viewport entry, plus a non-lazyastro:page-loadre-init for Astro View Transitions. - Astro-specific
id,class, andstylepass-throughs (wfpl-hostis always applied to the container). - Public TypeScript types derived from the two core packages so they
never drift:
WaveformPlaylistProps,WaveformPlaylistTrackInput, and re-exports ofWaveformPlaylistOptions/WaveformPlaylistTrack/WaveformPlaylistChapter/WaveformPlaylistMarker(from the playlist core) andWaveformStyle/WaveformMarker/WaveformPeaks/ColorPreset/AudioMode/AudioPreload/ButtonAlign(from the player core). - Vitest suite covering container option serialisation, omission semantics, JSON serialisation for array props, per-track and per-chapter rendering, lazy-mount and View-Transitions script presence, and the Astro extras.
- Documentation: full prop reference, setup guide, and usage examples
(
examples/basic.astro).
@arraypress/waveform-playlist-react
Section titled “@arraypress/waveform-playlist-react”[0.4.0] — 2026-08-07
Section titled “[0.4.0] — 2026-08-07”- Forward the core player’s
crossOriginoption to the embedded player. Forwarded in the constructor options builder and added to the remountuseEffectdependency array. This option shipped across the rest of the waveform family in@arraypress/waveform-player@1.23.0but was missed in the playlist wrappers, so it was previously accepted by the types and silently dropped at runtime. Requires@arraypress/waveform-player@^1.23.0and@arraypress/waveform-playlist@^1.7.2(the version that began forwarding it to each track’s player).
[0.3.0] — 2026-07-05
Section titled “[0.3.0] — 2026-07-05”- Forward the core player’s new localizable UI-string options —
seekValueText,playPauseLabel,speedLabel,artworkAlt, andunknownTrackText— through to the underlying player. Requires@arraypress/waveform-player@^1.20.0.
[0.1.0] — Unreleased
Section titled “[0.1.0] — Unreleased”Initial release.
<WaveformPlaylist>React component wrapping@arraypress/waveform-playlist:- A declarative, required
tracksarray (WaveformPlaylistTrackInput[]) rendered into the[data-track]/[data-chapter]child markup the playlist constructor parses on mount. Each track acceptsurl,title,artist,artwork,album,duration,markers, andchapters({ time, label, color? }, wheretimeis a seconds number or a'M:SS'string). - Playlist options as typed props:
layout('list' | 'minimal'),continuous,expandChapters,showDuration,showChapterMarkers,chapterMarkerColor,showPlayState. - Pass-through player options forwarded to the embedded player
(
waveformStyle,height,samples,barWidth,barSpacing,barRadius, colours,playbackRate,showPlaybackSpeed,playbackRates, UI toggles,accessibleSeek,seekLabel,errorText, behaviour flags, icons,audioMode,preload). - React-specific extras:
id,className,style, andrefforwarding viaWaveformPlaylistHandle.
- A declarative, required
WaveformPlaylistHandleimperative API on the forwarded ref —selectTrack(),seekToChapter(),nextTrack(),previousTrack(),getPlayer(),getCurrentTrackIndex(),getTracks(), plus the rawinstanceescape hatch.- SSR / RSC safe: the playlist library is loaded via dynamic
import('@arraypress/waveform-playlist')inside the effect so the browser-only audio surface never runs server-side. - Identity-prop re-mount: when any construction prop changes — the
serialised
tracks,layout,continuous, colours, sizing, etc. — the wrapper destroys the existing instance and creates a new one against the freshly-rendered markup. DOM-only props (className,style,id) do not trigger a re-mount. - The host container deliberately omits
data-waveform-playlistso the library’s global auto-init never double-mounts on top of the instance the wrapper creates explicitly. - Public TypeScript types:
WaveformPlaylistProps,WaveformPlaylistHandle,WaveformPlaylistTrackInput,WaveformPlaylistChapterInput, plus the re-exported core types (WaveformPlaylistOptions,WaveformPlaylistTrack,WaveformPlaylistChapter,WaveformPlaylistMarker,WaveformStyle,WaveformMarker,WaveformPeaks,ColorPreset,AudioMode,AudioPreload,ButtonAlign). - Vitest test suite (jsdom +
@testing-library/react) covering track / chapter markup rendering, mount, unmount destroy, option pass-through, identity-prop re-mount, ref forwarding, and the full imperative handle surface. The core library is mocked at the module boundary because jsdom has no Web Audio API. - Dual ESM (
dist/index.js) + CJS (dist/index.cjs) build viatsup, with.d.tsfor both. React and both@arraypress/waveform-*cores are externalised so they resolve to the consumer’s copies. - README with full prop reference and usage patterns, and
examples/basic.tsxwith seven copy-paste-ready snippets.
Peer dependencies
Section titled “Peer dependencies”@arraypress/waveform-playlist^1.3.0@arraypress/waveform-player^1.8.0react^18.0.0 || ^19.0.0
@arraypress/waveform-playlist-vue
Section titled “@arraypress/waveform-playlist-vue”[0.4.0] — 2026-08-07
Section titled “[0.4.0] — 2026-08-07”- Forward the core player’s
crossOriginoption to the embedded player. Added as a runtimepropsdeclaration (PropType<AudioCrossOrigin>), set in the options builder, and added to the remount watcher. This option shipped across the rest of the waveform family in@arraypress/waveform-player@1.23.0but was missed in the playlist wrappers, so it was previously accepted by the types and silently dropped at runtime. Requires@arraypress/waveform-player@^1.23.0and@arraypress/waveform-playlist@^1.7.2(the version that began forwarding it to each track’s player).
[0.3.0] — 2026-07-05
Section titled “[0.3.0] — 2026-07-05”- Forward the core player’s new localizable UI-string options —
seekValueText,playPauseLabel,speedLabel,artworkAlt, andunknownTrackText— through to the underlying player. Requires@arraypress/waveform-player@^1.20.0.
[0.1.0] — Unreleased
Section titled “[0.1.0] — Unreleased”Initial release.
<WaveformPlaylist>Vue 3 component wrapping@arraypress/waveform-playlist:- Declarative
tracksprop (with optional per-trackchaptersandmarkers), rendered into the[data-track]/[data-chapter]markup the playlist constructor parses on mount. - Playlist options as typed props:
layout('list' | 'minimal'),continuous,expandChapters,showDuration,showChapterMarkers,chapterMarkerColor,showPlayState. - The full pass-through player-option surface (waveform style, sizing,
colours, playback, UI toggles, accessibility, icons) — inherited from
the core
WaveformPlayerOptionsviaOmit<>, minus per-track content fields (which come fromtracks).
- Declarative
- Imperative navigation API exposed via a template
ref(WaveformPlaylistExpose):selectTrack(),seekToChapter(),nextTrack(),previousTrack(),getPlayer(),getCurrentTrackIndex(),getTracks(), plus the rawinstance. class,style, andidfall through to the host element via Vue’s attribute inheritance; the base classwfp-hostalways applies.- SSR / Nuxt safe: the core library is loaded via dynamic
import('@arraypress/waveform-playlist')insideonMounted. - Identity-prop re-mount: any construction-prop change (a serialised
trackschange, layout, options, …) destroys and rebuilds the instance. A monotonic mount token discards a superseded in-flight import; the watcher usesflush: 'post'so the fresh markup is in the DOM before the constructor re-parses it. - No lifecycle emits — the playlist owns the embedded player’s callbacks
internally (matching the React wrapper). Observe playback via the
embedded player from
getPlayer(). - Public types adopted from both cores (
@arraypress/waveform-playlist+@arraypress/waveform-player), re-exported so they can never drift. - Dual ESM + CJS build via
tsupwith.d.tsfor both. Vue + both cores are peer dependencies. - Vitest test suite (jsdom +
@vue/test-utils) covering host + track markup rendering, option mapping (tracks excluded), boolean-prop omission, destroy-on-unmount, identity-prop re-mount, and the exposed navigation API. The core is mocked at the module boundary.
@arraypress/waveform-playlist-svelte
Section titled “@arraypress/waveform-playlist-svelte”[0.4.0] — 2026-08-07
Section titled “[0.4.0] — 2026-08-07”- Forward the core player’s
crossOriginoption to the embedded player. Added to the$props()destructure (an undestructured prop falls into...restand is never forwarded) and set in the options builder. This option shipped across the rest of the waveform family in@arraypress/waveform-player@1.23.0but was missed in the playlist wrappers, so it was previously accepted by the types and silently dropped at runtime. Requires@arraypress/waveform-player@^1.23.0and@arraypress/waveform-playlist@^1.7.2(the version that began forwarding it to each track’s player).
[0.3.0] — 2026-07-05
Section titled “[0.3.0] — 2026-07-05”- Forward the core player’s new localizable UI-string options —
seekValueText,playPauseLabel,speedLabel,artworkAlt, andunknownTrackText— through to the underlying player. Requires@arraypress/waveform-player@^1.20.0.
[0.1.0] — Unreleased
Section titled “[0.1.0] — Unreleased”Initial release.
<WaveformPlaylist>Svelte 5 component (built with runes) wrapping@arraypress/waveform-playlist:- Declarative
tracksprop (with optional per-trackchaptersandmarkers), rendered into the[data-track]/[data-chapter]markup the playlist constructor parses on mount. - Playlist options as typed props:
layout('list' | 'minimal'),continuous,expandChapters,showDuration,showChapterMarkers,chapterMarkerColor,showPlayState. - The full pass-through player-option surface (waveform style, sizing,
colours, playback, UI toggles, accessibility, icons) — inherited from
the core
WaveformPlayerOptionsviaOmit<>, minus per-track content fields (which come fromtracks).
- Declarative
- Imperative navigation API exported by the component instance (reachable
via
bind:this):selectTrack(),seekToChapter(),nextTrack(),previousTrack(),getPlayer(),getCurrentTrackIndex(),getTracks(), andgetInstance(). class,style,id, and other element attributes fall through to the host element via...rest; the base classwfp-hostalways applies.- SSR / SvelteKit safe: the core library is loaded via dynamic
import('@arraypress/waveform-playlist')inside a browser-only$effect. - Identity-prop re-mount: a single
$effectreadsJSON.stringify(tracks)- every construction option, so any change destroys and rebuilds the instance over the freshly-rendered markup. A monotonic mount token discards a superseded in-flight import.
- Public types adopted from both cores (
@arraypress/waveform-playlist+@arraypress/waveform-player), re-exported so they can never drift. - Built with
svelte-package(dist/ships the preprocessed.svelte+ generated.d.ts). Svelte + both cores are peer dependencies. - Vitest test suite (jsdom +
@testing-library/svelte) covering host + track markup rendering, option mapping (tracks excluded), boolean-prop omission, destroy-on-unmount, identity-prop re-mount, and the exported navigation API. The core is mocked at the module boundary.