@mieweb/ui 0.1.1 → 0.2.1
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/ag-grid.cjs +753 -0
- package/dist/ag-grid.cjs.map +1 -0
- package/dist/ag-grid.d.cts +193 -0
- package/dist/ag-grid.d.ts +193 -0
- package/dist/ag-grid.js +698 -0
- package/dist/ag-grid.js.map +1 -0
- package/dist/brands/index.cjs +17 -12
- package/dist/brands/index.d.cts +2 -0
- package/dist/brands/index.d.ts +2 -0
- package/dist/brands/index.js +4 -3
- package/dist/brands/ozwell.cjs +12 -0
- package/dist/brands/ozwell.cjs.map +1 -0
- package/dist/brands/ozwell.css +145 -0
- package/dist/brands/ozwell.d.cts +17 -0
- package/dist/brands/ozwell.d.ts +17 -0
- package/dist/brands/ozwell.js +3 -0
- package/dist/brands/ozwell.js.map +1 -0
- package/dist/chunk-4DJNHPHB.js +82 -0
- package/dist/chunk-4DJNHPHB.js.map +1 -0
- package/dist/chunk-4T2ZNPTC.js +220 -0
- package/dist/chunk-4T2ZNPTC.js.map +1 -0
- package/dist/{chunk-NL3CZNBH.cjs → chunk-5UUL5EEO.cjs} +16 -5
- package/dist/chunk-5UUL5EEO.cjs.map +1 -0
- package/dist/{chunk-O7WRE2WX.js → chunk-5YRTFJ7K.js} +54 -2
- package/dist/chunk-5YRTFJ7K.js.map +1 -0
- package/dist/{chunk-6DP6RKUA.cjs → chunk-B5364UWR.cjs} +3 -2
- package/dist/chunk-B5364UWR.cjs.map +1 -0
- package/dist/chunk-BV75DAKO.cjs +245 -0
- package/dist/chunk-BV75DAKO.cjs.map +1 -0
- package/dist/chunk-D3BUYVLN.cjs +120 -0
- package/dist/chunk-D3BUYVLN.cjs.map +1 -0
- package/dist/{chunk-SJ3BF4BO.cjs → chunk-ERIGUDFS.cjs} +54 -2
- package/dist/chunk-ERIGUDFS.cjs.map +1 -0
- package/dist/{chunk-UBRDKNLQ.js → chunk-GHRQ3ZJH.js} +178 -51
- package/dist/chunk-GHRQ3ZJH.js.map +1 -0
- package/dist/{chunk-AKTUXJPI.cjs → chunk-INFSKLXE.cjs} +178 -51
- package/dist/chunk-INFSKLXE.cjs.map +1 -0
- package/dist/chunk-K5T2PT4M.js +3 -0
- package/dist/chunk-K5T2PT4M.js.map +1 -0
- package/dist/chunk-KEIA2G6O.cjs +84 -0
- package/dist/chunk-KEIA2G6O.cjs.map +1 -0
- package/dist/{chunk-MFB4FS7D.js → chunk-QSMMFATL.js} +16 -5
- package/dist/chunk-QSMMFATL.js.map +1 -0
- package/dist/{chunk-FIUNOH6W.js → chunk-RYQ5NEKH.js} +3 -2
- package/dist/chunk-RYQ5NEKH.js.map +1 -0
- package/dist/components/AudioPlayer/index.cjs +6 -6
- package/dist/components/AudioPlayer/index.d.cts +24 -10
- package/dist/components/AudioPlayer/index.d.ts +24 -10
- package/dist/components/AudioPlayer/index.js +1 -1
- package/dist/components/Select/index.cjs +3 -3
- package/dist/components/Select/index.js +1 -1
- package/dist/components/Slider/index.cjs +25 -0
- package/dist/components/Slider/index.cjs.map +1 -0
- package/dist/components/Slider/index.d.cts +82 -0
- package/dist/components/Slider/index.d.ts +82 -0
- package/dist/components/Slider/index.js +4 -0
- package/dist/components/Slider/index.js.map +1 -0
- package/dist/index.cjs +2782 -2350
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +213 -238
- package/dist/index.d.ts +213 -238
- package/dist/index.js +2577 -2133
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/tailwind-preset.cjs +4 -4
- package/dist/tailwind-preset.js +1 -1
- package/package.json +12 -1
- package/dist/chunk-6DP6RKUA.cjs.map +0 -1
- package/dist/chunk-AKTUXJPI.cjs.map +0 -1
- package/dist/chunk-FIUNOH6W.js.map +0 -1
- package/dist/chunk-MFB4FS7D.js.map +0 -1
- package/dist/chunk-NL3CZNBH.cjs.map +0 -1
- package/dist/chunk-O7WRE2WX.js.map +0 -1
- package/dist/chunk-SJ3BF4BO.cjs.map +0 -1
- package/dist/chunk-UBRDKNLQ.js.map +0 -1
|
@@ -228,6 +228,7 @@ function Waveform({
|
|
|
228
228
|
progressColor,
|
|
229
229
|
height = 64,
|
|
230
230
|
showHoverCursor = false,
|
|
231
|
+
waveformRef,
|
|
231
232
|
onHoverTimeChange,
|
|
232
233
|
cursorColor = "var(--color-red-500, rgb(239, 68, 68))"
|
|
233
234
|
}) {
|
|
@@ -236,6 +237,43 @@ function Waveform({
|
|
|
236
237
|
const [isLoaded, setIsLoaded] = React__namespace.useState(false);
|
|
237
238
|
const [isHovering, setIsHovering] = React__namespace.useState(false);
|
|
238
239
|
const [hoverPosition, setHoverPosition] = React__namespace.useState(0);
|
|
240
|
+
React__namespace.useEffect(() => {
|
|
241
|
+
if (waveformRef) {
|
|
242
|
+
waveformRef.current = {
|
|
243
|
+
seekTo: (time) => {
|
|
244
|
+
if (wavesurferRef.current && isLoaded) {
|
|
245
|
+
const duration = wavesurferRef.current.getDuration();
|
|
246
|
+
if (duration > 0) {
|
|
247
|
+
const clampedTime = Math.min(Math.max(time, 0), duration);
|
|
248
|
+
const progress = clampedTime / duration;
|
|
249
|
+
wavesurferRef.current.seekTo(progress);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
play: () => {
|
|
254
|
+
if (wavesurferRef.current && isLoaded) {
|
|
255
|
+
wavesurferRef.current.play();
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
pause: () => {
|
|
259
|
+
if (wavesurferRef.current && isLoaded) {
|
|
260
|
+
wavesurferRef.current.pause();
|
|
261
|
+
}
|
|
262
|
+
},
|
|
263
|
+
getCurrentTime: () => {
|
|
264
|
+
return wavesurferRef.current?.getCurrentTime?.() ?? 0;
|
|
265
|
+
},
|
|
266
|
+
getDuration: () => {
|
|
267
|
+
return wavesurferRef.current?.getDuration?.() ?? 0;
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
return () => {
|
|
272
|
+
if (waveformRef) {
|
|
273
|
+
waveformRef.current = null;
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
}, [waveformRef, isLoaded]);
|
|
239
277
|
React__namespace.useEffect(() => {
|
|
240
278
|
if (!containerRef.current) return;
|
|
241
279
|
const initWaveSurfer = async () => {
|
|
@@ -279,6 +317,7 @@ function Waveform({
|
|
|
279
317
|
console.error("Failed to load WaveSurfer:", error);
|
|
280
318
|
}
|
|
281
319
|
};
|
|
320
|
+
setIsLoaded(false);
|
|
282
321
|
initWaveSurfer();
|
|
283
322
|
return () => {
|
|
284
323
|
if (wavesurferRef.current) {
|
|
@@ -373,7 +412,7 @@ function Waveform({
|
|
|
373
412
|
}
|
|
374
413
|
);
|
|
375
414
|
}
|
|
376
|
-
|
|
415
|
+
var AudioPlayer = React__namespace.forwardRef(function AudioPlayer2({
|
|
377
416
|
src,
|
|
378
417
|
title,
|
|
379
418
|
variant = "compact",
|
|
@@ -398,14 +437,16 @@ function AudioPlayer({
|
|
|
398
437
|
preload = false,
|
|
399
438
|
/** Fallback duration in seconds to display before audio is loaded */
|
|
400
439
|
fallbackDuration
|
|
401
|
-
}) {
|
|
440
|
+
}, ref) {
|
|
402
441
|
const [state, setState] = React__namespace.useState("idle");
|
|
403
442
|
const [currentTime, setCurrentTime] = React__namespace.useState(0);
|
|
404
443
|
const [duration, setDuration] = React__namespace.useState(0);
|
|
405
444
|
const [playbackRate, setPlaybackRate] = React__namespace.useState(1);
|
|
406
445
|
const [audioInitialized, setAudioInitialized] = React__namespace.useState(false);
|
|
407
446
|
const [hoverTime, setHoverTime] = React__namespace.useState(null);
|
|
447
|
+
const containerRef = React__namespace.useRef(null);
|
|
408
448
|
const audioRef = React__namespace.useRef(null);
|
|
449
|
+
const waveformMethodsRef = React__namespace.useRef(null);
|
|
409
450
|
const isPlaying = state === "playing";
|
|
410
451
|
const isLoading = state === "loading";
|
|
411
452
|
const updateState = React__namespace.useCallback(
|
|
@@ -450,6 +491,70 @@ function AudioPlayer({
|
|
|
450
491
|
onEnded,
|
|
451
492
|
onError
|
|
452
493
|
]);
|
|
494
|
+
React__namespace.useImperativeHandle(
|
|
495
|
+
ref,
|
|
496
|
+
() => ({
|
|
497
|
+
get container() {
|
|
498
|
+
return containerRef.current;
|
|
499
|
+
},
|
|
500
|
+
seekTo: (time) => {
|
|
501
|
+
if (variant === "waveform") {
|
|
502
|
+
waveformMethodsRef.current?.seekTo(time);
|
|
503
|
+
} else {
|
|
504
|
+
if (!audioRef.current) {
|
|
505
|
+
initAudio();
|
|
506
|
+
}
|
|
507
|
+
if (audioRef.current) {
|
|
508
|
+
audioRef.current.currentTime = time;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
},
|
|
512
|
+
play: () => {
|
|
513
|
+
if (variant === "waveform") {
|
|
514
|
+
if (waveformMethodsRef.current) {
|
|
515
|
+
waveformMethodsRef.current.play();
|
|
516
|
+
updateState("playing");
|
|
517
|
+
}
|
|
518
|
+
} else {
|
|
519
|
+
if (!audioRef.current) {
|
|
520
|
+
initAudio();
|
|
521
|
+
}
|
|
522
|
+
if (audioRef.current) {
|
|
523
|
+
audioRef.current.play().catch((error) => {
|
|
524
|
+
updateState("error");
|
|
525
|
+
onError?.(error);
|
|
526
|
+
});
|
|
527
|
+
updateState("playing");
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
},
|
|
531
|
+
pause: () => {
|
|
532
|
+
if (variant === "waveform") {
|
|
533
|
+
if (waveformMethodsRef.current) {
|
|
534
|
+
waveformMethodsRef.current.pause();
|
|
535
|
+
updateState("paused");
|
|
536
|
+
}
|
|
537
|
+
} else if (audioRef.current) {
|
|
538
|
+
audioRef.current.pause();
|
|
539
|
+
updateState("paused");
|
|
540
|
+
}
|
|
541
|
+
},
|
|
542
|
+
getCurrentTime: () => {
|
|
543
|
+
if (variant === "waveform") {
|
|
544
|
+
return waveformMethodsRef.current?.getCurrentTime() ?? 0;
|
|
545
|
+
}
|
|
546
|
+
return audioRef.current?.currentTime ?? 0;
|
|
547
|
+
},
|
|
548
|
+
getDuration: () => {
|
|
549
|
+
if (variant === "waveform") {
|
|
550
|
+
return waveformMethodsRef.current?.getDuration() ?? 0;
|
|
551
|
+
}
|
|
552
|
+
const rawDuration = audioRef.current?.duration;
|
|
553
|
+
return Number.isFinite(rawDuration) ? rawDuration : 0;
|
|
554
|
+
}
|
|
555
|
+
}),
|
|
556
|
+
[variant, initAudio, updateState, onError]
|
|
557
|
+
);
|
|
453
558
|
React__namespace.useEffect(() => {
|
|
454
559
|
if (preload && !audioInitialized && variant !== "waveform") {
|
|
455
560
|
initAudio();
|
|
@@ -601,57 +706,79 @@ function AudioPlayer({
|
|
|
601
706
|
};
|
|
602
707
|
if (variant === "inline") {
|
|
603
708
|
const displayDuration = duration > 0 ? duration : fallbackDuration ?? 0;
|
|
604
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
709
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
710
|
+
"div",
|
|
711
|
+
{
|
|
712
|
+
ref: containerRef,
|
|
713
|
+
className: chunkOR5DRJCW_cjs.cn(audioPlayerVariants({ variant, size }), className),
|
|
714
|
+
children: [
|
|
715
|
+
renderPlayButton(),
|
|
716
|
+
title && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-neutral-700 dark:text-neutral-300", children: title }),
|
|
717
|
+
showDuration && displayDuration > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-xs text-neutral-500 tabular-nums dark:text-neutral-400", children: isPlaying ? formatTime(currentTime) : formatTime(displayDuration) })
|
|
718
|
+
]
|
|
719
|
+
}
|
|
720
|
+
);
|
|
609
721
|
}
|
|
610
722
|
if (variant === "compact") {
|
|
611
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
612
|
-
|
|
613
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
614
|
-
ProgressBar,
|
|
615
|
-
{
|
|
616
|
-
currentTime,
|
|
617
|
-
duration,
|
|
618
|
-
onSeek: handleSeek,
|
|
619
|
-
disabled
|
|
620
|
-
}
|
|
621
|
-
),
|
|
622
|
-
renderTime(),
|
|
623
|
-
renderPlaybackRateControl()
|
|
624
|
-
] });
|
|
625
|
-
}
|
|
626
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkOR5DRJCW_cjs.cn(audioPlayerVariants({ variant, size }), className), children: [
|
|
627
|
-
title && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-neutral-700 dark:text-neutral-300", children: title }),
|
|
628
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
629
|
-
Waveform,
|
|
723
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
724
|
+
"div",
|
|
630
725
|
{
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
726
|
+
ref: containerRef,
|
|
727
|
+
className: chunkOR5DRJCW_cjs.cn(audioPlayerVariants({ variant, size }), className),
|
|
728
|
+
children: [
|
|
729
|
+
renderPlayButton(),
|
|
730
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
731
|
+
ProgressBar,
|
|
732
|
+
{
|
|
733
|
+
currentTime,
|
|
734
|
+
duration,
|
|
735
|
+
onSeek: handleSeek,
|
|
736
|
+
disabled
|
|
737
|
+
}
|
|
738
|
+
),
|
|
739
|
+
renderTime(),
|
|
740
|
+
renderPlaybackRateControl()
|
|
741
|
+
]
|
|
644
742
|
}
|
|
645
|
-
)
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
743
|
+
);
|
|
744
|
+
}
|
|
745
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
746
|
+
"div",
|
|
747
|
+
{
|
|
748
|
+
ref: containerRef,
|
|
749
|
+
className: chunkOR5DRJCW_cjs.cn(audioPlayerVariants({ variant, size }), className),
|
|
750
|
+
children: [
|
|
751
|
+
title && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-neutral-700 dark:text-neutral-300", children: title }),
|
|
752
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
753
|
+
Waveform,
|
|
754
|
+
{
|
|
755
|
+
src,
|
|
756
|
+
isPlaying,
|
|
757
|
+
playbackRate,
|
|
758
|
+
onReady: handleWaveformReady,
|
|
759
|
+
onTimeUpdate: handleWaveformTimeUpdate,
|
|
760
|
+
onFinish: handleWaveformFinish,
|
|
761
|
+
onSeek: handleWaveformSeek,
|
|
762
|
+
waveColor,
|
|
763
|
+
progressColor,
|
|
764
|
+
height: waveformHeight,
|
|
765
|
+
showHoverCursor: showWaveformHoverCursor,
|
|
766
|
+
onHoverTimeChange: handleHoverTimeChange,
|
|
767
|
+
cursorColor: waveformCursorColor,
|
|
768
|
+
waveformRef: waveformMethodsRef
|
|
769
|
+
}
|
|
770
|
+
),
|
|
771
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
772
|
+
renderPlayButton(),
|
|
773
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 items-center justify-between", children: [
|
|
774
|
+
renderTime(true),
|
|
775
|
+
renderPlaybackRateControl()
|
|
776
|
+
] })
|
|
777
|
+
] })
|
|
778
|
+
]
|
|
779
|
+
}
|
|
780
|
+
);
|
|
781
|
+
});
|
|
655
782
|
AudioPlayer.displayName = "AudioPlayer";
|
|
656
783
|
|
|
657
784
|
exports.AudioPlayer = AudioPlayer;
|
|
@@ -659,5 +786,5 @@ exports.ProgressBar = ProgressBar;
|
|
|
659
786
|
exports.audioPlayerVariants = audioPlayerVariants;
|
|
660
787
|
exports.formatTime = formatTime;
|
|
661
788
|
exports.playButtonVariants = playButtonVariants;
|
|
662
|
-
//# sourceMappingURL=chunk-
|
|
663
|
-
//# sourceMappingURL=chunk-
|
|
789
|
+
//# sourceMappingURL=chunk-INFSKLXE.cjs.map
|
|
790
|
+
//# sourceMappingURL=chunk-INFSKLXE.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/AudioPlayer/AudioPlayer.tsx"],"names":["cva","jsx","jsxs","cn","React","AudioPlayer"],"mappings":"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","file":"chunk-INFSKLXE.cjs","sourcesContent":["import * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\n\n// ============================================================================\n// Types & Interfaces\n// ============================================================================\n\nexport type AudioPlayerState =\n | 'idle'\n | 'loading'\n | 'playing'\n | 'paused'\n | 'error';\n\n/** Ref handle for controlling AudioPlayer programmatically */\nexport interface AudioPlayerRef {\n /** The underlying container element */\n container: HTMLDivElement | null;\n /** Seek to a specific time in seconds */\n seekTo: (time: number) => void;\n /** Start playback */\n play: () => void;\n /** Pause playback */\n pause: () => void;\n /** Get current playback time in seconds */\n getCurrentTime: () => number;\n /** Get total duration in seconds */\n getDuration: () => number;\n}\n\nexport interface AudioPlayerProps extends VariantProps<\n typeof audioPlayerVariants\n> {\n /** Audio source URL */\n src: string;\n /** Title/label for the audio (used for accessibility and display) */\n title?: string;\n /** Callback when playback state changes */\n onStateChange?: (state: AudioPlayerState) => void;\n /** Callback when playback ends */\n onEnded?: () => void;\n /** Callback when an error occurs */\n onError?: (error: Error) => void;\n /** Callback when time updates during playback */\n onTimeUpdate?: (currentTime: number, duration: number) => void;\n /** Whether to show the time display */\n showTime?: boolean;\n /** Whether to show the duration (for inline variant) */\n showDuration?: boolean;\n /** Waveform color (for waveform variant) */\n waveColor?: string;\n /** Progress/played waveform color (for waveform variant) */\n progressColor?: string;\n /** Height of the waveform (for waveform variant) */\n waveformHeight?: number;\n /** Whether to show hover cursor on waveform for click-to-seek preview (for waveform variant) */\n showWaveformHoverCursor?: boolean;\n /** Color of the hover cursor line (for waveform variant) */\n waveformCursorColor?: string;\n /** Whether the player is disabled */\n disabled?: boolean;\n /** Additional class name */\n className?: string;\n /** Accessible label */\n 'aria-label'?: string;\n /** Playback speed options */\n playbackRates?: number[];\n /** Whether to show playback speed control */\n showPlaybackRate?: boolean;\n}\n\n// ============================================================================\n// Variants\n// ============================================================================\n\nconst audioPlayerVariants = cva('', {\n variants: {\n variant: {\n inline: 'inline-flex items-center gap-2',\n compact: [\n 'flex items-center gap-3 p-3',\n 'rounded-lg border border-border',\n 'bg-card text-card-foreground',\n ],\n waveform: [\n 'flex flex-col gap-3 p-4',\n 'rounded-xl border border-border',\n 'bg-card text-card-foreground',\n ],\n },\n size: {\n sm: '',\n md: '',\n lg: '',\n },\n },\n compoundVariants: [\n { variant: 'compact', size: 'sm', class: 'p-2 gap-2' },\n { variant: 'compact', size: 'lg', class: 'p-4 gap-4' },\n { variant: 'waveform', size: 'sm', class: 'p-3 gap-2' },\n { variant: 'waveform', size: 'lg', class: 'p-5 gap-4' },\n ],\n defaultVariants: {\n variant: 'compact',\n size: 'md',\n },\n});\n\nconst playButtonVariants = cva(\n [\n 'inline-flex items-center justify-center',\n 'rounded-full transition-all duration-200',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n 'disabled:pointer-events-none disabled:opacity-50',\n 'active:scale-95',\n ],\n {\n variants: {\n variant: {\n inline: [\n 'text-neutral-500 hover:text-neutral-700 hover:bg-neutral-100',\n 'dark:text-neutral-400 dark:hover:text-neutral-200 dark:hover:bg-neutral-800',\n ],\n compact: [\n 'bg-primary-600 text-white',\n 'hover:bg-primary-700',\n 'active:bg-primary-800',\n ],\n waveform: [\n 'bg-primary-600 text-white',\n 'hover:bg-primary-700',\n 'active:bg-primary-800',\n ],\n },\n size: {\n sm: 'h-7 w-7',\n md: 'h-9 w-9',\n lg: 'h-11 w-11',\n },\n },\n defaultVariants: {\n variant: 'compact',\n size: 'md',\n },\n }\n);\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\nexport function formatTime(seconds: number): string {\n if (!isFinite(seconds) || isNaN(seconds)) return '0:00';\n const mins = Math.floor(seconds / 60);\n const secs = Math.floor(seconds % 60);\n return `${mins}:${secs.toString().padStart(2, '0')}`;\n}\n\n// ============================================================================\n// Icons\n// ============================================================================\n\nfunction PlayIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"currentColor\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n >\n <path d=\"M8 5v14l11-7z\" />\n </svg>\n );\n}\n\nfunction PauseIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"currentColor\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n >\n <path d=\"M6 19h4V5H6v14zm8-14v14h4V5h-4z\" />\n </svg>\n );\n}\n\nfunction SpinnerIcon({ className }: { className?: string }) {\n return (\n <svg\n className={cn('animate-spin', className)}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n );\n}\n\n// ============================================================================\n// Progress Bar Component (for compact variant)\n// ============================================================================\n\ninterface ProgressBarProps {\n currentTime: number;\n duration: number;\n onSeek: (time: number) => void;\n disabled?: boolean;\n}\n\nfunction ProgressBar({\n currentTime,\n duration,\n onSeek,\n disabled,\n}: ProgressBarProps) {\n const progressRef = React.useRef<HTMLDivElement>(null);\n const progress = duration > 0 ? (currentTime / duration) * 100 : 0;\n\n const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {\n if (disabled || !progressRef.current || duration <= 0) return;\n const rect = progressRef.current.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const percentage = x / rect.width;\n onSeek(percentage * duration);\n };\n\n return (\n <div\n ref={progressRef}\n role=\"slider\"\n aria-label=\"Audio progress\"\n aria-valuemin={0}\n aria-valuemax={duration}\n aria-valuenow={currentTime}\n aria-valuetext={`${formatTime(currentTime)} of ${formatTime(duration)}`}\n tabIndex={disabled ? -1 : 0}\n className={cn(\n 'relative h-1.5 flex-1 cursor-pointer rounded-full bg-neutral-200 dark:bg-neutral-700',\n disabled && 'cursor-not-allowed opacity-50'\n )}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (disabled) return;\n const step = duration * 0.05; // 5% steps\n if (e.key === 'ArrowRight') {\n onSeek(Math.min(currentTime + step, duration));\n } else if (e.key === 'ArrowLeft') {\n onSeek(Math.max(currentTime - step, 0));\n }\n }}\n >\n <div\n className=\"bg-primary-600 absolute inset-y-0 left-0 rounded-full transition-all\"\n style={{ width: `${progress}%` }}\n />\n <div\n className=\"bg-primary-600 absolute top-1/2 h-3 w-3 -translate-y-1/2 rounded-full shadow-sm transition-all\"\n style={{ left: `calc(${progress}% - 6px)` }}\n />\n </div>\n );\n}\n\n// ============================================================================\n// Waveform Component (lazy-loaded WaveSurfer)\n// ============================================================================\n\n/** Methods exposed by Waveform via ref */\nexport interface WaveformMethods {\n seekTo: (time: number) => void;\n play: () => void;\n pause: () => void;\n getCurrentTime: () => number;\n getDuration: () => number;\n}\n\ninterface WaveformProps {\n src: string;\n isPlaying: boolean;\n playbackRate?: number;\n onReady: (duration: number) => void;\n onTimeUpdate: (time: number) => void;\n onFinish: () => void;\n onSeek: (time: number) => void;\n waveColor?: string;\n progressColor?: string;\n height?: number;\n showHoverCursor?: boolean;\n onHoverTimeChange?: (time: number | null) => void;\n cursorColor?: string;\n /** Ref to expose waveform control methods */\n waveformRef?: React.MutableRefObject<WaveformMethods | null>;\n}\n\nfunction Waveform({\n src,\n isPlaying,\n playbackRate = 1,\n onReady,\n onTimeUpdate,\n onFinish,\n onSeek,\n waveColor,\n progressColor,\n height = 64,\n showHoverCursor = false,\n waveformRef,\n onHoverTimeChange,\n cursorColor = 'var(--color-red-500, rgb(239, 68, 68))',\n}: WaveformProps) {\n const containerRef = React.useRef<HTMLDivElement>(null);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const wavesurferRef = React.useRef<any>(null);\n const [isLoaded, setIsLoaded] = React.useState(false);\n const [isHovering, setIsHovering] = React.useState(false);\n const [hoverPosition, setHoverPosition] = React.useState(0);\n\n // Expose methods via ref for external control\n React.useEffect(() => {\n if (waveformRef) {\n waveformRef.current = {\n seekTo: (time: number) => {\n if (wavesurferRef.current && isLoaded) {\n const duration = wavesurferRef.current.getDuration();\n if (duration > 0) {\n const clampedTime = Math.min(Math.max(time, 0), duration);\n const progress = clampedTime / duration;\n wavesurferRef.current.seekTo(progress);\n }\n }\n },\n play: () => {\n if (wavesurferRef.current && isLoaded) {\n wavesurferRef.current.play();\n }\n },\n pause: () => {\n if (wavesurferRef.current && isLoaded) {\n wavesurferRef.current.pause();\n }\n },\n getCurrentTime: () => {\n return wavesurferRef.current?.getCurrentTime?.() ?? 0;\n },\n getDuration: () => {\n return wavesurferRef.current?.getDuration?.() ?? 0;\n },\n };\n }\n return () => {\n if (waveformRef) {\n waveformRef.current = null;\n }\n };\n }, [waveformRef, isLoaded]);\n\n // Initialize WaveSurfer\n React.useEffect(() => {\n if (!containerRef.current) return;\n\n const initWaveSurfer = async () => {\n try {\n const WaveSurfer = (await import('wavesurfer.js')).default;\n\n if (wavesurferRef.current) {\n wavesurferRef.current.destroy();\n }\n\n wavesurferRef.current = WaveSurfer.create({\n container: containerRef.current!,\n waveColor: waveColor || '#d1d5db',\n progressColor: progressColor || 'var(--color-primary-600, #2563eb)',\n cursorColor: 'transparent',\n barWidth: 2,\n barGap: 2,\n barRadius: 2,\n height,\n normalize: true,\n interact: !showHoverCursor,\n });\n\n wavesurferRef.current.on('ready', () => {\n setIsLoaded(true);\n onReady(wavesurferRef.current.getDuration());\n });\n\n wavesurferRef.current.on('audioprocess', () => {\n onTimeUpdate(wavesurferRef.current.getCurrentTime());\n });\n\n wavesurferRef.current.on('seeking', () => {\n onTimeUpdate(wavesurferRef.current.getCurrentTime());\n });\n\n if (!showHoverCursor) {\n wavesurferRef.current.on('interaction', () => {\n onSeek(wavesurferRef.current.getCurrentTime());\n });\n }\n\n wavesurferRef.current.on('finish', () => {\n onFinish();\n });\n\n wavesurferRef.current.load(src);\n } catch (error) {\n console.error('Failed to load WaveSurfer:', error);\n }\n };\n\n setIsLoaded(false);\n initWaveSurfer();\n\n return () => {\n if (wavesurferRef.current) {\n wavesurferRef.current.destroy();\n wavesurferRef.current = null;\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [src, showHoverCursor]);\n\n // Handle play/pause\n React.useEffect(() => {\n if (!wavesurferRef.current || !isLoaded) return;\n\n if (isPlaying) {\n wavesurferRef.current.play();\n } else {\n wavesurferRef.current.pause();\n }\n }, [isPlaying, isLoaded]);\n\n // Handle playback rate changes\n React.useEffect(() => {\n if (!wavesurferRef.current || !isLoaded) return;\n wavesurferRef.current.setPlaybackRate(playbackRate);\n }, [playbackRate, isLoaded]);\n\n // Hover cursor handlers\n const handleMouseMove = showHoverCursor\n ? (e: React.MouseEvent<HTMLDivElement>) => {\n if (!containerRef.current || !wavesurferRef.current || !isLoaded)\n return;\n const rect = containerRef.current.getBoundingClientRect();\n const x = Math.max(0, Math.min(e.clientX - rect.left, rect.width));\n const percentage = x / rect.width;\n const duration = wavesurferRef.current.getDuration();\n setHoverPosition(percentage * 100);\n onHoverTimeChange?.(percentage * duration);\n }\n : undefined;\n\n const handleMouseEnter = showHoverCursor\n ? () => setIsHovering(true)\n : undefined;\n\n const handleMouseLeave = showHoverCursor\n ? () => {\n setIsHovering(false);\n setHoverPosition(0);\n onHoverTimeChange?.(null);\n }\n : undefined;\n\n const handleClick = showHoverCursor\n ? (e: React.MouseEvent<HTMLDivElement>) => {\n if (!containerRef.current || !wavesurferRef.current || !isLoaded)\n return;\n const rect = containerRef.current.getBoundingClientRect();\n const x = Math.max(0, Math.min(e.clientX - rect.left, rect.width));\n const percentage = x / rect.width;\n wavesurferRef.current.seekTo(percentage);\n onSeek(wavesurferRef.current.getDuration() * percentage);\n onHoverTimeChange?.(null);\n }\n : undefined;\n\n const handleKeyDown = showHoverCursor\n ? (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (!wavesurferRef.current || !isLoaded) return;\n const duration = wavesurferRef.current.getDuration();\n const currentTime = wavesurferRef.current.getCurrentTime();\n const step = duration * 0.05; // 5% steps\n\n if (e.key === 'ArrowRight') {\n e.preventDefault();\n const newTime = Math.min(currentTime + step, duration);\n wavesurferRef.current.seekTo(newTime / duration);\n onSeek(newTime);\n } else if (e.key === 'ArrowLeft') {\n e.preventDefault();\n const newTime = Math.max(currentTime - step, 0);\n wavesurferRef.current.seekTo(newTime / duration);\n onSeek(newTime);\n }\n }\n : undefined;\n\n return (\n <div\n ref={containerRef}\n role={showHoverCursor ? 'slider' : undefined}\n aria-label={showHoverCursor ? 'Audio progress' : undefined}\n aria-valuemin={showHoverCursor ? 0 : undefined}\n aria-valuemax={\n showHoverCursor && wavesurferRef.current\n ? wavesurferRef.current.getDuration()\n : undefined\n }\n aria-valuenow={\n showHoverCursor && wavesurferRef.current\n ? wavesurferRef.current.getCurrentTime()\n : undefined\n }\n tabIndex={showHoverCursor ? 0 : undefined}\n className={cn(\n 'relative w-full rounded-lg bg-neutral-100 dark:bg-neutral-800',\n showHoverCursor && 'cursor-pointer',\n !isLoaded && 'animate-pulse'\n )}\n style={{ height }}\n onMouseMove={handleMouseMove}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n >\n {/* Hover cursor line */}\n {showHoverCursor && isHovering && isLoaded && (\n <div\n className=\"pointer-events-none absolute top-0 bottom-0 z-10 w-0.5\"\n style={{ left: `${hoverPosition}%`, backgroundColor: cursorColor }}\n />\n )}\n </div>\n );\n}\n\n// ============================================================================\n// Main AudioPlayer Component\n// ============================================================================\n\n/**\n * A versatile audio player component with multiple display variants.\n *\n * @example\n * ```tsx\n * // Inline - minimal, just play button and duration\n * <AudioPlayer src=\"/audio.mp3\" variant=\"inline\" showDuration />\n *\n * // Compact - play button, progress bar, and time\n * <AudioPlayer src=\"/audio.mp3\" variant=\"compact\" showTime />\n *\n * // Waveform - full visualization with WaveSurfer\n * <AudioPlayer src=\"/audio.mp3\" variant=\"waveform\" showTime />\n *\n * // With ref for programmatic control\n * const playerRef = useRef<AudioPlayerRef>(null);\n * <AudioPlayer ref={playerRef} src=\"/audio.mp3\" variant=\"waveform\" />\n * // Then: playerRef.current?.seekTo(30); playerRef.current?.play();\n * ```\n */\nconst AudioPlayer = React.forwardRef<\n AudioPlayerRef,\n AudioPlayerProps & { preload?: boolean; fallbackDuration?: number }\n>(function AudioPlayer(\n {\n src,\n title,\n variant = 'compact',\n size = 'md',\n onStateChange,\n onEnded,\n onError,\n onTimeUpdate,\n showTime = true,\n showDuration = true,\n waveColor,\n progressColor,\n waveformHeight = 64,\n showWaveformHoverCursor = true,\n waveformCursorColor,\n disabled = false,\n className,\n 'aria-label': ariaLabel,\n playbackRates = [0.5, 0.75, 1, 1.25, 1.5, 2],\n showPlaybackRate = false,\n /** Whether to preload audio (set to false for lists with many items) */\n preload = false,\n /** Fallback duration in seconds to display before audio is loaded */\n fallbackDuration,\n },\n ref\n) {\n const [state, setState] = React.useState<AudioPlayerState>('idle');\n const [currentTime, setCurrentTime] = React.useState(0);\n const [duration, setDuration] = React.useState(0);\n const [playbackRate, setPlaybackRate] = React.useState(1);\n const [audioInitialized, setAudioInitialized] = React.useState(false);\n const [hoverTime, setHoverTime] = React.useState<number | null>(null);\n const containerRef = React.useRef<HTMLDivElement>(null);\n const audioRef = React.useRef<globalThis.HTMLAudioElement | null>(null);\n const waveformMethodsRef = React.useRef<WaveformMethods | null>(null);\n\n const isPlaying = state === 'playing';\n const isLoading = state === 'loading';\n\n // Update state helper\n const updateState = React.useCallback(\n (newState: AudioPlayerState) => {\n setState(newState);\n onStateChange?.(newState);\n },\n [onStateChange]\n );\n\n // Initialize audio element (for non-waveform variants)\n const initAudio = React.useCallback(() => {\n if (variant === 'waveform' || audioInitialized) return null;\n\n const audio = new globalThis.Audio(src);\n audioRef.current = audio;\n setAudioInitialized(true);\n\n audio.addEventListener('loadstart', () => updateState('loading'));\n audio.addEventListener('canplay', () => {\n updateState('idle');\n });\n audio.addEventListener('loadedmetadata', () => {\n setDuration(audio.duration);\n });\n audio.addEventListener('timeupdate', () => {\n setCurrentTime(audio.currentTime);\n onTimeUpdate?.(audio.currentTime, audio.duration);\n });\n audio.addEventListener('ended', () => {\n updateState('idle');\n setCurrentTime(0);\n onEnded?.();\n });\n audio.addEventListener('error', () => {\n updateState('error');\n onError?.(new Error('Failed to load audio'));\n });\n\n return audio;\n }, [\n src,\n variant,\n audioInitialized,\n updateState,\n onTimeUpdate,\n onEnded,\n onError,\n ]);\n\n // Expose methods via ref for external control\n React.useImperativeHandle(\n ref,\n () => ({\n get container() {\n return containerRef.current;\n },\n seekTo: (time: number) => {\n if (variant === 'waveform') {\n waveformMethodsRef.current?.seekTo(time);\n } else {\n // Lazily initialize audio if not yet created\n if (!audioRef.current) {\n initAudio();\n }\n if (audioRef.current) {\n audioRef.current.currentTime = time;\n }\n }\n },\n play: () => {\n if (variant === 'waveform') {\n if (waveformMethodsRef.current) {\n waveformMethodsRef.current.play();\n updateState('playing');\n }\n } else {\n // Lazily initialize audio if not yet created\n if (!audioRef.current) {\n initAudio();\n }\n if (audioRef.current) {\n audioRef.current.play().catch((error) => {\n updateState('error');\n onError?.(error);\n });\n updateState('playing');\n }\n }\n },\n pause: () => {\n if (variant === 'waveform') {\n if (waveformMethodsRef.current) {\n waveformMethodsRef.current.pause();\n updateState('paused');\n }\n } else if (audioRef.current) {\n audioRef.current.pause();\n updateState('paused');\n }\n },\n getCurrentTime: () => {\n if (variant === 'waveform') {\n return waveformMethodsRef.current?.getCurrentTime() ?? 0;\n }\n return audioRef.current?.currentTime ?? 0;\n },\n getDuration: () => {\n if (variant === 'waveform') {\n return waveformMethodsRef.current?.getDuration() ?? 0;\n }\n const rawDuration = audioRef.current?.duration;\n return Number.isFinite(rawDuration) ? rawDuration! : 0;\n },\n }),\n [variant, initAudio, updateState, onError]\n );\n\n // Auto-initialize if preload is true\n React.useEffect(() => {\n if (preload && !audioInitialized && variant !== 'waveform') {\n initAudio();\n }\n }, [preload, audioInitialized, variant, initAudio]);\n\n // Cleanup on unmount\n React.useEffect(() => {\n return () => {\n if (audioRef.current) {\n audioRef.current.pause();\n audioRef.current.src = '';\n }\n };\n }, []);\n\n // Handle playback rate changes\n React.useEffect(() => {\n if (audioRef.current) {\n audioRef.current.playbackRate = playbackRate;\n }\n }, [playbackRate]);\n\n const handlePlay = React.useCallback(() => {\n if (disabled) return;\n\n // Waveform variant uses WaveSurfer for playback - just toggle state\n if (variant === 'waveform') {\n if (isLoading) return;\n updateState(isPlaying ? 'paused' : 'playing');\n return;\n }\n\n // Lazy initialize audio on first play\n if (!audioInitialized && !isLoading) {\n const audio = initAudio();\n if (audio) {\n updateState('loading');\n audio.addEventListener(\n 'canplay',\n () => {\n audio.play().catch((error) => {\n updateState('error');\n onError?.(error);\n });\n updateState('playing');\n },\n { once: true }\n );\n }\n return;\n }\n\n if (isLoading) return;\n\n if (isPlaying) {\n if (audioRef.current) {\n audioRef.current.pause();\n }\n updateState('paused');\n } else {\n if (audioRef.current) {\n audioRef.current.play().catch((error) => {\n updateState('error');\n onError?.(error);\n });\n updateState('playing');\n }\n }\n }, [\n disabled,\n variant,\n audioInitialized,\n isLoading,\n isPlaying,\n initAudio,\n updateState,\n onError,\n ]);\n\n const handleSeek = React.useCallback((time: number) => {\n if (audioRef.current) {\n audioRef.current.currentTime = time;\n setCurrentTime(time);\n }\n }, []);\n\n // Waveform callbacks\n const handleWaveformReady = React.useCallback((dur: number) => {\n setDuration(dur);\n setState('idle');\n }, []);\n\n const handleWaveformTimeUpdate = React.useCallback(\n (time: number) => {\n setCurrentTime(time);\n onTimeUpdate?.(time, duration);\n },\n [duration, onTimeUpdate]\n );\n\n const handleWaveformFinish = React.useCallback(() => {\n updateState('idle');\n setCurrentTime(0);\n onEnded?.();\n }, [updateState, onEnded]);\n\n const handleWaveformSeek = React.useCallback((time: number) => {\n setCurrentTime(time);\n }, []);\n\n const handleHoverTimeChange = React.useCallback((time: number | null) => {\n setHoverTime(time);\n }, []);\n\n const iconSize =\n size === 'sm' ? 'h-3.5 w-3.5' : size === 'lg' ? 'h-5 w-5' : 'h-4 w-4';\n\n const getAriaLabel = () => {\n if (ariaLabel) return ariaLabel;\n if (title) return `${isPlaying ? 'Pause' : 'Play'} ${title}`;\n return isPlaying ? 'Pause audio' : 'Play audio';\n };\n\n const renderPlayButton = () => (\n <button\n type=\"button\"\n onClick={handlePlay}\n disabled={disabled || isLoading}\n className={cn(playButtonVariants({ variant, size }))}\n aria-label={getAriaLabel()}\n aria-pressed={isPlaying}\n >\n {isLoading ? (\n <SpinnerIcon className={iconSize} />\n ) : isPlaying ? (\n <PauseIcon className={iconSize} />\n ) : (\n <PlayIcon className={iconSize} />\n )}\n </button>\n );\n\n const renderTime = (useHoverTime = false) => {\n if (!showTime) return null;\n const displayTime =\n useHoverTime && hoverTime !== null ? hoverTime : currentTime;\n const isShowingHoverTime = useHoverTime && hoverTime !== null;\n return (\n <span\n className={cn(\n 'font-mono text-xs tabular-nums',\n isShowingHoverTime\n ? 'text-primary-600 dark:text-primary-400'\n : 'text-neutral-500 dark:text-neutral-400'\n )}\n >\n {formatTime(displayTime)} / {formatTime(duration)}\n </span>\n );\n };\n\n const renderPlaybackRateControl = () => {\n if (!showPlaybackRate) return null;\n return (\n <select\n value={playbackRate}\n onChange={(e) => setPlaybackRate(Number(e.target.value))}\n className=\"rounded border border-neutral-200 bg-transparent px-1 py-0.5 text-xs dark:border-neutral-700\"\n aria-label=\"Playback speed\"\n >\n {playbackRates.map((rate) => (\n <option key={rate} value={rate}>\n {rate}x\n </option>\n ))}\n </select>\n );\n };\n\n // ============================================================================\n // Inline Variant\n // ============================================================================\n if (variant === 'inline') {\n const displayDuration = duration > 0 ? duration : (fallbackDuration ?? 0);\n return (\n <div\n ref={containerRef}\n className={cn(audioPlayerVariants({ variant, size }), className)}\n >\n {renderPlayButton()}\n {title && (\n <span className=\"text-sm font-medium text-neutral-700 dark:text-neutral-300\">\n {title}\n </span>\n )}\n {showDuration && displayDuration > 0 && (\n <span className=\"font-mono text-xs text-neutral-500 tabular-nums dark:text-neutral-400\">\n {isPlaying ? formatTime(currentTime) : formatTime(displayDuration)}\n </span>\n )}\n </div>\n );\n }\n\n // Compact Variant\n // ============================================================================\n if (variant === 'compact') {\n return (\n <div\n ref={containerRef}\n className={cn(audioPlayerVariants({ variant, size }), className)}\n >\n {renderPlayButton()}\n <ProgressBar\n currentTime={currentTime}\n duration={duration}\n onSeek={handleSeek}\n disabled={disabled}\n />\n {renderTime()}\n {renderPlaybackRateControl()}\n </div>\n );\n }\n\n // ============================================================================\n // Waveform Variant\n // ============================================================================\n return (\n <div\n ref={containerRef}\n className={cn(audioPlayerVariants({ variant, size }), className)}\n >\n {title && (\n <span className=\"text-sm font-medium text-neutral-700 dark:text-neutral-300\">\n {title}\n </span>\n )}\n <Waveform\n src={src}\n isPlaying={isPlaying}\n playbackRate={playbackRate}\n onReady={handleWaveformReady}\n onTimeUpdate={handleWaveformTimeUpdate}\n onFinish={handleWaveformFinish}\n onSeek={handleWaveformSeek}\n waveColor={waveColor}\n progressColor={progressColor}\n height={waveformHeight}\n showHoverCursor={showWaveformHoverCursor}\n onHoverTimeChange={handleHoverTimeChange}\n cursorColor={waveformCursorColor}\n waveformRef={waveformMethodsRef}\n />\n <div className=\"flex items-center gap-3\">\n {renderPlayButton()}\n <div className=\"flex flex-1 items-center justify-between\">\n {renderTime(true)}\n {renderPlaybackRateControl()}\n </div>\n </div>\n </div>\n );\n});\n\nAudioPlayer.displayName = 'AudioPlayer';\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { AudioPlayer, audioPlayerVariants, playButtonVariants, ProgressBar };\n"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { AlertCircle, ArrowLeft, Building, Calendar, Camera, Check, CheckCircle, ChevronDown, ChevronUp, ClipboardList, Clock, FileText, Globe, Image, Mail, Menu, Paperclip, Pencil, Phone, Plus, RefreshCw, Scan, ScanLine, Stethoscope, Trash2, Upload, Users, X } from 'lucide-react';
|
|
2
|
+
//# sourceMappingURL=chunk-K5T2PT4M.js.map
|
|
3
|
+
//# sourceMappingURL=chunk-K5T2PT4M.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-K5T2PT4M.js","sourcesContent":[]}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/brands/ozwell.ts
|
|
4
|
+
var ozwellBrand = {
|
|
5
|
+
name: "ozwell",
|
|
6
|
+
displayName: "Ozwell",
|
|
7
|
+
description: "Ozwell AI Assistant by BlueHive Health",
|
|
8
|
+
colors: {
|
|
9
|
+
// Primary color scale - BlueHive Blue (#27aae1)
|
|
10
|
+
primary: {
|
|
11
|
+
50: "#e6f7fc",
|
|
12
|
+
100: "#b3e6f6",
|
|
13
|
+
200: "#80d5f0",
|
|
14
|
+
300: "#4dc4ea",
|
|
15
|
+
400: "#27aae1",
|
|
16
|
+
500: "#27aae1",
|
|
17
|
+
600: "#1f98ca",
|
|
18
|
+
700: "#1786b3",
|
|
19
|
+
800: "#0f749c",
|
|
20
|
+
900: "#086285",
|
|
21
|
+
950: "#00506e"
|
|
22
|
+
},
|
|
23
|
+
// Light mode semantic colors
|
|
24
|
+
light: {
|
|
25
|
+
background: "#ffffff",
|
|
26
|
+
foreground: "#171717",
|
|
27
|
+
card: "#ffffff",
|
|
28
|
+
cardForeground: "#171717",
|
|
29
|
+
muted: "#f5f5f5",
|
|
30
|
+
mutedForeground: "#737373",
|
|
31
|
+
border: "#e5e7eb",
|
|
32
|
+
input: "#e5e7eb",
|
|
33
|
+
ring: "#27aae1",
|
|
34
|
+
destructive: "#ef4444",
|
|
35
|
+
destructiveForeground: "#ffffff",
|
|
36
|
+
success: "#22c55e",
|
|
37
|
+
successForeground: "#ffffff",
|
|
38
|
+
warning: "#f59e0b",
|
|
39
|
+
warningForeground: "#ffffff"
|
|
40
|
+
},
|
|
41
|
+
// Dark mode semantic colors
|
|
42
|
+
dark: {
|
|
43
|
+
background: "#181818",
|
|
44
|
+
foreground: "#dee2e6",
|
|
45
|
+
card: "#181818",
|
|
46
|
+
cardForeground: "#dee2e6",
|
|
47
|
+
muted: "#2b3035",
|
|
48
|
+
mutedForeground: "#adb5bd",
|
|
49
|
+
border: "rgba(255, 255, 255, 0.15)",
|
|
50
|
+
input: "#495057",
|
|
51
|
+
ring: "#27aae1",
|
|
52
|
+
destructive: "#dc2626",
|
|
53
|
+
destructiveForeground: "#fafafa",
|
|
54
|
+
success: "#16a34a",
|
|
55
|
+
successForeground: "#fafafa",
|
|
56
|
+
warning: "#d97706",
|
|
57
|
+
warningForeground: "#fafafa"
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
typography: {
|
|
61
|
+
fontFamily: {
|
|
62
|
+
sans: ["Nunito", "ui-sans-serif", "system-ui", "sans-serif"],
|
|
63
|
+
mono: ["ui-monospace", "SFMono-Regular", "Menlo", "monospace"]
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
borderRadius: {
|
|
67
|
+
none: "0",
|
|
68
|
+
sm: "0.25rem",
|
|
69
|
+
md: "0.5rem",
|
|
70
|
+
lg: "0.75rem",
|
|
71
|
+
xl: "1rem",
|
|
72
|
+
"2xl": "1.5rem",
|
|
73
|
+
full: "9999px"
|
|
74
|
+
},
|
|
75
|
+
boxShadow: {
|
|
76
|
+
card: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
|
|
77
|
+
dropdown: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
|
|
78
|
+
modal: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)"
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
exports.ozwellBrand = ozwellBrand;
|
|
83
|
+
//# sourceMappingURL=chunk-KEIA2G6O.cjs.map
|
|
84
|
+
//# sourceMappingURL=chunk-KEIA2G6O.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/brands/ozwell.ts"],"names":[],"mappings":";;;AAcO,IAAM,WAAA,GAA2B;AAAA,EACtC,IAAA,EAAM,QAAA;AAAA,EACN,WAAA,EAAa,QAAA;AAAA,EACb,WAAA,EAAa,wCAAA;AAAA,EAEb,MAAA,EAAQ;AAAA;AAAA,IAEN,OAAA,EAAS;AAAA,MACP,EAAA,EAAI,SAAA;AAAA,MACJ,GAAA,EAAK,SAAA;AAAA,MACL,GAAA,EAAK,SAAA;AAAA,MACL,GAAA,EAAK,SAAA;AAAA,MACL,GAAA,EAAK,SAAA;AAAA,MACL,GAAA,EAAK,SAAA;AAAA,MACL,GAAA,EAAK,SAAA;AAAA,MACL,GAAA,EAAK,SAAA;AAAA,MACL,GAAA,EAAK,SAAA;AAAA,MACL,GAAA,EAAK,SAAA;AAAA,MACL,GAAA,EAAK;AAAA,KACP;AAAA;AAAA,IAGA,KAAA,EAAO;AAAA,MACL,UAAA,EAAY,SAAA;AAAA,MACZ,UAAA,EAAY,SAAA;AAAA,MACZ,IAAA,EAAM,SAAA;AAAA,MACN,cAAA,EAAgB,SAAA;AAAA,MAChB,KAAA,EAAO,SAAA;AAAA,MACP,eAAA,EAAiB,SAAA;AAAA,MACjB,MAAA,EAAQ,SAAA;AAAA,MACR,KAAA,EAAO,SAAA;AAAA,MACP,IAAA,EAAM,SAAA;AAAA,MACN,WAAA,EAAa,SAAA;AAAA,MACb,qBAAA,EAAuB,SAAA;AAAA,MACvB,OAAA,EAAS,SAAA;AAAA,MACT,iBAAA,EAAmB,SAAA;AAAA,MACnB,OAAA,EAAS,SAAA;AAAA,MACT,iBAAA,EAAmB;AAAA,KACrB;AAAA;AAAA,IAGA,IAAA,EAAM;AAAA,MACJ,UAAA,EAAY,SAAA;AAAA,MACZ,UAAA,EAAY,SAAA;AAAA,MACZ,IAAA,EAAM,SAAA;AAAA,MACN,cAAA,EAAgB,SAAA;AAAA,MAChB,KAAA,EAAO,SAAA;AAAA,MACP,eAAA,EAAiB,SAAA;AAAA,MACjB,MAAA,EAAQ,2BAAA;AAAA,MACR,KAAA,EAAO,SAAA;AAAA,MACP,IAAA,EAAM,SAAA;AAAA,MACN,WAAA,EAAa,SAAA;AAAA,MACb,qBAAA,EAAuB,SAAA;AAAA,MACvB,OAAA,EAAS,SAAA;AAAA,MACT,iBAAA,EAAmB,SAAA;AAAA,MACnB,OAAA,EAAS,SAAA;AAAA,MACT,iBAAA,EAAmB;AAAA;AACrB,GACF;AAAA,EAEA,UAAA,EAAY;AAAA,IACV,UAAA,EAAY;AAAA,MACV,IAAA,EAAM,CAAC,QAAA,EAAU,eAAA,EAAiB,aAAa,YAAY,CAAA;AAAA,MAC3D,IAAA,EAAM,CAAC,cAAA,EAAgB,gBAAA,EAAkB,SAAS,WAAW;AAAA;AAC/D,GACF;AAAA,EAEA,YAAA,EAAc;AAAA,IACZ,IAAA,EAAM,GAAA;AAAA,IACN,EAAA,EAAI,SAAA;AAAA,IACJ,EAAA,EAAI,QAAA;AAAA,IACJ,EAAA,EAAI,SAAA;AAAA,IACJ,EAAA,EAAI,MAAA;AAAA,IACJ,KAAA,EAAO,QAAA;AAAA,IACP,IAAA,EAAM;AAAA,GACR;AAAA,EAEA,SAAA,EAAW;AAAA,IACT,IAAA,EAAM,+DAAA;AAAA,IACN,QAAA,EACE,kEAAA;AAAA,IACF,KAAA,EAAO;AAAA;AAEX","file":"chunk-KEIA2G6O.cjs","sourcesContent":["/**\n * Ozwell Brand Configuration\n *\n * The official brand theme for Ozwell AI Assistant.\n * Primary color: #27aae1 (BlueHive Blue)\n * Font: Nunito\n */\n\nimport type { BrandConfig } from './types';\n\n/**\n * Ozwell brand configuration.\n * This defines all the design tokens used in the Ozwell AI Assistant.\n */\nexport const ozwellBrand: BrandConfig = {\n name: 'ozwell',\n displayName: 'Ozwell',\n description: 'Ozwell AI Assistant by BlueHive Health',\n\n colors: {\n // Primary color scale - BlueHive Blue (#27aae1)\n primary: {\n 50: '#e6f7fc',\n 100: '#b3e6f6',\n 200: '#80d5f0',\n 300: '#4dc4ea',\n 400: '#27aae1',\n 500: '#27aae1',\n 600: '#1f98ca',\n 700: '#1786b3',\n 800: '#0f749c',\n 900: '#086285',\n 950: '#00506e',\n },\n\n // Light mode semantic colors\n light: {\n background: '#ffffff',\n foreground: '#171717',\n card: '#ffffff',\n cardForeground: '#171717',\n muted: '#f5f5f5',\n mutedForeground: '#737373',\n border: '#e5e7eb',\n input: '#e5e7eb',\n ring: '#27aae1',\n destructive: '#ef4444',\n destructiveForeground: '#ffffff',\n success: '#22c55e',\n successForeground: '#ffffff',\n warning: '#f59e0b',\n warningForeground: '#ffffff',\n },\n\n // Dark mode semantic colors\n dark: {\n background: '#181818',\n foreground: '#dee2e6',\n card: '#181818',\n cardForeground: '#dee2e6',\n muted: '#2b3035',\n mutedForeground: '#adb5bd',\n border: 'rgba(255, 255, 255, 0.15)',\n input: '#495057',\n ring: '#27aae1',\n destructive: '#dc2626',\n destructiveForeground: '#fafafa',\n success: '#16a34a',\n successForeground: '#fafafa',\n warning: '#d97706',\n warningForeground: '#fafafa',\n },\n },\n\n typography: {\n fontFamily: {\n sans: ['Nunito', 'ui-sans-serif', 'system-ui', 'sans-serif'],\n mono: ['ui-monospace', 'SFMono-Regular', 'Menlo', 'monospace'],\n },\n },\n\n borderRadius: {\n none: '0',\n sm: '0.25rem',\n md: '0.5rem',\n lg: '0.75rem',\n xl: '1rem',\n '2xl': '1.5rem',\n full: '9999px',\n },\n\n boxShadow: {\n card: '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',\n dropdown:\n '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',\n modal: '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',\n },\n};\n"]}
|
|
@@ -135,14 +135,25 @@ function Select({
|
|
|
135
135
|
const updateDropdownPosition = React.useCallback(() => {
|
|
136
136
|
if (!triggerRef.current) return;
|
|
137
137
|
const rect = triggerRef.current.getBoundingClientRect();
|
|
138
|
+
const spaceBelow = window.innerHeight - rect.bottom;
|
|
139
|
+
const spaceAbove = rect.top;
|
|
140
|
+
const estimatedDropdownHeight = Math.min(flatOptions.length * 40 + 16, 300);
|
|
141
|
+
const openAbove = spaceBelow < estimatedDropdownHeight && spaceAbove > spaceBelow;
|
|
138
142
|
setDropdownStyle({
|
|
139
143
|
position: "fixed",
|
|
140
|
-
top: rect.bottom + 4,
|
|
144
|
+
...openAbove ? { bottom: window.innerHeight - rect.top + 4 } : { top: rect.bottom + 4 },
|
|
141
145
|
left: rect.left,
|
|
142
146
|
width: rect.width,
|
|
147
|
+
maxHeight: Math.max(
|
|
148
|
+
Math.min(openAbove ? spaceAbove - 8 : spaceBelow - 8, 300),
|
|
149
|
+
0
|
|
150
|
+
),
|
|
151
|
+
display: "flex",
|
|
152
|
+
flexDirection: "column",
|
|
153
|
+
overflow: "hidden",
|
|
143
154
|
zIndex: 9999
|
|
144
155
|
});
|
|
145
|
-
}, []);
|
|
156
|
+
}, [flatOptions.length]);
|
|
146
157
|
React.useEffect(() => {
|
|
147
158
|
if (!isOpen) return;
|
|
148
159
|
updateDropdownPosition();
|
|
@@ -307,7 +318,7 @@ function Select({
|
|
|
307
318
|
id: listboxId,
|
|
308
319
|
role: "listbox",
|
|
309
320
|
"aria-label": label || "Options",
|
|
310
|
-
className: "
|
|
321
|
+
className: "flex-1 overflow-auto p-1",
|
|
311
322
|
children: filteredFlatOptions.length === 0 ? /* @__PURE__ */ jsx("li", { className: "text-muted-foreground px-3 py-2 text-center text-sm", children: noResultsText }) : filteredOptions.map((item) => {
|
|
312
323
|
if ("options" in item) {
|
|
313
324
|
return /* @__PURE__ */ jsxs("li", { role: "presentation", children: [
|
|
@@ -441,5 +452,5 @@ function CheckIcon({ className }) {
|
|
|
441
452
|
}
|
|
442
453
|
|
|
443
454
|
export { Select, selectTriggerVariants };
|
|
444
|
-
//# sourceMappingURL=chunk-
|
|
445
|
-
//# sourceMappingURL=chunk-
|
|
455
|
+
//# sourceMappingURL=chunk-QSMMFATL.js.map
|
|
456
|
+
//# sourceMappingURL=chunk-QSMMFATL.js.map
|