@arraypress/waveform-player 1.9.0 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/waveform-player.cjs +25 -7
- package/dist/waveform-player.cjs.map +2 -2
- package/dist/waveform-player.css +1 -1
- package/dist/waveform-player.esm.js +9 -9
- package/dist/waveform-player.esm.js.map +3 -3
- package/dist/waveform-player.js +25 -7
- package/dist/waveform-player.min.js +9 -9
- package/dist/waveform-player.min.js.map +3 -3
- package/index.d.ts +12 -0
- package/package.json +1 -1
- package/src/css/waveform-player.css +47 -4
- package/src/js/core.js +9 -2
- package/src/js/themes.js +17 -5
- package/src/js/utils.js +2 -0
package/index.d.ts
CHANGED
|
@@ -127,6 +127,18 @@ export interface WaveformPlayerOptions {
|
|
|
127
127
|
// ── Layout / UI toggles ───────────────────────────────────────
|
|
128
128
|
/** Play-button alignment. @default 'auto' */
|
|
129
129
|
buttonAlign?: ButtonAlign;
|
|
130
|
+
/**
|
|
131
|
+
* Player layout. `'preview'` centers the title under the waveform and trims
|
|
132
|
+
* the meta row (time/speed/BPM) — ideal for sample-pack previews.
|
|
133
|
+
* @default 'default'
|
|
134
|
+
*/
|
|
135
|
+
layout?: 'default' | 'preview';
|
|
136
|
+
/**
|
|
137
|
+
* Play/pause button style. `'minimal'` renders a bare glyph with no circle —
|
|
138
|
+
* the look sample-pack and beat stores use in preview grids.
|
|
139
|
+
* @default 'circle'
|
|
140
|
+
*/
|
|
141
|
+
buttonStyle?: 'circle' | 'minimal';
|
|
130
142
|
/** Show transport controls. @default true */
|
|
131
143
|
showControls?: boolean;
|
|
132
144
|
/** Show the info (title/subtitle) block. @default true */
|
package/package.json
CHANGED
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
font-family: inherit;
|
|
4
4
|
color: inherit;
|
|
5
5
|
line-height: var(--waveform-line-height, 1.4);
|
|
6
|
+
/* Neutral accent for the keyboard-focus ring + active states. Monochrome
|
|
7
|
+
by default (shadcn-style); override this variable to re-tint it. */
|
|
8
|
+
--wfp-accent: #71717a;
|
|
6
9
|
}
|
|
7
10
|
|
|
8
11
|
.waveform-player * {
|
|
@@ -48,6 +51,28 @@
|
|
|
48
51
|
transform: scale(1.05);
|
|
49
52
|
}
|
|
50
53
|
|
|
54
|
+
/* Minimal button style — a bare play/pause glyph with no circle. Set via
|
|
55
|
+
`buttonStyle: 'minimal'` / data-button-style="minimal". Ideal for sample-pack
|
|
56
|
+
and beat-store preview grids. */
|
|
57
|
+
.waveform-btn-minimal {
|
|
58
|
+
width: auto;
|
|
59
|
+
height: auto;
|
|
60
|
+
min-width: 0;
|
|
61
|
+
border: none;
|
|
62
|
+
border-radius: 0;
|
|
63
|
+
opacity: 0.7;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.waveform-btn-minimal:hover:not(:disabled) {
|
|
67
|
+
opacity: 1;
|
|
68
|
+
transform: none;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.waveform-btn-minimal svg {
|
|
72
|
+
width: 22px;
|
|
73
|
+
height: 22px;
|
|
74
|
+
}
|
|
75
|
+
|
|
51
76
|
.waveform-btn:disabled {
|
|
52
77
|
cursor: not-allowed;
|
|
53
78
|
opacity: 0.3;
|
|
@@ -302,13 +327,13 @@
|
|
|
302
327
|
}
|
|
303
328
|
|
|
304
329
|
.speed-option.active {
|
|
305
|
-
background: rgba(
|
|
306
|
-
color: #
|
|
330
|
+
background: rgba(255, 255, 255, 0.16);
|
|
331
|
+
color: #fff;
|
|
307
332
|
font-weight: 600;
|
|
308
333
|
}
|
|
309
334
|
|
|
310
335
|
.waveform-player.waveform-focused {
|
|
311
|
-
outline: 2px solid
|
|
336
|
+
outline: 2px solid var(--wfp-accent);
|
|
312
337
|
outline-offset: 2px;
|
|
313
338
|
border-radius: 4px;
|
|
314
339
|
}
|
|
@@ -320,10 +345,28 @@
|
|
|
320
345
|
|
|
321
346
|
/* Only show focus indicator when keyboard navigating (not clicking) */
|
|
322
347
|
.waveform-player:focus-visible {
|
|
323
|
-
outline: 1px solid
|
|
348
|
+
outline: 1px solid var(--wfp-accent);
|
|
324
349
|
outline-offset: 1px;
|
|
325
350
|
}
|
|
326
351
|
|
|
352
|
+
/* ==========================================================================
|
|
353
|
+
'preview' layout — compact, centered title under the waveform, trimmed
|
|
354
|
+
meta row. Ideal for sample-pack previews and dense grids.
|
|
355
|
+
========================================================================== */
|
|
356
|
+
.waveform-layout-preview .waveform-meta {
|
|
357
|
+
display: none !important;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.waveform-layout-preview .waveform-info {
|
|
361
|
+
justify-content: center;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
.waveform-layout-preview .waveform-text {
|
|
365
|
+
flex: 0 1 auto;
|
|
366
|
+
align-items: center;
|
|
367
|
+
text-align: center;
|
|
368
|
+
}
|
|
369
|
+
|
|
327
370
|
/* Remove the class-based focus indicator since we're using :focus-visible */
|
|
328
371
|
.waveform-player.waveform-focused {
|
|
329
372
|
outline: none;
|
package/src/js/core.js
CHANGED
|
@@ -224,9 +224,16 @@ export class WaveformPlayer {
|
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
+
// Compact 'preview' layout: centered title under the waveform with the
|
|
228
|
+
// meta row trimmed. Set via the `layout` option / data-layout="preview".
|
|
229
|
+
const isPreview = this.options.layout === 'preview';
|
|
230
|
+
if (isPreview) {
|
|
231
|
+
this.container.classList.add('waveform-layout-preview');
|
|
232
|
+
}
|
|
233
|
+
|
|
227
234
|
// Build play button HTML (conditional)
|
|
228
235
|
const buttonHTML = this.options.showControls ? `
|
|
229
|
-
<button class="waveform-btn" aria-label="Play/Pause" style="
|
|
236
|
+
<button class="waveform-btn${this.options.buttonStyle === 'minimal' ? ' waveform-btn-minimal' : ''}" aria-label="Play/Pause" style="
|
|
230
237
|
border-color: ${this.options.buttonColor};
|
|
231
238
|
color: ${this.options.buttonColor};
|
|
232
239
|
">
|
|
@@ -251,7 +258,7 @@ export class WaveformPlayer {
|
|
|
251
258
|
<span class="waveform-title" style="color: ${this.options.textColor};"></span>
|
|
252
259
|
${this.options.subtitle ? `<span class="waveform-subtitle" style="color: ${this.options.textSecondaryColor};">${this.options.subtitle}</span>` : ''}
|
|
253
260
|
</div>
|
|
254
|
-
<div style="display: flex; align-items: center; gap: 1rem;">
|
|
261
|
+
<div class="waveform-meta" style="display: flex; align-items: center; gap: 1rem;">
|
|
255
262
|
${this.options.showBPM ? `
|
|
256
263
|
<span class="waveform-bpm" style="color: ${this.options.textSecondaryColor}; display: none;">
|
|
257
264
|
<span class="bpm-value">--</span> BPM
|
package/src/js/themes.js
CHANGED
|
@@ -151,8 +151,11 @@ export function getColorPreset(presetName) {
|
|
|
151
151
|
export const DEFAULT_OPTIONS = {
|
|
152
152
|
// Core settings
|
|
153
153
|
url: '',
|
|
154
|
-
height:
|
|
155
|
-
|
|
154
|
+
height: 64,
|
|
155
|
+
// Source peak resolution. The drawer resamples these to fit
|
|
156
|
+
// canvasWidth / (barWidth + barSpacing) bars, so this is fidelity headroom,
|
|
157
|
+
// not the visible bar count.
|
|
158
|
+
samples: 256,
|
|
156
159
|
preload: 'metadata',
|
|
157
160
|
|
|
158
161
|
// Audio mode — 'self' = player owns the <audio> element (default, current
|
|
@@ -169,13 +172,22 @@ export const DEFAULT_OPTIONS = {
|
|
|
169
172
|
|
|
170
173
|
// Layout Options
|
|
171
174
|
buttonAlign: 'auto',
|
|
175
|
+
// Player layout. 'default' = play button + waveform with a left-aligned
|
|
176
|
+
// info row below. 'preview' = compact: the title is centered under the
|
|
177
|
+
// waveform and the meta row (time / speed / BPM) is trimmed — ideal for
|
|
178
|
+
// sample-pack sample previews and dense grids.
|
|
179
|
+
layout: 'default',
|
|
180
|
+
// Play/pause button style. 'circle' = bordered circle (default).
|
|
181
|
+
// 'minimal' = a bare play/pause glyph with no circle — the look sample-pack
|
|
182
|
+
// and beat stores use in their preview grids.
|
|
183
|
+
buttonStyle: 'circle',
|
|
172
184
|
|
|
173
185
|
// Default waveform style
|
|
174
186
|
waveformStyle: 'mirror',
|
|
175
187
|
barWidth: 2,
|
|
176
188
|
barSpacing: 0,
|
|
177
|
-
// Rounded bar caps (px). 0 = square (default). Applies to bars/mirror.
|
|
178
|
-
barRadius:
|
|
189
|
+
// Rounded bar caps (px). 0 = square; 1 = soft caps (default). Applies to bars/mirror.
|
|
190
|
+
barRadius: 1,
|
|
179
191
|
|
|
180
192
|
// Color preset: null = auto-detect, 'dark' = force dark, 'light' = force light
|
|
181
193
|
colorPreset: null,
|
|
@@ -245,7 +257,7 @@ export const DEFAULT_OPTIONS = {
|
|
|
245
257
|
*/
|
|
246
258
|
export const STYLE_DEFAULTS = {
|
|
247
259
|
bars: {barWidth: 3, barSpacing: 1},
|
|
248
|
-
mirror: {barWidth: 2, barSpacing:
|
|
260
|
+
mirror: {barWidth: 2, barSpacing: 2},
|
|
249
261
|
line: {barWidth: 2, barSpacing: 0},
|
|
250
262
|
blocks: {barWidth: 4, barSpacing: 2},
|
|
251
263
|
dots: {barWidth: 3, barSpacing: 3},
|
package/src/js/utils.js
CHANGED
|
@@ -137,6 +137,8 @@ export function parseDataAttributes(element) {
|
|
|
137
137
|
setNum('barSpacing');
|
|
138
138
|
setNum('barRadius');
|
|
139
139
|
if (element.dataset.buttonAlign) options.buttonAlign = element.dataset.buttonAlign;
|
|
140
|
+
if (element.dataset.layout) options.layout = element.dataset.layout;
|
|
141
|
+
if (element.dataset.buttonStyle) options.buttonStyle = element.dataset.buttonStyle;
|
|
140
142
|
|
|
141
143
|
// Color preset
|
|
142
144
|
if (element.dataset.colorPreset) options.colorPreset = element.dataset.colorPreset;
|