@zentauri-ui/zentauri-components 2.1.5 → 2.1.7

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.
Files changed (149) hide show
  1. package/README.md +12 -8
  2. package/cli/cli.integration.test.ts +36 -0
  3. package/cli/index.mjs +91 -12
  4. package/cli/index.test.ts +180 -0
  5. package/cli/props.json +609 -14
  6. package/cli/registry.json +22 -0
  7. package/cli/rewrite-imports.mjs +29 -4
  8. package/cli/rewrite-imports.test.ts +35 -0
  9. package/dist/{chunk-RENXBUZY.js → chunk-5ELR6MIN.js} +6 -6
  10. package/dist/{chunk-RENXBUZY.js.map → chunk-5ELR6MIN.js.map} +1 -1
  11. package/dist/chunk-5FU57ZVQ.js +19 -0
  12. package/dist/{chunk-D2GISTDL.js.map → chunk-5FU57ZVQ.js.map} +1 -1
  13. package/dist/chunk-74SKXGTM.js +4 -0
  14. package/dist/chunk-74SKXGTM.js.map +1 -0
  15. package/dist/{chunk-WBZKMSXW.mjs → chunk-7UXPXCKV.mjs} +3 -3
  16. package/dist/{chunk-WBZKMSXW.mjs.map → chunk-7UXPXCKV.mjs.map} +1 -1
  17. package/dist/chunk-COCPCZMR.mjs +77 -0
  18. package/dist/chunk-COCPCZMR.mjs.map +1 -0
  19. package/dist/chunk-CYKSS5S5.mjs +128 -0
  20. package/dist/chunk-CYKSS5S5.mjs.map +1 -0
  21. package/dist/chunk-DBNGLT5U.mjs +221 -0
  22. package/dist/chunk-DBNGLT5U.mjs.map +1 -0
  23. package/dist/{chunk-BL6UVCV7.mjs → chunk-FUCW5GPE.mjs} +36 -11
  24. package/dist/chunk-FUCW5GPE.mjs.map +1 -0
  25. package/dist/chunk-G7FVHZRB.js +225 -0
  26. package/dist/chunk-G7FVHZRB.js.map +1 -0
  27. package/dist/chunk-HMDH4BQJ.js +123 -0
  28. package/dist/chunk-HMDH4BQJ.js.map +1 -0
  29. package/dist/chunk-I7EBE7BD.js +98 -0
  30. package/dist/chunk-I7EBE7BD.js.map +1 -0
  31. package/dist/{chunk-PAG5CTLN.mjs → chunk-KVSRUAXP.mjs} +3 -3
  32. package/dist/{chunk-PAG5CTLN.mjs.map → chunk-KVSRUAXP.mjs.map} +1 -1
  33. package/dist/chunk-LHBJD57K.mjs +143 -0
  34. package/dist/chunk-LHBJD57K.mjs.map +1 -0
  35. package/dist/chunk-OYAJG2BO.js +83 -0
  36. package/dist/chunk-OYAJG2BO.js.map +1 -0
  37. package/dist/chunk-PG7LQVU6.js +86 -0
  38. package/dist/chunk-PG7LQVU6.js.map +1 -0
  39. package/dist/chunk-PTU5ZAYX.js +145 -0
  40. package/dist/chunk-PTU5ZAYX.js.map +1 -0
  41. package/dist/chunk-QKO5DA4N.mjs +81 -0
  42. package/dist/chunk-QKO5DA4N.mjs.map +1 -0
  43. package/dist/chunk-T7PIKDUZ.js +130 -0
  44. package/dist/chunk-T7PIKDUZ.js.map +1 -0
  45. package/dist/chunk-TDK5TVJE.mjs +3 -0
  46. package/dist/chunk-TDK5TVJE.mjs.map +1 -0
  47. package/dist/{chunk-NZSZE36T.js → chunk-TJ2EWPER.js} +42 -10
  48. package/dist/chunk-TJ2EWPER.js.map +1 -0
  49. package/dist/chunk-VBNW2B4D.mjs +3 -0
  50. package/dist/chunk-VBNW2B4D.mjs.map +1 -0
  51. package/dist/chunk-W6DO36XD.mjs +96 -0
  52. package/dist/chunk-W6DO36XD.mjs.map +1 -0
  53. package/dist/chunk-XR3J46TZ.js +4 -0
  54. package/dist/chunk-XR3J46TZ.js.map +1 -0
  55. package/dist/chunk-ZOHCADDL.mjs +121 -0
  56. package/dist/chunk-ZOHCADDL.mjs.map +1 -0
  57. package/dist/design-system/audio-player.d.ts +61 -0
  58. package/dist/design-system/audio-player.d.ts.map +1 -0
  59. package/dist/design-system/data-table.d.ts +8 -0
  60. package/dist/design-system/data-table.d.ts.map +1 -0
  61. package/dist/design-system/facade.js +11 -10
  62. package/dist/design-system/facade.js.map +1 -1
  63. package/dist/design-system/facade.mjs +10 -9
  64. package/dist/design-system/facade.mjs.map +1 -1
  65. package/dist/design-system/index.d.ts +2 -0
  66. package/dist/design-system/index.d.ts.map +1 -1
  67. package/dist/hooks/useTableFilter.js +6 -116
  68. package/dist/hooks/useTableFilter.js.map +1 -1
  69. package/dist/hooks/useTableFilter.mjs +1 -118
  70. package/dist/hooks/useTableFilter.mjs.map +1 -1
  71. package/dist/hooks/useTableSort.js +6 -91
  72. package/dist/hooks/useTableSort.js.map +1 -1
  73. package/dist/hooks/useTableSort.mjs +1 -93
  74. package/dist/hooks/useTableSort.mjs.map +1 -1
  75. package/dist/hooks/useVirtualList.js +6 -76
  76. package/dist/hooks/useVirtualList.js.map +1 -1
  77. package/dist/hooks/useVirtualList.mjs +1 -78
  78. package/dist/hooks/useVirtualList.mjs.map +1 -1
  79. package/dist/ui/audio-player/audio-player-base.d.ts +20 -0
  80. package/dist/ui/audio-player/audio-player-base.d.ts.map +1 -0
  81. package/dist/ui/audio-player/audio-player.d.ts +6 -0
  82. package/dist/ui/audio-player/audio-player.d.ts.map +1 -0
  83. package/dist/ui/audio-player/index.d.ts +5 -0
  84. package/dist/ui/audio-player/index.d.ts.map +1 -0
  85. package/dist/ui/audio-player/types.d.ts +44 -0
  86. package/dist/ui/audio-player/types.d.ts.map +1 -0
  87. package/dist/ui/audio-player/variants.d.ts +12 -0
  88. package/dist/ui/audio-player/variants.d.ts.map +1 -0
  89. package/dist/ui/audio-player.js +556 -0
  90. package/dist/ui/audio-player.js.map +1 -0
  91. package/dist/ui/audio-player.mjs +545 -0
  92. package/dist/ui/audio-player.mjs.map +1 -0
  93. package/dist/ui/buttons/animated.js +13 -12
  94. package/dist/ui/buttons/animated.js.map +1 -1
  95. package/dist/ui/buttons/animated.mjs +11 -10
  96. package/dist/ui/buttons/animated.mjs.map +1 -1
  97. package/dist/ui/buttons.js +15 -13
  98. package/dist/ui/buttons.mjs +13 -11
  99. package/dist/ui/checkbox.js +7 -123
  100. package/dist/ui/checkbox.js.map +1 -1
  101. package/dist/ui/checkbox.mjs +2 -126
  102. package/dist/ui/checkbox.mjs.map +1 -1
  103. package/dist/ui/data-table/data-table-base.d.ts +6 -0
  104. package/dist/ui/data-table/data-table-base.d.ts.map +1 -0
  105. package/dist/ui/data-table/data-table.d.ts +6 -0
  106. package/dist/ui/data-table/data-table.d.ts.map +1 -0
  107. package/dist/ui/data-table/index.d.ts +4 -0
  108. package/dist/ui/data-table/index.d.ts.map +1 -0
  109. package/dist/ui/data-table/types.d.ts +92 -0
  110. package/dist/ui/data-table/types.d.ts.map +1 -0
  111. package/dist/ui/data-table/variants.d.ts +8 -0
  112. package/dist/ui/data-table/variants.d.ts.map +1 -0
  113. package/dist/ui/data-table.js +620 -0
  114. package/dist/ui/data-table.js.map +1 -0
  115. package/dist/ui/data-table.mjs +611 -0
  116. package/dist/ui/data-table.mjs.map +1 -0
  117. package/dist/ui/dynamic-stepper.js +23 -22
  118. package/dist/ui/dynamic-stepper.js.map +1 -1
  119. package/dist/ui/dynamic-stepper.mjs +12 -11
  120. package/dist/ui/dynamic-stepper.mjs.map +1 -1
  121. package/dist/ui/inputs.js +7 -138
  122. package/dist/ui/inputs.js.map +1 -1
  123. package/dist/ui/inputs.mjs +2 -141
  124. package/dist/ui/inputs.mjs.map +1 -1
  125. package/dist/ui/pagination.js +25 -225
  126. package/dist/ui/pagination.js.map +1 -1
  127. package/dist/ui/pagination.mjs +13 -227
  128. package/dist/ui/pagination.mjs.map +1 -1
  129. package/dist/ui/table.js +1 -0
  130. package/dist/ui/table.mjs +1 -0
  131. package/package.json +1 -1
  132. package/src/design-system/audio-player.ts +109 -0
  133. package/src/design-system/data-table.ts +20 -0
  134. package/src/design-system/index.ts +2 -0
  135. package/src/ui/audio-player/audio-player-base.tsx +557 -0
  136. package/src/ui/audio-player/audio-player.test.tsx +485 -0
  137. package/src/ui/audio-player/audio-player.tsx +8 -0
  138. package/src/ui/audio-player/index.ts +24 -0
  139. package/src/ui/audio-player/types.ts +57 -0
  140. package/src/ui/audio-player/variants.ts +43 -0
  141. package/src/ui/data-table/data-table-base.tsx +701 -0
  142. package/src/ui/data-table/data-table.test.tsx +389 -0
  143. package/src/ui/data-table/data-table.tsx +11 -0
  144. package/src/ui/data-table/index.ts +24 -0
  145. package/src/ui/data-table/types.ts +121 -0
  146. package/src/ui/data-table/variants.ts +21 -0
  147. package/dist/chunk-BL6UVCV7.mjs.map +0 -1
  148. package/dist/chunk-D2GISTDL.js +0 -19
  149. package/dist/chunk-NZSZE36T.js.map +0 -1
@@ -0,0 +1,545 @@
1
+ "use client";
2
+ import { zuiAudioPlayerBase, zuiAudioPlayerShapes, zuiAudioPlayerSizes, zuiAudioPlayerAppearances, zuiAudioPlayerTrackBase, zuiAudioPlayerTrackSizes, zuiAudioPlayerBarBase, zuiAudioPlayerTimeBase } from '../chunk-COCPCZMR.mjs';
3
+ import { cn } from '../chunk-4D54YOL6.mjs';
4
+ import '../chunk-J5LGTIGS.mjs';
5
+ import { createContext, useContext, useRef, useState, useEffect, useCallback, useMemo } from 'react';
6
+ import { cva } from 'class-variance-authority';
7
+ import { jsx, jsxs } from 'react/jsx-runtime';
8
+
9
+ var audioPlayerVariants = cva(
10
+ [...zuiAudioPlayerBase, "flex flex-col"],
11
+ {
12
+ variants: {
13
+ appearance: zuiAudioPlayerAppearances,
14
+ size: zuiAudioPlayerSizes,
15
+ shape: zuiAudioPlayerShapes
16
+ },
17
+ defaultVariants: {
18
+ appearance: "default",
19
+ size: "md",
20
+ shape: "rounded"
21
+ }
22
+ }
23
+ );
24
+ var audioPlayerTrackVariants = cva([...zuiAudioPlayerTrackBase], {
25
+ variants: {
26
+ size: zuiAudioPlayerTrackSizes,
27
+ shape: zuiAudioPlayerShapes
28
+ },
29
+ defaultVariants: {
30
+ size: "md",
31
+ shape: "rounded"
32
+ }
33
+ });
34
+ var audioPlayerBarVariants = cva(zuiAudioPlayerBarBase);
35
+ var audioPlayerTimeVariants = cva(zuiAudioPlayerTimeBase);
36
+ var AudioPlayerContext = createContext(null);
37
+ function useAudioPlayer() {
38
+ const ctx = useContext(AudioPlayerContext);
39
+ if (!ctx) {
40
+ throw new Error("useAudioPlayer must be used within <AudioPlayer>");
41
+ }
42
+ return ctx;
43
+ }
44
+ function formatTime(seconds) {
45
+ if (!isFinite(seconds) || isNaN(seconds)) return "0:00";
46
+ const m = Math.floor(seconds / 60);
47
+ const s = Math.floor(seconds % 60);
48
+ return `${m}:${s.toString().padStart(2, "0")}`;
49
+ }
50
+ function AudioPlayerBase(props) {
51
+ const {
52
+ className,
53
+ appearance = "default",
54
+ size = "md",
55
+ shape = "rounded",
56
+ src,
57
+ children,
58
+ autoPlay = false,
59
+ loop = false,
60
+ onEnded,
61
+ onPlay,
62
+ onPause,
63
+ onTimeUpdate,
64
+ ref,
65
+ ...rest
66
+ } = props;
67
+ const audioRef = useRef(null);
68
+ const [isPlaying, setIsPlaying] = useState(false);
69
+ const [currentTime, setCurrentTime] = useState(0);
70
+ const [duration, setDuration] = useState(0);
71
+ const [volume, setVolumeState] = useState(1);
72
+ const [muted, setMuted] = useState(false);
73
+ const progress = duration > 0 ? currentTime / duration * 100 : 0;
74
+ const callbacksRef = useRef({ onEnded, onPlay, onPause, onTimeUpdate });
75
+ useEffect(() => {
76
+ callbacksRef.current = { onEnded, onPlay, onPause, onTimeUpdate };
77
+ });
78
+ useEffect(() => {
79
+ setIsPlaying(false);
80
+ setCurrentTime(0);
81
+ setDuration(0);
82
+ }, [src]);
83
+ useEffect(() => {
84
+ const audio = audioRef.current;
85
+ if (!audio) return;
86
+ const handleTimeUpdate = () => {
87
+ setCurrentTime(audio.currentTime);
88
+ callbacksRef.current.onTimeUpdate?.(audio.currentTime, audio.duration);
89
+ };
90
+ const handleDurationChange = () => {
91
+ if (isFinite(audio.duration)) setDuration(audio.duration);
92
+ };
93
+ const handlePlay = () => {
94
+ setIsPlaying(true);
95
+ callbacksRef.current.onPlay?.();
96
+ };
97
+ const handlePause = () => {
98
+ setIsPlaying(false);
99
+ callbacksRef.current.onPause?.();
100
+ };
101
+ const handleEnded = () => {
102
+ setIsPlaying(false);
103
+ callbacksRef.current.onEnded?.();
104
+ };
105
+ const handleVolumeChange = () => {
106
+ setVolumeState(audio.volume);
107
+ setMuted(audio.muted);
108
+ };
109
+ audio.addEventListener("timeupdate", handleTimeUpdate);
110
+ audio.addEventListener("durationchange", handleDurationChange);
111
+ audio.addEventListener("loadedmetadata", handleDurationChange);
112
+ audio.addEventListener("play", handlePlay);
113
+ audio.addEventListener("pause", handlePause);
114
+ audio.addEventListener("ended", handleEnded);
115
+ audio.addEventListener("volumechange", handleVolumeChange);
116
+ return () => {
117
+ audio.removeEventListener("timeupdate", handleTimeUpdate);
118
+ audio.removeEventListener("durationchange", handleDurationChange);
119
+ audio.removeEventListener("loadedmetadata", handleDurationChange);
120
+ audio.removeEventListener("play", handlePlay);
121
+ audio.removeEventListener("pause", handlePause);
122
+ audio.removeEventListener("ended", handleEnded);
123
+ audio.removeEventListener("volumechange", handleVolumeChange);
124
+ };
125
+ }, []);
126
+ const play = useCallback(() => {
127
+ audioRef.current?.play().catch(() => {
128
+ });
129
+ }, []);
130
+ const pause = useCallback(() => {
131
+ audioRef.current?.pause();
132
+ }, []);
133
+ const toggle = useCallback(() => {
134
+ const audio = audioRef.current;
135
+ if (!audio) return;
136
+ if (audio.paused) {
137
+ audio.play().catch(() => {
138
+ });
139
+ } else {
140
+ audio.pause();
141
+ }
142
+ }, []);
143
+ const reset = useCallback(() => {
144
+ const audio = audioRef.current;
145
+ if (!audio) return;
146
+ audio.pause();
147
+ audio.currentTime = 0;
148
+ setIsPlaying(false);
149
+ setCurrentTime(0);
150
+ }, []);
151
+ const seek = useCallback((seconds) => {
152
+ const audio = audioRef.current;
153
+ if (!audio || !isFinite(audio.duration) || audio.duration <= 0) return;
154
+ const nextTime = Math.max(0, Math.min(seconds, audio.duration));
155
+ audio.currentTime = nextTime;
156
+ setDuration(audio.duration);
157
+ setCurrentTime(nextTime);
158
+ }, []);
159
+ const seekByPercent = useCallback((percent) => {
160
+ const audio = audioRef.current;
161
+ if (!audio || !isFinite(percent) || !isFinite(audio.duration) || audio.duration <= 0) {
162
+ return;
163
+ }
164
+ const clamped = Math.max(0, Math.min(percent, 100));
165
+ const nextTime = clamped / 100 * audio.duration;
166
+ audio.currentTime = nextTime;
167
+ setDuration(audio.duration);
168
+ setCurrentTime(nextTime);
169
+ }, []);
170
+ const setVolume = useCallback((vol) => {
171
+ const audio = audioRef.current;
172
+ if (!audio || !isFinite(vol)) return;
173
+ const nextVolume = Math.max(0, Math.min(vol, 1));
174
+ audio.volume = nextVolume;
175
+ setVolumeState(nextVolume);
176
+ }, []);
177
+ const toggleMute = useCallback(() => {
178
+ const audio = audioRef.current;
179
+ if (!audio) return;
180
+ const nextMuted = !audio.muted;
181
+ audio.muted = nextMuted;
182
+ setMuted(nextMuted);
183
+ }, []);
184
+ const ctx = useMemo(
185
+ () => ({
186
+ isPlaying,
187
+ currentTime,
188
+ duration,
189
+ progress,
190
+ volume,
191
+ muted,
192
+ play,
193
+ pause,
194
+ toggle,
195
+ reset,
196
+ seek,
197
+ seekByPercent,
198
+ setVolume,
199
+ toggleMute,
200
+ size: size ?? "md",
201
+ shape: shape ?? "rounded",
202
+ appearance: appearance ?? "default"
203
+ }),
204
+ [
205
+ isPlaying,
206
+ currentTime,
207
+ duration,
208
+ progress,
209
+ volume,
210
+ muted,
211
+ play,
212
+ pause,
213
+ toggle,
214
+ reset,
215
+ seek,
216
+ seekByPercent,
217
+ setVolume,
218
+ toggleMute,
219
+ size,
220
+ shape,
221
+ appearance
222
+ ]
223
+ );
224
+ return /* @__PURE__ */ jsx(AudioPlayerContext.Provider, { value: ctx, children: /* @__PURE__ */ jsxs(
225
+ "div",
226
+ {
227
+ ref,
228
+ "data-slot": "audio-player",
229
+ className: cn(
230
+ audioPlayerVariants({ appearance, size, shape }),
231
+ className
232
+ ),
233
+ ...rest,
234
+ children: [
235
+ /* @__PURE__ */ jsx(
236
+ "audio",
237
+ {
238
+ ref: audioRef,
239
+ src,
240
+ autoPlay,
241
+ loop,
242
+ preload: "metadata",
243
+ className: "hidden",
244
+ "aria-hidden": "true"
245
+ }
246
+ ),
247
+ children
248
+ ]
249
+ }
250
+ ) });
251
+ }
252
+ AudioPlayerBase.displayName = "AudioPlayer";
253
+ function AudioPlayerProgress({
254
+ className,
255
+ ref,
256
+ ...rest
257
+ }) {
258
+ const { progress, seekByPercent, size, shape } = useAudioPlayer();
259
+ const trackRef = useRef(null);
260
+ const draggingRef = useRef(false);
261
+ const getPercentFromEvent = useCallback((clientX) => {
262
+ const el = trackRef.current;
263
+ if (!el) return 0;
264
+ const { left, width } = el.getBoundingClientRect();
265
+ return Math.max(0, Math.min((clientX - left) / width * 100, 100));
266
+ }, []);
267
+ const handleClick = useCallback(
268
+ (e) => {
269
+ if (draggingRef.current) return;
270
+ seekByPercent(getPercentFromEvent(e.clientX));
271
+ },
272
+ [getPercentFromEvent, seekByPercent]
273
+ );
274
+ const handlePointerDown = useCallback(
275
+ (e) => {
276
+ draggingRef.current = true;
277
+ e.currentTarget.setPointerCapture?.(e.pointerId);
278
+ seekByPercent(getPercentFromEvent(e.clientX));
279
+ },
280
+ [getPercentFromEvent, seekByPercent]
281
+ );
282
+ const handlePointerMove = useCallback(
283
+ (e) => {
284
+ if (!draggingRef.current) return;
285
+ seekByPercent(getPercentFromEvent(e.clientX));
286
+ },
287
+ [getPercentFromEvent, seekByPercent]
288
+ );
289
+ const handlePointerUp = useCallback(() => {
290
+ draggingRef.current = false;
291
+ }, []);
292
+ const handleKeyDown = useCallback(
293
+ (e) => {
294
+ if (e.key === "ArrowRight" || e.key === "ArrowUp") {
295
+ e.preventDefault();
296
+ seekByPercent(Math.min(progress + 1, 100));
297
+ } else if (e.key === "ArrowLeft" || e.key === "ArrowDown") {
298
+ e.preventDefault();
299
+ seekByPercent(Math.max(progress - 1, 0));
300
+ } else if (e.key === "Home") {
301
+ e.preventDefault();
302
+ seekByPercent(0);
303
+ } else if (e.key === "End") {
304
+ e.preventDefault();
305
+ seekByPercent(100);
306
+ }
307
+ },
308
+ [progress, seekByPercent]
309
+ );
310
+ return /* @__PURE__ */ jsx(
311
+ "div",
312
+ {
313
+ ref: (node) => {
314
+ trackRef.current = node;
315
+ if (typeof ref === "function") ref(node);
316
+ else if (ref)
317
+ ref.current = node;
318
+ },
319
+ "data-slot": "audio-player-progress",
320
+ role: "slider",
321
+ "aria-label": "Audio progress",
322
+ "aria-valuenow": Math.round(progress),
323
+ "aria-valuemin": 0,
324
+ "aria-valuemax": 100,
325
+ tabIndex: 0,
326
+ className: cn(
327
+ audioPlayerTrackVariants({ size, shape }),
328
+ "group",
329
+ className
330
+ ),
331
+ onClick: handleClick,
332
+ onPointerDown: handlePointerDown,
333
+ onPointerMove: handlePointerMove,
334
+ onPointerUp: handlePointerUp,
335
+ onPointerCancel: handlePointerUp,
336
+ onKeyDown: handleKeyDown,
337
+ ...rest,
338
+ children: /* @__PURE__ */ jsx(
339
+ "div",
340
+ {
341
+ "data-slot": "audio-player-bar",
342
+ className: cn(
343
+ audioPlayerBarVariants(),
344
+ "rounded-[inherit] group-hover:opacity-90 transition-opacity"
345
+ ),
346
+ style: { transform: `scaleX(${progress / 100})` }
347
+ }
348
+ )
349
+ }
350
+ );
351
+ }
352
+ AudioPlayerProgress.displayName = "AudioPlayerProgress";
353
+ function AudioPlayerTime({
354
+ className,
355
+ format = formatTime
356
+ }) {
357
+ const { currentTime, duration } = useAudioPlayer();
358
+ return /* @__PURE__ */ jsxs(
359
+ "div",
360
+ {
361
+ "data-slot": "audio-player-time",
362
+ className: cn(
363
+ audioPlayerTimeVariants(),
364
+ "flex items-center gap-1",
365
+ className
366
+ ),
367
+ children: [
368
+ /* @__PURE__ */ jsx("span", { "aria-label": "Current time", children: format(currentTime) }),
369
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "/" }),
370
+ /* @__PURE__ */ jsx("span", { "aria-label": "Total duration", children: format(duration) })
371
+ ]
372
+ }
373
+ );
374
+ }
375
+ AudioPlayerTime.displayName = "AudioPlayerTime";
376
+ function AudioPlayerVolume({
377
+ className,
378
+ ref,
379
+ ...rest
380
+ }) {
381
+ const { volume, muted, setVolume, toggleMute } = useAudioPlayer();
382
+ const trackRef = useRef(null);
383
+ const draggingRef = useRef(false);
384
+ const getVolumeFromEvent = useCallback((clientX) => {
385
+ const el = trackRef.current;
386
+ if (!el) return 0;
387
+ const { left, width } = el.getBoundingClientRect();
388
+ return Math.max(0, Math.min((clientX - left) / width, 1));
389
+ }, []);
390
+ const handlePointerDown = useCallback(
391
+ (e) => {
392
+ draggingRef.current = true;
393
+ e.currentTarget.setPointerCapture?.(e.pointerId);
394
+ setVolume(getVolumeFromEvent(e.clientX));
395
+ },
396
+ [getVolumeFromEvent, setVolume]
397
+ );
398
+ const handlePointerMove = useCallback(
399
+ (e) => {
400
+ if (!draggingRef.current) return;
401
+ setVolume(getVolumeFromEvent(e.clientX));
402
+ },
403
+ [getVolumeFromEvent, setVolume]
404
+ );
405
+ const handlePointerUp = useCallback(() => {
406
+ draggingRef.current = false;
407
+ }, []);
408
+ const handleClick = useCallback(
409
+ (e) => {
410
+ if (draggingRef.current) return;
411
+ setVolume(getVolumeFromEvent(e.clientX));
412
+ },
413
+ [getVolumeFromEvent, setVolume]
414
+ );
415
+ const displayVolume = muted ? 0 : volume;
416
+ const handleKeyDown = useCallback(
417
+ (e) => {
418
+ if (e.key === "ArrowRight" || e.key === "ArrowUp") {
419
+ e.preventDefault();
420
+ setVolume(Math.min(volume + 0.05, 1));
421
+ } else if (e.key === "ArrowLeft" || e.key === "ArrowDown") {
422
+ e.preventDefault();
423
+ setVolume(Math.max(volume - 0.05, 0));
424
+ } else if (e.key === "Home") {
425
+ e.preventDefault();
426
+ setVolume(0);
427
+ } else if (e.key === "End") {
428
+ e.preventDefault();
429
+ setVolume(1);
430
+ }
431
+ },
432
+ [volume, setVolume]
433
+ );
434
+ return /* @__PURE__ */ jsxs(
435
+ "div",
436
+ {
437
+ "data-slot": "audio-player-volume",
438
+ className: cn("flex items-center gap-2", className),
439
+ ...rest,
440
+ children: [
441
+ /* @__PURE__ */ jsx(
442
+ "button",
443
+ {
444
+ type: "button",
445
+ "aria-label": muted ? "Unmute" : "Mute",
446
+ onClick: toggleMute,
447
+ className: "shrink-0 rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--audio-fill,#0f172a)]",
448
+ children: displayVolume === 0 ? /* @__PURE__ */ jsxs(
449
+ "svg",
450
+ {
451
+ className: "h-4 w-4",
452
+ viewBox: "0 0 24 24",
453
+ fill: "none",
454
+ stroke: "currentColor",
455
+ strokeWidth: 2,
456
+ strokeLinecap: "round",
457
+ strokeLinejoin: "round",
458
+ "aria-hidden": "true",
459
+ children: [
460
+ /* @__PURE__ */ jsx("polygon", { points: "11 5 6 9 2 9 2 15 6 15 11 19 11 5" }),
461
+ /* @__PURE__ */ jsx("line", { x1: "23", y1: "9", x2: "17", y2: "15" }),
462
+ /* @__PURE__ */ jsx("line", { x1: "17", y1: "9", x2: "23", y2: "15" })
463
+ ]
464
+ }
465
+ ) : displayVolume < 0.5 ? /* @__PURE__ */ jsxs(
466
+ "svg",
467
+ {
468
+ className: "h-4 w-4",
469
+ viewBox: "0 0 24 24",
470
+ fill: "none",
471
+ stroke: "currentColor",
472
+ strokeWidth: 2,
473
+ strokeLinecap: "round",
474
+ strokeLinejoin: "round",
475
+ "aria-hidden": "true",
476
+ children: [
477
+ /* @__PURE__ */ jsx("polygon", { points: "11 5 6 9 2 9 2 15 6 15 11 19 11 5" }),
478
+ /* @__PURE__ */ jsx("path", { d: "M15.54 8.46a5 5 0 0 1 0 7.07" })
479
+ ]
480
+ }
481
+ ) : /* @__PURE__ */ jsxs(
482
+ "svg",
483
+ {
484
+ className: "h-4 w-4",
485
+ viewBox: "0 0 24 24",
486
+ fill: "none",
487
+ stroke: "currentColor",
488
+ strokeWidth: 2,
489
+ strokeLinecap: "round",
490
+ strokeLinejoin: "round",
491
+ "aria-hidden": "true",
492
+ children: [
493
+ /* @__PURE__ */ jsx("polygon", { points: "11 5 6 9 2 9 2 15 6 15 11 19 11 5" }),
494
+ /* @__PURE__ */ jsx("path", { d: "M19.07 4.93a10 10 0 0 1 0 14.14" }),
495
+ /* @__PURE__ */ jsx("path", { d: "M15.54 8.46a5 5 0 0 1 0 7.07" })
496
+ ]
497
+ }
498
+ )
499
+ }
500
+ ),
501
+ /* @__PURE__ */ jsx(
502
+ "div",
503
+ {
504
+ ref: (node) => {
505
+ trackRef.current = node;
506
+ if (typeof ref === "function") ref(node);
507
+ else if (ref)
508
+ ref.current = node;
509
+ },
510
+ role: "slider",
511
+ "aria-label": "Volume",
512
+ "aria-valuenow": Math.round(displayVolume * 100),
513
+ "aria-valuemin": 0,
514
+ "aria-valuemax": 100,
515
+ tabIndex: 0,
516
+ className: "relative h-1.5 w-20 cursor-pointer overflow-hidden rounded-full bg-[var(--zui-audio-player-track-bg,var(--zui-surface-muted,#0000001a))] dark:bg-[var(--zui-audio-player-track-bg-dark,var(--zui-surface-muted-dark,#ffffff1a))] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--audio-fill,#0f172a)]",
517
+ onClick: handleClick,
518
+ onPointerDown: handlePointerDown,
519
+ onPointerMove: handlePointerMove,
520
+ onPointerUp: handlePointerUp,
521
+ onPointerCancel: handlePointerUp,
522
+ onKeyDown: handleKeyDown,
523
+ children: /* @__PURE__ */ jsx(
524
+ "div",
525
+ {
526
+ "data-slot": "audio-player-volume-bar",
527
+ className: "h-full origin-left [background:var(--audio-fill)] rounded-[inherit]",
528
+ style: { transform: `scaleX(${displayVolume})` }
529
+ }
530
+ )
531
+ }
532
+ )
533
+ ]
534
+ }
535
+ );
536
+ }
537
+ AudioPlayerVolume.displayName = "AudioPlayerVolume";
538
+ var AudioPlayer = (props) => {
539
+ return /* @__PURE__ */ jsx(AudioPlayerBase, { ...props });
540
+ };
541
+ AudioPlayer.displayName = "AudioPlayer";
542
+
543
+ export { AudioPlayer, AudioPlayerBase, AudioPlayerProgress, AudioPlayerTime, AudioPlayerVolume, audioPlayerBarVariants, audioPlayerTimeVariants, audioPlayerTrackVariants, audioPlayerVariants, useAudioPlayer };
544
+ //# sourceMappingURL=audio-player.mjs.map
545
+ //# sourceMappingURL=audio-player.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/ui/audio-player/variants.ts","../../src/ui/audio-player/audio-player-base.tsx","../../src/ui/audio-player/audio-player.tsx"],"names":["jsx"],"mappings":"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","file":"audio-player.mjs","sourcesContent":["import { cva } from \"class-variance-authority\";\n\nimport {\n zuiAudioPlayerAppearances,\n zuiAudioPlayerBarBase,\n zuiAudioPlayerBase,\n zuiAudioPlayerShapes,\n zuiAudioPlayerSizes,\n zuiAudioPlayerTimeBase,\n zuiAudioPlayerTrackBase,\n zuiAudioPlayerTrackSizes,\n} from \"../../design-system/audio-player\";\n\nexport const audioPlayerVariants = cva(\n [...zuiAudioPlayerBase, \"flex flex-col\"],\n {\n variants: {\n appearance: zuiAudioPlayerAppearances,\n size: zuiAudioPlayerSizes,\n shape: zuiAudioPlayerShapes,\n },\n defaultVariants: {\n appearance: \"default\",\n size: \"md\",\n shape: \"rounded\",\n },\n },\n);\n\nexport const audioPlayerTrackVariants = cva([...zuiAudioPlayerTrackBase], {\n variants: {\n size: zuiAudioPlayerTrackSizes,\n shape: zuiAudioPlayerShapes,\n },\n defaultVariants: {\n size: \"md\",\n shape: \"rounded\",\n },\n});\n\nexport const audioPlayerBarVariants = cva(zuiAudioPlayerBarBase);\n\nexport const audioPlayerTimeVariants = cva(zuiAudioPlayerTimeBase);\n","\"use client\";\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { KeyboardEvent, MouseEvent, PointerEvent } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nimport type {\n AudioPlayerCtx,\n AudioPlayerProgressProps,\n AudioPlayerProps,\n AudioPlayerTimeProps,\n AudioPlayerVolumeProps,\n} from \"./types\";\nimport {\n audioPlayerBarVariants,\n audioPlayerTimeVariants,\n audioPlayerTrackVariants,\n audioPlayerVariants,\n} from \"./variants\";\n\nexport const AudioPlayerContext = createContext<AudioPlayerCtx | null>(null);\n\nexport function useAudioPlayer(): AudioPlayerCtx {\n const ctx = useContext(AudioPlayerContext);\n if (!ctx) {\n throw new Error(\"useAudioPlayer must be used within <AudioPlayer>\");\n }\n return ctx;\n}\n\nfunction formatTime(seconds: number): string {\n if (!isFinite(seconds) || isNaN(seconds)) return \"0:00\";\n const m = Math.floor(seconds / 60);\n const s = Math.floor(seconds % 60);\n return `${m}:${s.toString().padStart(2, \"0\")}`;\n}\n\nexport function AudioPlayerBase(props: AudioPlayerProps) {\n const {\n className,\n appearance = \"default\",\n size = \"md\",\n shape = \"rounded\",\n src,\n children,\n autoPlay = false,\n loop = false,\n onEnded,\n onPlay,\n onPause,\n onTimeUpdate,\n ref,\n ...rest\n } = props;\n\n const audioRef = useRef<HTMLAudioElement>(null);\n const [isPlaying, setIsPlaying] = useState(false);\n const [currentTime, setCurrentTime] = useState(0);\n const [duration, setDuration] = useState(0);\n const [volume, setVolumeState] = useState(1);\n const [muted, setMuted] = useState(false);\n\n const progress = duration > 0 ? (currentTime / duration) * 100 : 0;\n\n const callbacksRef = useRef({ onEnded, onPlay, onPause, onTimeUpdate });\n useEffect(() => {\n callbacksRef.current = { onEnded, onPlay, onPause, onTimeUpdate };\n });\n\n useEffect(() => {\n setIsPlaying(false);\n setCurrentTime(0);\n setDuration(0);\n }, [src]);\n\n useEffect(() => {\n const audio = audioRef.current;\n if (!audio) return;\n\n const handleTimeUpdate = () => {\n setCurrentTime(audio.currentTime);\n callbacksRef.current.onTimeUpdate?.(audio.currentTime, audio.duration);\n };\n const handleDurationChange = () => {\n if (isFinite(audio.duration)) setDuration(audio.duration);\n };\n const handlePlay = () => {\n setIsPlaying(true);\n callbacksRef.current.onPlay?.();\n };\n const handlePause = () => {\n setIsPlaying(false);\n callbacksRef.current.onPause?.();\n };\n const handleEnded = () => {\n setIsPlaying(false);\n callbacksRef.current.onEnded?.();\n };\n const handleVolumeChange = () => {\n setVolumeState(audio.volume);\n setMuted(audio.muted);\n };\n\n audio.addEventListener(\"timeupdate\", handleTimeUpdate);\n audio.addEventListener(\"durationchange\", handleDurationChange);\n audio.addEventListener(\"loadedmetadata\", handleDurationChange);\n audio.addEventListener(\"play\", handlePlay);\n audio.addEventListener(\"pause\", handlePause);\n audio.addEventListener(\"ended\", handleEnded);\n audio.addEventListener(\"volumechange\", handleVolumeChange);\n\n return () => {\n audio.removeEventListener(\"timeupdate\", handleTimeUpdate);\n audio.removeEventListener(\"durationchange\", handleDurationChange);\n audio.removeEventListener(\"loadedmetadata\", handleDurationChange);\n audio.removeEventListener(\"play\", handlePlay);\n audio.removeEventListener(\"pause\", handlePause);\n audio.removeEventListener(\"ended\", handleEnded);\n audio.removeEventListener(\"volumechange\", handleVolumeChange);\n };\n }, []);\n\n const play = useCallback(() => {\n audioRef.current?.play().catch(() => {});\n }, []);\n\n const pause = useCallback(() => {\n audioRef.current?.pause();\n }, []);\n\n const toggle = useCallback(() => {\n const audio = audioRef.current;\n if (!audio) return;\n if (audio.paused) {\n audio.play().catch(() => {});\n } else {\n audio.pause();\n }\n }, []);\n\n const reset = useCallback(() => {\n const audio = audioRef.current;\n if (!audio) return;\n audio.pause();\n audio.currentTime = 0;\n setIsPlaying(false);\n setCurrentTime(0);\n }, []);\n\n const seek = useCallback((seconds: number) => {\n const audio = audioRef.current;\n if (!audio || !isFinite(audio.duration) || audio.duration <= 0) return;\n const nextTime = Math.max(0, Math.min(seconds, audio.duration));\n audio.currentTime = nextTime;\n setDuration(audio.duration);\n setCurrentTime(nextTime);\n }, []);\n\n const seekByPercent = useCallback((percent: number) => {\n const audio = audioRef.current;\n if (\n !audio ||\n !isFinite(percent) ||\n !isFinite(audio.duration) ||\n audio.duration <= 0\n ) {\n return;\n }\n const clamped = Math.max(0, Math.min(percent, 100));\n const nextTime = (clamped / 100) * audio.duration;\n audio.currentTime = nextTime;\n setDuration(audio.duration);\n setCurrentTime(nextTime);\n }, []);\n\n const setVolume = useCallback((vol: number) => {\n const audio = audioRef.current;\n if (!audio || !isFinite(vol)) return;\n const nextVolume = Math.max(0, Math.min(vol, 1));\n audio.volume = nextVolume;\n setVolumeState(nextVolume);\n }, []);\n\n const toggleMute = useCallback(() => {\n const audio = audioRef.current;\n if (!audio) return;\n const nextMuted = !audio.muted;\n audio.muted = nextMuted;\n setMuted(nextMuted);\n }, []);\n\n const ctx = useMemo<AudioPlayerCtx>(\n () => ({\n isPlaying,\n currentTime,\n duration,\n progress,\n volume,\n muted,\n play,\n pause,\n toggle,\n reset,\n seek,\n seekByPercent,\n setVolume,\n toggleMute,\n size: size ?? \"md\",\n shape: shape ?? \"rounded\",\n appearance: appearance ?? \"default\",\n }),\n [\n isPlaying,\n currentTime,\n duration,\n progress,\n volume,\n muted,\n play,\n pause,\n toggle,\n reset,\n seek,\n seekByPercent,\n setVolume,\n toggleMute,\n size,\n shape,\n appearance,\n ],\n );\n\n return (\n <AudioPlayerContext.Provider value={ctx}>\n <div\n ref={ref}\n data-slot=\"audio-player\"\n className={cn(\n audioPlayerVariants({ appearance, size, shape }),\n className,\n )}\n {...rest}\n >\n <audio\n ref={audioRef}\n src={src}\n autoPlay={autoPlay}\n loop={loop}\n preload=\"metadata\"\n className=\"hidden\"\n aria-hidden=\"true\"\n />\n {children}\n </div>\n </AudioPlayerContext.Provider>\n );\n}\n\nAudioPlayerBase.displayName = \"AudioPlayer\";\n\nexport function AudioPlayerProgress({\n className,\n ref,\n ...rest\n}: AudioPlayerProgressProps) {\n const { progress, seekByPercent, size, shape } = useAudioPlayer();\n const trackRef = useRef<HTMLDivElement>(null);\n const draggingRef = useRef(false);\n\n const getPercentFromEvent = useCallback((clientX: number): number => {\n const el = trackRef.current;\n if (!el) return 0;\n const { left, width } = el.getBoundingClientRect();\n return Math.max(0, Math.min(((clientX - left) / width) * 100, 100));\n }, []);\n\n const handleClick = useCallback(\n (e: MouseEvent<HTMLDivElement>) => {\n if (draggingRef.current) return;\n seekByPercent(getPercentFromEvent(e.clientX));\n },\n [getPercentFromEvent, seekByPercent],\n );\n\n const handlePointerDown = useCallback(\n (e: PointerEvent<HTMLDivElement>) => {\n draggingRef.current = true;\n e.currentTarget.setPointerCapture?.(e.pointerId);\n seekByPercent(getPercentFromEvent(e.clientX));\n },\n [getPercentFromEvent, seekByPercent],\n );\n\n const handlePointerMove = useCallback(\n (e: PointerEvent<HTMLDivElement>) => {\n if (!draggingRef.current) return;\n seekByPercent(getPercentFromEvent(e.clientX));\n },\n [getPercentFromEvent, seekByPercent],\n );\n\n const handlePointerUp = useCallback(() => {\n draggingRef.current = false;\n }, []);\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key === \"ArrowRight\" || e.key === \"ArrowUp\") {\n e.preventDefault();\n seekByPercent(Math.min(progress + 1, 100));\n } else if (e.key === \"ArrowLeft\" || e.key === \"ArrowDown\") {\n e.preventDefault();\n seekByPercent(Math.max(progress - 1, 0));\n } else if (e.key === \"Home\") {\n e.preventDefault();\n seekByPercent(0);\n } else if (e.key === \"End\") {\n e.preventDefault();\n seekByPercent(100);\n }\n },\n [progress, seekByPercent],\n );\n\n return (\n <div\n ref={(node) => {\n (trackRef as React.MutableRefObject<HTMLDivElement | null>).current =\n node;\n if (typeof ref === \"function\") ref(node);\n else if (ref)\n (ref as React.MutableRefObject<HTMLDivElement | null>).current = node;\n }}\n data-slot=\"audio-player-progress\"\n role=\"slider\"\n aria-label=\"Audio progress\"\n aria-valuenow={Math.round(progress)}\n aria-valuemin={0}\n aria-valuemax={100}\n tabIndex={0}\n className={cn(\n audioPlayerTrackVariants({ size, shape }),\n \"group\",\n className,\n )}\n onClick={handleClick}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerUp}\n onKeyDown={handleKeyDown}\n {...rest}\n >\n <div\n data-slot=\"audio-player-bar\"\n className={cn(\n audioPlayerBarVariants(),\n \"rounded-[inherit] group-hover:opacity-90 transition-opacity\",\n )}\n style={{ transform: `scaleX(${progress / 100})` }}\n />\n </div>\n );\n}\n\nAudioPlayerProgress.displayName = \"AudioPlayerProgress\";\n\nexport function AudioPlayerTime({\n className,\n format = formatTime,\n}: AudioPlayerTimeProps) {\n const { currentTime, duration } = useAudioPlayer();\n return (\n <div\n data-slot=\"audio-player-time\"\n className={cn(\n audioPlayerTimeVariants(),\n \"flex items-center gap-1\",\n className,\n )}\n >\n <span aria-label=\"Current time\">{format(currentTime)}</span>\n <span aria-hidden=\"true\">/</span>\n <span aria-label=\"Total duration\">{format(duration)}</span>\n </div>\n );\n}\n\nAudioPlayerTime.displayName = \"AudioPlayerTime\";\n\nexport function AudioPlayerVolume({\n className,\n ref,\n ...rest\n}: AudioPlayerVolumeProps) {\n const { volume, muted, setVolume, toggleMute } = useAudioPlayer();\n const trackRef = useRef<HTMLDivElement>(null);\n const draggingRef = useRef(false);\n\n const getVolumeFromEvent = useCallback((clientX: number): number => {\n const el = trackRef.current;\n if (!el) return 0;\n const { left, width } = el.getBoundingClientRect();\n return Math.max(0, Math.min((clientX - left) / width, 1));\n }, []);\n\n const handlePointerDown = useCallback(\n (e: PointerEvent<HTMLDivElement>) => {\n draggingRef.current = true;\n e.currentTarget.setPointerCapture?.(e.pointerId);\n setVolume(getVolumeFromEvent(e.clientX));\n },\n [getVolumeFromEvent, setVolume],\n );\n\n const handlePointerMove = useCallback(\n (e: PointerEvent<HTMLDivElement>) => {\n if (!draggingRef.current) return;\n setVolume(getVolumeFromEvent(e.clientX));\n },\n [getVolumeFromEvent, setVolume],\n );\n\n const handlePointerUp = useCallback(() => {\n draggingRef.current = false;\n }, []);\n\n const handleClick = useCallback(\n (e: MouseEvent<HTMLDivElement>) => {\n if (draggingRef.current) return;\n setVolume(getVolumeFromEvent(e.clientX));\n },\n [getVolumeFromEvent, setVolume],\n );\n\n const displayVolume = muted ? 0 : volume;\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key === \"ArrowRight\" || e.key === \"ArrowUp\") {\n e.preventDefault();\n setVolume(Math.min(volume + 0.05, 1));\n } else if (e.key === \"ArrowLeft\" || e.key === \"ArrowDown\") {\n e.preventDefault();\n setVolume(Math.max(volume - 0.05, 0));\n } else if (e.key === \"Home\") {\n e.preventDefault();\n setVolume(0);\n } else if (e.key === \"End\") {\n e.preventDefault();\n setVolume(1);\n }\n },\n [volume, setVolume],\n );\n\n return (\n <div\n data-slot=\"audio-player-volume\"\n className={cn(\"flex items-center gap-2\", className)}\n {...rest}\n >\n <button\n type=\"button\"\n aria-label={muted ? \"Unmute\" : \"Mute\"}\n onClick={toggleMute}\n className=\"shrink-0 rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--audio-fill,#0f172a)]\"\n >\n {displayVolume === 0 ? (\n <svg\n className=\"h-4 w-4\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" />\n <line x1=\"23\" y1=\"9\" x2=\"17\" y2=\"15\" />\n <line x1=\"17\" y1=\"9\" x2=\"23\" y2=\"15\" />\n </svg>\n ) : displayVolume < 0.5 ? (\n <svg\n className=\"h-4 w-4\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" />\n <path d=\"M15.54 8.46a5 5 0 0 1 0 7.07\" />\n </svg>\n ) : (\n <svg\n className=\"h-4 w-4\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" />\n <path d=\"M19.07 4.93a10 10 0 0 1 0 14.14\" />\n <path d=\"M15.54 8.46a5 5 0 0 1 0 7.07\" />\n </svg>\n )}\n </button>\n <div\n ref={(node) => {\n (trackRef as React.MutableRefObject<HTMLDivElement | null>).current =\n node;\n if (typeof ref === \"function\") ref(node);\n else if (ref)\n (ref as React.MutableRefObject<HTMLDivElement | null>).current =\n node;\n }}\n role=\"slider\"\n aria-label=\"Volume\"\n aria-valuenow={Math.round(displayVolume * 100)}\n aria-valuemin={0}\n aria-valuemax={100}\n tabIndex={0}\n className=\"relative h-1.5 w-20 cursor-pointer overflow-hidden rounded-full bg-[var(--zui-audio-player-track-bg,var(--zui-surface-muted,#0000001a))] dark:bg-[var(--zui-audio-player-track-bg-dark,var(--zui-surface-muted-dark,#ffffff1a))] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--audio-fill,#0f172a)]\"\n onClick={handleClick}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerUp}\n onKeyDown={handleKeyDown}\n >\n <div\n data-slot=\"audio-player-volume-bar\"\n className=\"h-full origin-left [background:var(--audio-fill)] rounded-[inherit]\"\n style={{ transform: `scaleX(${displayVolume})` }}\n />\n </div>\n </div>\n );\n}\n\nAudioPlayerVolume.displayName = \"AudioPlayerVolume\";\n","import { AudioPlayerBase } from \"./audio-player-base\";\nimport type { AudioPlayerProps } from \"./types\";\n\nexport const AudioPlayer = (props: AudioPlayerProps) => {\n return <AudioPlayerBase {...props} />;\n};\n\nAudioPlayer.displayName = \"AudioPlayer\";\n"]}