@mieweb/ui 0.11.0-dev.1 → 0.11.0-dev.10
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 +11 -2
- package/dist/ag-grid.cjs.map +1 -1
- package/dist/ag-grid.d.cts +8 -0
- package/dist/ag-grid.d.ts +8 -0
- package/dist/ag-grid.js +11 -2
- package/dist/ag-grid.js.map +1 -1
- package/dist/brands/index.cjs +12 -12
- package/dist/brands/index.js +3 -3
- package/dist/{chunk-U2RS574O.cjs → chunk-2GBVJHWN.cjs} +120 -63
- package/dist/chunk-2GBVJHWN.cjs.map +1 -0
- package/dist/{chunk-7UTBDFFL.cjs → chunk-2S76TRBJ.cjs} +4 -4
- package/dist/{chunk-7UTBDFFL.cjs.map → chunk-2S76TRBJ.cjs.map} +1 -1
- package/dist/{chunk-IJYTASQQ.cjs → chunk-3AD4HFYI.cjs} +15 -7
- package/dist/chunk-3AD4HFYI.cjs.map +1 -0
- package/dist/{chunk-CFI3TQMA.cjs → chunk-56C7K4MV.cjs} +9 -4
- package/dist/chunk-56C7K4MV.cjs.map +1 -0
- package/dist/{chunk-TNUL4LGG.js → chunk-5ILCNY74.js} +15 -7
- package/dist/chunk-5ILCNY74.js.map +1 -0
- package/dist/{chunk-AFDW64EF.cjs → chunk-5K7PRPSV.cjs} +30 -2
- package/dist/chunk-5K7PRPSV.cjs.map +1 -0
- package/dist/{chunk-QQCHM7BZ.cjs → chunk-5VA2HJ5B.cjs} +6 -6
- package/dist/{chunk-QQCHM7BZ.cjs.map → chunk-5VA2HJ5B.cjs.map} +1 -1
- package/dist/{chunk-PJ6CC53R.cjs → chunk-AKMTPCLC.cjs} +13 -8
- package/dist/chunk-AKMTPCLC.cjs.map +1 -0
- package/dist/{chunk-OODVC2UD.cjs → chunk-AWSSWNJY.cjs} +2 -2
- package/dist/{chunk-OODVC2UD.cjs.map → chunk-AWSSWNJY.cjs.map} +1 -1
- package/dist/chunk-BFVYM6IT.cjs +345 -0
- package/dist/chunk-BFVYM6IT.cjs.map +1 -0
- package/dist/{chunk-VVDE4CHU.js → chunk-C4GEPUE7.js} +13 -8
- package/dist/chunk-C4GEPUE7.js.map +1 -0
- package/dist/{chunk-TJ4GWQPM.js → chunk-DAAJ3B2T.js} +121 -65
- package/dist/chunk-DAAJ3B2T.js.map +1 -0
- package/dist/{chunk-QJ2L5RU6.js → chunk-DSQCYX7L.js} +2 -2
- package/dist/{chunk-QJ2L5RU6.js.map → chunk-DSQCYX7L.js.map} +1 -1
- package/dist/{chunk-NUB5HRKS.js → chunk-DT3X3RBM.js} +3 -3
- package/dist/{chunk-NUB5HRKS.js.map → chunk-DT3X3RBM.js.map} +1 -1
- package/dist/{chunk-AG5EKCE4.js → chunk-EBQG3NGT.js} +30 -2
- package/dist/chunk-EBQG3NGT.js.map +1 -0
- package/dist/{chunk-MYAU2ZUC.cjs → chunk-GDKOYVX3.cjs} +14 -10
- package/dist/chunk-GDKOYVX3.cjs.map +1 -0
- package/dist/{chunk-JTSKPDPH.cjs → chunk-HIYQ3M5V.cjs} +4 -3
- package/dist/chunk-HIYQ3M5V.cjs.map +1 -0
- package/dist/{chunk-7IBZA7G6.js → chunk-I6Y2KLTZ.js} +5 -2
- package/dist/chunk-I6Y2KLTZ.js.map +1 -0
- package/dist/chunk-IZY4CMOO.js +715 -0
- package/dist/chunk-IZY4CMOO.js.map +1 -0
- package/dist/{chunk-753ENNB6.js → chunk-J3QEMZCH.js} +2 -2
- package/dist/{chunk-753ENNB6.js.map → chunk-J3QEMZCH.js.map} +1 -1
- package/dist/{chunk-S2JZL4JC.js → chunk-JM4YFLO4.js} +22 -15
- package/dist/chunk-JM4YFLO4.js.map +1 -0
- package/dist/{chunk-QX6AAVDE.cjs → chunk-L4APW65W.cjs} +15 -6
- package/dist/chunk-L4APW65W.cjs.map +1 -0
- package/dist/{chunk-OHKO5THF.cjs → chunk-MGFRGPWI.cjs} +3 -2
- package/dist/chunk-MGFRGPWI.cjs.map +1 -0
- package/dist/{chunk-RM2HPQIC.js → chunk-MQ5WJ3NO.js} +4 -4
- package/dist/chunk-MQ5WJ3NO.js.map +1 -0
- package/dist/{chunk-VNWJTCBQ.js → chunk-MQOYDQTF.js} +4 -3
- package/dist/chunk-MQOYDQTF.js.map +1 -0
- package/dist/chunk-MZA2LDS4.js +321 -0
- package/dist/chunk-MZA2LDS4.js.map +1 -0
- package/dist/{chunk-VYNFJVRZ.js → chunk-N6XBE47W.js} +3 -3
- package/dist/{chunk-VYNFJVRZ.js.map → chunk-N6XBE47W.js.map} +1 -1
- package/dist/{chunk-T5BBZQ66.js → chunk-OTIKWEFZ.js} +9 -4
- package/dist/chunk-OTIKWEFZ.js.map +1 -0
- package/dist/{chunk-YZCM7CXK.js → chunk-OZKJYLN6.js} +3 -3
- package/dist/{chunk-YZCM7CXK.js.map → chunk-OZKJYLN6.js.map} +1 -1
- package/dist/{chunk-ZSGEGISB.cjs → chunk-PHUTJKHL.cjs} +5 -2
- package/dist/chunk-PHUTJKHL.cjs.map +1 -0
- package/dist/{chunk-FMEA6WAY.cjs → chunk-Q6QLGCL7.cjs} +9 -9
- package/dist/{chunk-FMEA6WAY.cjs.map → chunk-Q6QLGCL7.cjs.map} +1 -1
- package/dist/{chunk-XOIIUO6O.js → chunk-QDNHN7R2.js} +3 -2
- package/dist/chunk-QDNHN7R2.js.map +1 -0
- package/dist/{chunk-XRVMYT5G.cjs → chunk-QKW2QCGI.cjs} +5 -5
- package/dist/chunk-QKW2QCGI.cjs.map +1 -0
- package/dist/{chunk-NAH65KPK.cjs → chunk-TOJ56HKQ.cjs} +2 -2
- package/dist/{chunk-NAH65KPK.cjs.map → chunk-TOJ56HKQ.cjs.map} +1 -1
- package/dist/chunk-TRZLN32I.cjs +740 -0
- package/dist/chunk-TRZLN32I.cjs.map +1 -0
- package/dist/{chunk-O6XDA3SI.js → chunk-UY2EZYIC.js} +15 -6
- package/dist/chunk-UY2EZYIC.js.map +1 -0
- package/dist/{chunk-2BPIVWAK.js → chunk-V5VPECJI.js} +14 -10
- package/dist/chunk-V5VPECJI.js.map +1 -0
- package/dist/{chunk-O6BJMVGT.cjs → chunk-XZNHS7YQ.cjs} +24 -17
- package/dist/chunk-XZNHS7YQ.cjs.map +1 -0
- package/dist/components/AudioPlayer/index.cjs +7 -6
- package/dist/components/AudioPlayer/index.js +2 -1
- package/dist/components/CollabStatus/index.cjs +5 -4
- package/dist/components/CollabStatus/index.js +2 -1
- package/dist/components/CountryCodeDropdown/index.cjs +4 -4
- package/dist/components/CountryCodeDropdown/index.js +1 -1
- package/dist/components/DateInput/index.cjs +2 -2
- package/dist/components/DateInput/index.js +1 -1
- package/dist/components/DictationButton/index.cjs +23 -0
- package/dist/components/DictationButton/index.cjs.map +1 -0
- package/dist/components/DictationButton/index.d.cts +78 -0
- package/dist/components/DictationButton/index.d.ts +78 -0
- package/dist/components/DictationButton/index.js +6 -0
- package/dist/components/DictationButton/index.js.map +1 -0
- package/dist/components/Markdown/index.cjs +10 -10
- package/dist/components/Markdown/index.js +2 -2
- package/dist/components/MediaEditor/index.cjs +8 -7
- package/dist/components/MediaEditor/index.js +3 -2
- package/dist/components/PhoneInput/index.cjs +3 -3
- package/dist/components/PhoneInput/index.js +1 -1
- package/dist/components/RecordButton/index.cjs +4 -4
- package/dist/components/RecordButton/index.js +1 -1
- package/dist/components/Slider/index.cjs +6 -5
- package/dist/components/Slider/index.js +2 -1
- package/dist/components/SliderCalculator/index.cjs +5 -4
- package/dist/components/SliderCalculator/index.js +3 -2
- package/dist/components/SuperChat/index.cjs +14 -14
- package/dist/components/SuperChat/index.cjs.map +1 -1
- package/dist/components/SuperChat/index.d.cts +10 -6
- package/dist/components/SuperChat/index.d.ts +10 -6
- package/dist/components/SuperChat/index.js +4 -4
- package/dist/components/SuperChat/index.js.map +1 -1
- package/dist/components/SuperChat/plugins/index.cjs +3 -3
- package/dist/components/SuperChat/plugins/index.d.cts +2 -2
- package/dist/components/SuperChat/plugins/index.d.ts +2 -2
- package/dist/components/SuperChat/plugins/index.js +2 -2
- package/dist/components/Table/index.cjs +9 -9
- package/dist/components/Table/index.d.cts +17 -1
- package/dist/components/Table/index.d.ts +17 -1
- package/dist/components/Table/index.js +1 -1
- package/dist/deck.cjs +1 -1
- package/dist/deck.cjs.map +1 -1
- package/dist/deck.js +1 -1
- package/dist/deck.js.map +1 -1
- package/dist/esheet.cjs +5 -5
- package/dist/esheet.js +2 -2
- package/dist/index.cjs +600 -1134
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +154 -14
- package/dist/index.d.ts +154 -14
- package/dist/index.js +230 -834
- package/dist/index.js.map +1 -1
- package/dist/styles/init.css +39 -0
- package/dist/styles.css +1 -1
- package/dist/tailwind-preset.cjs +4 -4
- package/dist/tailwind-preset.js +1 -1
- package/dist/{types-Cx1FHLq2.d.ts → types-DSWbrVkM.d.cts} +1 -1
- package/dist/{types-Cx1FHLq2.d.cts → types-DSWbrVkM.d.ts} +1 -1
- package/dist/whisperTranscribe-AV752TZI.cjs +81 -0
- package/dist/whisperTranscribe-AV752TZI.cjs.map +1 -0
- package/dist/whisperTranscribe-UBNUWXUQ.js +4 -0
- package/dist/whisperTranscribe-UBNUWXUQ.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-2BPIVWAK.js.map +0 -1
- package/dist/chunk-7IBZA7G6.js.map +0 -1
- package/dist/chunk-AFDW64EF.cjs.map +0 -1
- package/dist/chunk-AG5EKCE4.js.map +0 -1
- package/dist/chunk-CFI3TQMA.cjs.map +0 -1
- package/dist/chunk-IJYTASQQ.cjs.map +0 -1
- package/dist/chunk-JTSKPDPH.cjs.map +0 -1
- package/dist/chunk-MYAU2ZUC.cjs.map +0 -1
- package/dist/chunk-O6BJMVGT.cjs.map +0 -1
- package/dist/chunk-O6XDA3SI.js.map +0 -1
- package/dist/chunk-OHKO5THF.cjs.map +0 -1
- package/dist/chunk-PJ6CC53R.cjs.map +0 -1
- package/dist/chunk-QX6AAVDE.cjs.map +0 -1
- package/dist/chunk-RM2HPQIC.js.map +0 -1
- package/dist/chunk-S2JZL4JC.js.map +0 -1
- package/dist/chunk-T5BBZQ66.js.map +0 -1
- package/dist/chunk-TJ4GWQPM.js.map +0 -1
- package/dist/chunk-TNUL4LGG.js.map +0 -1
- package/dist/chunk-U2RS574O.cjs.map +0 -1
- package/dist/chunk-VNWJTCBQ.js.map +0 -1
- package/dist/chunk-VVDE4CHU.js.map +0 -1
- package/dist/chunk-XOIIUO6O.js.map +0 -1
- package/dist/chunk-XRVMYT5G.cjs.map +0 -1
- package/dist/chunk-ZSGEGISB.cjs.map +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var chunkZ3WMDVMR_cjs = require('./chunk-Z3WMDVMR.cjs');
|
|
3
4
|
var chunkS5RVSXDV_cjs = require('./chunk-S5RVSXDV.cjs');
|
|
4
5
|
var React = require('react');
|
|
5
6
|
var classVarianceAuthority = require('class-variance-authority');
|
|
@@ -168,7 +169,7 @@ function ProgressBar({
|
|
|
168
169
|
const handleClick = (e) => {
|
|
169
170
|
if (disabled || !progressRef.current || duration <= 0) return;
|
|
170
171
|
const rect = progressRef.current.getBoundingClientRect();
|
|
171
|
-
const x = e.clientX - rect.left;
|
|
172
|
+
const x = chunkZ3WMDVMR_cjs.isRtl(progressRef.current) ? rect.right - e.clientX : e.clientX - rect.left;
|
|
172
173
|
const percentage = x / rect.width;
|
|
173
174
|
onSeek(percentage * duration);
|
|
174
175
|
};
|
|
@@ -192,10 +193,12 @@ function ProgressBar({
|
|
|
192
193
|
onKeyDown: (e) => {
|
|
193
194
|
if (disabled) return;
|
|
194
195
|
const step = duration * 0.05;
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
onSeek(
|
|
196
|
+
const rtl = chunkZ3WMDVMR_cjs.isRtl(e.currentTarget);
|
|
197
|
+
if (e.key === "ArrowRight" || e.key === "ArrowLeft") {
|
|
198
|
+
const forward = e.key === "ArrowRight" !== rtl;
|
|
199
|
+
onSeek(
|
|
200
|
+
forward ? Math.min(currentTime + step, duration) : Math.max(currentTime - step, 0)
|
|
201
|
+
);
|
|
199
202
|
}
|
|
200
203
|
},
|
|
201
204
|
children: [
|
|
@@ -209,8 +212,9 @@ function ProgressBar({
|
|
|
209
212
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
210
213
|
"div",
|
|
211
214
|
{
|
|
215
|
+
"data-slot": "audio-player-progress-thumb",
|
|
212
216
|
className: "bg-primary-800 absolute top-1/2 h-3 w-3 -translate-y-1/2 rounded-full shadow-sm transition-all",
|
|
213
|
-
style: {
|
|
217
|
+
style: { insetInlineStart: `calc(${progress}% - 6px)` }
|
|
214
218
|
}
|
|
215
219
|
)
|
|
216
220
|
]
|
|
@@ -399,6 +403,7 @@ function Waveform({
|
|
|
399
403
|
{
|
|
400
404
|
ref: containerRef,
|
|
401
405
|
"data-slot": "audio-player-waveform",
|
|
406
|
+
dir: "ltr",
|
|
402
407
|
role: showHoverCursor ? "slider" : void 0,
|
|
403
408
|
"aria-label": showHoverCursor ? "Audio progress" : void 0,
|
|
404
409
|
"aria-valuemin": showHoverCursor ? 0 : void 0,
|
|
@@ -851,5 +856,5 @@ exports.ProgressBar = ProgressBar;
|
|
|
851
856
|
exports.audioPlayerVariants = audioPlayerVariants;
|
|
852
857
|
exports.formatTime = formatTime;
|
|
853
858
|
exports.playButtonVariants = playButtonVariants;
|
|
854
|
-
//# sourceMappingURL=chunk-
|
|
855
|
-
//# sourceMappingURL=chunk-
|
|
859
|
+
//# sourceMappingURL=chunk-AKMTPCLC.cjs.map
|
|
860
|
+
//# sourceMappingURL=chunk-AKMTPCLC.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/AudioPlayer/AudioPlayer.tsx"],"names":["cva","jsx","jsxs","cn","React","isRtl","AudioPlayer"],"mappings":"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","file":"chunk-AKMTPCLC.cjs","sourcesContent":["import * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\nimport { isRtl } from '../../hooks/useDirection';\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 /** Whether to preload audio (set to false for lists with many items) */\n preload?: boolean;\n /** Fallback duration in seconds to display before audio metadata is loaded */\n fallbackDuration?: number;\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-800 text-white',\n 'hover:bg-primary-900',\n 'active:bg-primary-800',\n ],\n waveform: [\n 'bg-primary-800 text-white',\n 'hover:bg-primary-900',\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 // Progress fills from the inline-start edge: left→right in LTR,\n // right→left in RTL.\n const x = isRtl(progressRef.current)\n ? rect.right - e.clientX\n : e.clientX - rect.left;\n const percentage = x / rect.width;\n onSeek(percentage * duration);\n };\n\n return (\n <div\n ref={progressRef}\n data-slot=\"audio-player-progress\"\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 // Horizontal arrows follow the visual direction: in RTL the bar\n // fills right→left, so ArrowLeft seeks forward.\n const rtl = isRtl(e.currentTarget);\n if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') {\n const forward = (e.key === 'ArrowRight') !== rtl;\n onSeek(\n forward\n ? Math.min(currentTime + step, duration)\n : Math.max(currentTime - step, 0)\n );\n }\n }}\n >\n <div\n className=\"bg-primary-800 absolute inset-y-0 start-0 rounded-full transition-all\"\n style={{ width: `${progress}%` }}\n />\n <div\n data-slot=\"audio-player-progress-thumb\"\n className=\"bg-primary-800 absolute top-1/2 h-3 w-3 -translate-y-1/2 rounded-full shadow-sm transition-all\"\n style={{ insetInlineStart: `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, duration: 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 const emitTimeUpdate = () => {\n onTimeUpdate(\n wavesurferRef.current.getCurrentTime(),\n wavesurferRef.current.getDuration()\n );\n };\n\n wavesurferRef.current.on('ready', () => {\n setIsLoaded(true);\n const duration = wavesurferRef.current.getDuration();\n onReady(duration);\n onTimeUpdate(wavesurferRef.current.getCurrentTime(), duration);\n });\n\n wavesurferRef.current.on('timeupdate', emitTimeUpdate);\n wavesurferRef.current.on('audioprocess', emitTimeUpdate);\n\n wavesurferRef.current.on('seeking', () => {\n emitTimeUpdate();\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 const duration = wavesurferRef.current.getDuration();\n const time = duration * percentage;\n wavesurferRef.current.seekTo(percentage);\n onSeek(time);\n onTimeUpdate(time, duration);\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 onTimeUpdate(newTime, duration);\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 onTimeUpdate(newTime, duration);\n }\n }\n : undefined;\n\n return (\n <div\n ref={containerRef}\n data-slot=\"audio-player-waveform\"\n // WaveSurfer draws its canvas physically left→right regardless of\n // document direction, so the waveform is an LTR island — cursor math,\n // click/keyboard seeking, and the canvas all stay physical.\n dir=\"ltr\"\n role={showHoverCursor ? 'slider' : undefined}\n aria-label={showHoverCursor ? 'Audio progress' : undefined}\n aria-valuemin={showHoverCursor ? 0 : undefined}\n aria-valuemax={\n showHoverCursor\n ? (wavesurferRef.current?.getDuration() ?? 0)\n : undefined\n }\n aria-valuenow={\n showHoverCursor\n ? (wavesurferRef.current?.getCurrentTime() ?? 0)\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 // rtl-ignore -- anchored to the WaveSurfer canvas, an LTR island\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<AudioPlayerRef, AudioPlayerProps>(\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 const displayDuration = duration > 0 ? duration : (fallbackDuration ?? 0);\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 onTimeUpdate?.(audio.currentTime, 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(\n (time: number) => {\n if (audioRef.current) {\n audioRef.current.currentTime = time;\n setCurrentTime(time);\n onTimeUpdate?.(time, audioRef.current.duration);\n }\n },\n [onTimeUpdate]\n );\n\n // Waveform callbacks\n const handleWaveformReady = React.useCallback(\n (dur: number) => {\n setDuration(dur);\n setState('idle');\n onTimeUpdate?.(currentTime, dur);\n },\n [currentTime, onTimeUpdate]\n );\n\n const handleWaveformTimeUpdate = React.useCallback(\n (time: number, dur: number) => {\n setCurrentTime(time);\n if (dur > 0) {\n setDuration(dur);\n }\n onTimeUpdate?.(time, dur);\n },\n [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 data-slot=\"audio-player-play-btn\"\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 data-slot=\"audio-player-time\"\n className={cn(\n 'font-mono text-xs tabular-nums',\n isShowingHoverTime\n ? 'text-primary-800 dark:text-primary-400'\n : 'text-neutral-600 dark:text-neutral-400'\n )}\n >\n {formatTime(displayTime)} / {formatTime(displayDuration)}\n </span>\n );\n };\n\n const renderPlaybackRateControl = () => {\n if (!showPlaybackRate) return null;\n return (\n <select\n data-slot=\"audio-player-rate\"\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 return (\n <div\n ref={containerRef}\n data-slot=\"audio-player\"\n data-variant=\"inline\"\n className={cn(audioPlayerVariants({ variant, size }), className)}\n >\n {renderPlayButton()}\n {title && (\n <span\n data-slot=\"audio-player-title\"\n className=\"text-sm font-medium text-neutral-700 dark:text-neutral-300\"\n >\n {title}\n </span>\n )}\n {showDuration && displayDuration > 0 && (\n <span\n data-slot=\"audio-player-duration\"\n className=\"font-mono text-xs text-neutral-500 tabular-nums dark:text-neutral-400\"\n >\n {isPlaying\n ? formatTime(currentTime)\n : 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 data-slot=\"audio-player\"\n data-variant=\"compact\"\n className={cn(audioPlayerVariants({ variant, size }), className)}\n >\n {renderPlayButton()}\n <ProgressBar\n currentTime={currentTime}\n duration={displayDuration}\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 data-slot=\"audio-player\"\n data-variant=\"waveform\"\n className={cn(audioPlayerVariants({ variant, size }), className)}\n >\n {title && (\n <span\n data-slot=\"audio-player-title\"\n className=\"text-sm font-medium text-neutral-700 dark:text-neutral-300\"\n >\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\n data-slot=\"audio-player-controls\"\n className=\"flex items-center gap-3\"\n >\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);\n\nAudioPlayer.displayName = 'AudioPlayer';\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { AudioPlayer, audioPlayerVariants, playButtonVariants, ProgressBar };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/brands/index.ts"],"names":[],"mappings":";;;AAkCO,IAAM,MAAA,GAAS;AAAA,EACpB,QAAA,EAAU,MAAM,OAAO,uBAAY,EAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,aAAa,CAAA;AAAA,EAChE,IAAA,EAAM,MAAM,OAAO,mBAAQ,EAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,CAAA;AAAA,EACpD,OAAA,EAAS,MAAM,OAAO,wBAAW,EAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,YAAY,CAAA;AAAA,EAC7D,mBAAA,EAAqB,MACnB,OAAO,kCAAqB,EAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,qBAAqB,CAAA;AAAA,EACnE,MAAA,EAAQ,MAAM,OAAO,uBAAU,EAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,CAAA;AAAA,EAC1D,MAAA,EAAQ,MAAM,OAAO,qBAAU,EAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,CAAA;AAAA,EAC1D,UAAA,EAAY,MAAM,OAAO,2BAAc,EAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,eAAe,CAAA;AAAA,EACtE,QAAA,EAAU,MAAM,OAAO,yBAAY,EAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,aAAa;AAClE","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/brands/index.ts"],"names":[],"mappings":";;;AAkCO,IAAM,MAAA,GAAS;AAAA,EACpB,QAAA,EAAU,MAAM,OAAO,uBAAY,EAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,aAAa,CAAA;AAAA,EAChE,IAAA,EAAM,MAAM,OAAO,mBAAQ,EAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,CAAA;AAAA,EACpD,OAAA,EAAS,MAAM,OAAO,wBAAW,EAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,YAAY,CAAA;AAAA,EAC7D,mBAAA,EAAqB,MACnB,OAAO,kCAAqB,EAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,qBAAqB,CAAA;AAAA,EACnE,MAAA,EAAQ,MAAM,OAAO,uBAAU,EAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,CAAA;AAAA,EAC1D,MAAA,EAAQ,MAAM,OAAO,qBAAU,EAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,CAAA;AAAA,EAC1D,UAAA,EAAY,MAAM,OAAO,2BAAc,EAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,eAAe,CAAA;AAAA,EACtE,QAAA,EAAU,MAAM,OAAO,yBAAY,EAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,aAAa;AAClE","file":"chunk-AWSSWNJY.cjs","sourcesContent":["/**\n * @mieweb/ui Brand System\n *\n * Export all brand-related types, utilities, and configurations.\n */\n\n// Types and utilities\nexport type {\n BrandConfig,\n BrandColors,\n BrandTypography,\n BrandBorderRadius,\n BrandBoxShadow,\n ColorScale,\n SemanticColors,\n} from './types';\n\nexport {\n generateBrandCSS,\n generateTailwindTheme,\n createBrandPreset,\n} from './types';\n\n// Brand configurations\nexport { bluehiveBrand } from './bluehive';\nexport { ccmeBrand } from './ccme';\nexport { defaultBrand } from './default';\nexport { enterpriseHealthBrand } from './enterprise-health';\nexport { miewebBrand } from './mieweb';\nexport { ozwellBrand } from './ozwell';\nexport { wagglelineBrand } from './waggleline';\nexport { webchartBrand } from './webchart';\n\n// All brands for iteration\nexport const brands = {\n bluehive: () => import('./bluehive').then((m) => m.bluehiveBrand),\n ccme: () => import('./ccme').then((m) => m.ccmeBrand),\n default: () => import('./default').then((m) => m.defaultBrand),\n 'enterprise-health': () =>\n import('./enterprise-health').then((m) => m.enterpriseHealthBrand),\n mieweb: () => import('./mieweb').then((m) => m.miewebBrand),\n ozwell: () => import('./ozwell').then((m) => m.ozwellBrand),\n waggleline: () => import('./waggleline').then((m) => m.wagglelineBrand),\n webchart: () => import('./webchart').then((m) => m.webchartBrand),\n} as const;\n"]}
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkHIYQ3M5V_cjs = require('./chunk-HIYQ3M5V.cjs');
|
|
4
|
+
var chunkS5RVSXDV_cjs = require('./chunk-S5RVSXDV.cjs');
|
|
5
|
+
var React = require('react');
|
|
6
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
7
|
+
|
|
8
|
+
function _interopNamespace(e) {
|
|
9
|
+
if (e && e.__esModule) return e;
|
|
10
|
+
var n = Object.create(null);
|
|
11
|
+
if (e) {
|
|
12
|
+
Object.keys(e).forEach(function (k) {
|
|
13
|
+
if (k !== 'default') {
|
|
14
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
15
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
get: function () { return e[k]; }
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
n.default = e;
|
|
23
|
+
return Object.freeze(n);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
27
|
+
|
|
28
|
+
var onDeviceTranscribe = async (audio, signal) => {
|
|
29
|
+
const { transcribeBlob } = await import('./whisperTranscribe-AV752TZI.cjs');
|
|
30
|
+
if (signal.aborted) throw new Error("Dictation cancelled");
|
|
31
|
+
return transcribeBlob(audio);
|
|
32
|
+
};
|
|
33
|
+
function toError(value) {
|
|
34
|
+
if (value instanceof Error) return value;
|
|
35
|
+
if (value && typeof value === "object" && "name" in value && "message" in value)
|
|
36
|
+
return value;
|
|
37
|
+
return new Error(String(value));
|
|
38
|
+
}
|
|
39
|
+
function liveAudio(stream) {
|
|
40
|
+
return stream?.getAudioTracks().some((track) => track.readyState === "live") ? stream : null;
|
|
41
|
+
}
|
|
42
|
+
function useDictation({
|
|
43
|
+
onText,
|
|
44
|
+
transcribe,
|
|
45
|
+
onError,
|
|
46
|
+
maxDurationSeconds = 300,
|
|
47
|
+
getStream
|
|
48
|
+
}) {
|
|
49
|
+
const [status, setStatus] = React__namespace.useState("idle");
|
|
50
|
+
const [error, setError] = React__namespace.useState(null);
|
|
51
|
+
const [elapsedMs, setElapsedMs] = React__namespace.useState(0);
|
|
52
|
+
const callbacksRef = React__namespace.useRef({ onText, onError, transcribe, getStream });
|
|
53
|
+
callbacksRef.current = { onText, onError, transcribe, getStream };
|
|
54
|
+
const maxMsRef = React__namespace.useRef(maxDurationSeconds * 1e3);
|
|
55
|
+
maxMsRef.current = maxDurationSeconds * 1e3;
|
|
56
|
+
const sessionRef = React__namespace.useRef(0);
|
|
57
|
+
const busyRef = React__namespace.useRef(false);
|
|
58
|
+
const mountedRef = React__namespace.useRef(true);
|
|
59
|
+
const streamRef = React__namespace.useRef(null);
|
|
60
|
+
const recorderRef = React__namespace.useRef(null);
|
|
61
|
+
const timerRef = React__namespace.useRef(null);
|
|
62
|
+
const abortRef = React__namespace.useRef(null);
|
|
63
|
+
const releaseMic = React__namespace.useCallback(() => {
|
|
64
|
+
if (timerRef.current) clearInterval(timerRef.current);
|
|
65
|
+
timerRef.current = null;
|
|
66
|
+
streamRef.current?.getTracks().forEach((track) => track.stop());
|
|
67
|
+
streamRef.current = null;
|
|
68
|
+
}, []);
|
|
69
|
+
const fail = React__namespace.useCallback(
|
|
70
|
+
(err) => {
|
|
71
|
+
releaseMic();
|
|
72
|
+
recorderRef.current = null;
|
|
73
|
+
busyRef.current = false;
|
|
74
|
+
const e = toError(err);
|
|
75
|
+
if (mountedRef.current) {
|
|
76
|
+
setError(e);
|
|
77
|
+
setStatus("error");
|
|
78
|
+
}
|
|
79
|
+
callbacksRef.current.onError?.(e);
|
|
80
|
+
},
|
|
81
|
+
[releaseMic]
|
|
82
|
+
);
|
|
83
|
+
const finish = React__namespace.useCallback(
|
|
84
|
+
async (session, chunks, mimeType) => {
|
|
85
|
+
if (session !== sessionRef.current) return;
|
|
86
|
+
releaseMic();
|
|
87
|
+
recorderRef.current = null;
|
|
88
|
+
const audio = new Blob(chunks, { type: mimeType });
|
|
89
|
+
if (audio.size === 0) {
|
|
90
|
+
busyRef.current = false;
|
|
91
|
+
if (mountedRef.current) setStatus("idle");
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const controller = new AbortController();
|
|
95
|
+
abortRef.current = controller;
|
|
96
|
+
if (mountedRef.current) setStatus("transcribing");
|
|
97
|
+
try {
|
|
98
|
+
const run = callbacksRef.current.transcribe ?? onDeviceTranscribe;
|
|
99
|
+
const text = (await run(audio, controller.signal)).trim();
|
|
100
|
+
if (session !== sessionRef.current || controller.signal.aborted) return;
|
|
101
|
+
busyRef.current = false;
|
|
102
|
+
abortRef.current = null;
|
|
103
|
+
if (mountedRef.current) setStatus("idle");
|
|
104
|
+
if (text) callbacksRef.current.onText(text);
|
|
105
|
+
} catch (err) {
|
|
106
|
+
if (session !== sessionRef.current || controller.signal.aborted) return;
|
|
107
|
+
abortRef.current = null;
|
|
108
|
+
fail(err);
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
[releaseMic, fail]
|
|
112
|
+
);
|
|
113
|
+
const cancel = React__namespace.useCallback(() => {
|
|
114
|
+
sessionRef.current += 1;
|
|
115
|
+
abortRef.current?.abort();
|
|
116
|
+
abortRef.current = null;
|
|
117
|
+
const recorder = recorderRef.current;
|
|
118
|
+
recorderRef.current = null;
|
|
119
|
+
if (recorder && recorder.state !== "inactive") recorder.stop();
|
|
120
|
+
releaseMic();
|
|
121
|
+
busyRef.current = false;
|
|
122
|
+
if (mountedRef.current) {
|
|
123
|
+
setStatus("idle");
|
|
124
|
+
setError(null);
|
|
125
|
+
setElapsedMs(0);
|
|
126
|
+
}
|
|
127
|
+
}, [releaseMic]);
|
|
128
|
+
const stop = React__namespace.useCallback(() => {
|
|
129
|
+
const recorder = recorderRef.current;
|
|
130
|
+
if (recorder) {
|
|
131
|
+
if (recorder.state !== "inactive") recorder.stop();
|
|
132
|
+
} else if (busyRef.current && !abortRef.current) {
|
|
133
|
+
cancel();
|
|
134
|
+
}
|
|
135
|
+
}, [cancel]);
|
|
136
|
+
const start = React__namespace.useCallback(async () => {
|
|
137
|
+
if (busyRef.current) return;
|
|
138
|
+
busyRef.current = true;
|
|
139
|
+
const session = ++sessionRef.current;
|
|
140
|
+
setStatus("idle");
|
|
141
|
+
setError(null);
|
|
142
|
+
setElapsedMs(0);
|
|
143
|
+
let shared;
|
|
144
|
+
try {
|
|
145
|
+
shared = liveAudio(callbacksRef.current.getStream?.());
|
|
146
|
+
} catch (err) {
|
|
147
|
+
fail(err);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (typeof MediaRecorder === "undefined" || !shared && (typeof navigator === "undefined" || !navigator.mediaDevices?.getUserMedia)) {
|
|
151
|
+
fail(new Error("Microphone is not available in this context"));
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
let stream;
|
|
155
|
+
if (shared) {
|
|
156
|
+
stream = shared;
|
|
157
|
+
} else {
|
|
158
|
+
try {
|
|
159
|
+
stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
160
|
+
} catch (err) {
|
|
161
|
+
if (session === sessionRef.current) fail(err);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (session !== sessionRef.current) {
|
|
165
|
+
stream.getTracks().forEach((track) => track.stop());
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
streamRef.current = stream;
|
|
169
|
+
}
|
|
170
|
+
let recorder;
|
|
171
|
+
try {
|
|
172
|
+
recorder = new MediaRecorder(stream);
|
|
173
|
+
} catch (err) {
|
|
174
|
+
fail(err);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
const chunks = [];
|
|
178
|
+
recorder.ondataavailable = (e) => {
|
|
179
|
+
if (e.data.size > 0) chunks.push(e.data);
|
|
180
|
+
};
|
|
181
|
+
recorder.onstop = () => {
|
|
182
|
+
void finish(session, chunks, recorder.mimeType || "audio/webm");
|
|
183
|
+
};
|
|
184
|
+
recorder.onerror = (e) => {
|
|
185
|
+
if (session !== sessionRef.current) return;
|
|
186
|
+
sessionRef.current += 1;
|
|
187
|
+
recorderRef.current = null;
|
|
188
|
+
fail(e.error ?? e);
|
|
189
|
+
};
|
|
190
|
+
if (!shared) {
|
|
191
|
+
stream.getAudioTracks().forEach((track) => {
|
|
192
|
+
track.addEventListener("ended", () => {
|
|
193
|
+
if (recorderRef.current === recorder && recorder.state !== "inactive")
|
|
194
|
+
recorder.stop();
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
recorderRef.current = recorder;
|
|
199
|
+
try {
|
|
200
|
+
recorder.start();
|
|
201
|
+
} catch (err) {
|
|
202
|
+
recorderRef.current = null;
|
|
203
|
+
fail(err);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
setStatus("recording");
|
|
207
|
+
const startedAt = Date.now();
|
|
208
|
+
timerRef.current = setInterval(() => {
|
|
209
|
+
const elapsed = Date.now() - startedAt;
|
|
210
|
+
setElapsedMs(elapsed);
|
|
211
|
+
if (maxMsRef.current > 0 && elapsed >= maxMsRef.current) {
|
|
212
|
+
if (recorder.state !== "inactive") recorder.stop();
|
|
213
|
+
}
|
|
214
|
+
}, 250);
|
|
215
|
+
}, [fail, finish]);
|
|
216
|
+
React__namespace.useEffect(() => {
|
|
217
|
+
mountedRef.current = true;
|
|
218
|
+
return () => {
|
|
219
|
+
mountedRef.current = false;
|
|
220
|
+
cancel();
|
|
221
|
+
};
|
|
222
|
+
}, [cancel]);
|
|
223
|
+
return { status, error, elapsedMs, start, stop, cancel };
|
|
224
|
+
}
|
|
225
|
+
var defaultDictationLabels = {
|
|
226
|
+
start: "Start dictation",
|
|
227
|
+
stop: "Stop dictation",
|
|
228
|
+
listening: "Listening\u2026",
|
|
229
|
+
transcribing: "Transcribing\u2026",
|
|
230
|
+
error: "Dictation failed. Try again.",
|
|
231
|
+
micBlocked: "Microphone access is blocked."
|
|
232
|
+
};
|
|
233
|
+
var buttonState = {
|
|
234
|
+
idle: "idle",
|
|
235
|
+
recording: "recording",
|
|
236
|
+
transcribing: "processing",
|
|
237
|
+
error: "error"
|
|
238
|
+
};
|
|
239
|
+
var DictationButton = React__namespace.forwardRef(
|
|
240
|
+
({
|
|
241
|
+
onText,
|
|
242
|
+
transcribe,
|
|
243
|
+
onError,
|
|
244
|
+
maxDurationSeconds,
|
|
245
|
+
getStream,
|
|
246
|
+
disabled = false,
|
|
247
|
+
size = "sm",
|
|
248
|
+
variant = "ghost",
|
|
249
|
+
showDuration = false,
|
|
250
|
+
showStatus = false,
|
|
251
|
+
labels: labelOverrides,
|
|
252
|
+
className,
|
|
253
|
+
handleRef,
|
|
254
|
+
...rest
|
|
255
|
+
}, ref) => {
|
|
256
|
+
const labels = { ...defaultDictationLabels, ...labelOverrides };
|
|
257
|
+
const { status, error, elapsedMs, start, stop, cancel } = useDictation({
|
|
258
|
+
onText,
|
|
259
|
+
transcribe,
|
|
260
|
+
onError,
|
|
261
|
+
maxDurationSeconds,
|
|
262
|
+
getStream
|
|
263
|
+
});
|
|
264
|
+
React__namespace.useEffect(() => {
|
|
265
|
+
if (disabled) cancel();
|
|
266
|
+
}, [disabled, cancel]);
|
|
267
|
+
React__namespace.useImperativeHandle(
|
|
268
|
+
handleRef,
|
|
269
|
+
() => ({
|
|
270
|
+
start: () => {
|
|
271
|
+
if (!disabled) void start();
|
|
272
|
+
},
|
|
273
|
+
stop,
|
|
274
|
+
cancel
|
|
275
|
+
}),
|
|
276
|
+
[disabled, start, stop, cancel]
|
|
277
|
+
);
|
|
278
|
+
React__namespace.useEffect(() => {
|
|
279
|
+
if (status !== "recording") return;
|
|
280
|
+
const onEscape = (e) => {
|
|
281
|
+
if (e.key !== "Escape" || e.defaultPrevented) return;
|
|
282
|
+
e.preventDefault();
|
|
283
|
+
cancel();
|
|
284
|
+
};
|
|
285
|
+
document.addEventListener("keydown", onEscape);
|
|
286
|
+
return () => document.removeEventListener("keydown", onEscape);
|
|
287
|
+
}, [status, cancel]);
|
|
288
|
+
const errorText = error?.name === "NotAllowedError" ? labels.micBlocked : labels.error;
|
|
289
|
+
const statusText = status === "recording" ? labels.listening : status === "transcribing" ? labels.transcribing : status === "error" ? errorText : "";
|
|
290
|
+
const ariaLabel = status === "recording" ? labels.stop : status === "transcribing" ? labels.transcribing : status === "error" ? errorText : labels.start;
|
|
291
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
292
|
+
"div",
|
|
293
|
+
{
|
|
294
|
+
"data-slot": "dictation-button",
|
|
295
|
+
className: chunkS5RVSXDV_cjs.cn("inline-flex items-center gap-2", className),
|
|
296
|
+
children: [
|
|
297
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
298
|
+
chunkHIYQ3M5V_cjs.RecordButton,
|
|
299
|
+
{
|
|
300
|
+
...rest,
|
|
301
|
+
ref,
|
|
302
|
+
state: disabled ? "disabled" : buttonState[status],
|
|
303
|
+
disabled,
|
|
304
|
+
size,
|
|
305
|
+
variant,
|
|
306
|
+
"aria-label": ariaLabel,
|
|
307
|
+
onClick: () => {
|
|
308
|
+
if (status === "recording") stop();
|
|
309
|
+
else void start();
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
),
|
|
313
|
+
showDuration && status === "recording" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
314
|
+
"span",
|
|
315
|
+
{
|
|
316
|
+
"data-slot": "dictation-button-duration",
|
|
317
|
+
className: "text-destructive font-mono text-xs tabular-nums",
|
|
318
|
+
children: chunkHIYQ3M5V_cjs.formatDuration(elapsedMs / 1e3)
|
|
319
|
+
}
|
|
320
|
+
),
|
|
321
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
322
|
+
"span",
|
|
323
|
+
{
|
|
324
|
+
role: "status",
|
|
325
|
+
"data-slot": "dictation-button-status",
|
|
326
|
+
className: chunkS5RVSXDV_cjs.cn(
|
|
327
|
+
"text-xs",
|
|
328
|
+
status === "error" ? "text-destructive" : "text-muted-foreground",
|
|
329
|
+
!showStatus && "sr-only"
|
|
330
|
+
),
|
|
331
|
+
children: statusText
|
|
332
|
+
}
|
|
333
|
+
)
|
|
334
|
+
]
|
|
335
|
+
}
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
);
|
|
339
|
+
DictationButton.displayName = "DictationButton";
|
|
340
|
+
|
|
341
|
+
exports.DictationButton = DictationButton;
|
|
342
|
+
exports.defaultDictationLabels = defaultDictationLabels;
|
|
343
|
+
exports.useDictation = useDictation;
|
|
344
|
+
//# sourceMappingURL=chunk-BFVYM6IT.cjs.map
|
|
345
|
+
//# sourceMappingURL=chunk-BFVYM6IT.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/DictationButton/useDictation.ts","../src/components/DictationButton/DictationButton.tsx"],"names":["React","React2","jsxs","cn","jsx","RecordButton","formatDuration"],"mappings":"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","file":"chunk-BFVYM6IT.cjs","sourcesContent":["import * as React from 'react';\n\nexport type DictationStatus = 'idle' | 'recording' | 'transcribing' | 'error';\n\n/** Turns recorded audio into text. Reject to report an error; honor `signal` to support cancel. */\nexport type DictationTranscribe = (\n audio: Blob,\n signal: AbortSignal\n) => Promise<string>;\n\nexport interface UseDictationOptions {\n /** Called with the final, trimmed transcript. Not called for empty results or after cancel. */\n onText: (text: string) => void;\n /** Transcription provider. Defaults to on-device Whisper (audio never leaves the browser). */\n transcribe?: DictationTranscribe;\n /** Called with the underlying error (permission denied, provider failure, …). */\n onError?: (error: Error) => void;\n /** Auto-stop after this many seconds. `0` disables the limit. Default 300. */\n maxDurationSeconds?: number;\n /**\n * Reuse a mic stream the host already holds (e.g. a wake-word listener) instead of opening one.\n * Its tracks are never stopped by the hook. Falls back to `getUserMedia` when it returns no live audio.\n */\n getStream?: () => MediaStream | null | undefined;\n}\n\nexport interface UseDictationResult {\n status: DictationStatus;\n error: Error | null;\n /** Milliseconds recorded so far in the current session. */\n elapsedMs: number;\n start: () => Promise<void>;\n /** Stop recording and transcribe. */\n stop: () => void;\n /** Discard the recording or in-flight transcription. `onText` will not fire. */\n cancel: () => void;\n}\n\nconst onDeviceTranscribe: DictationTranscribe = async (audio, signal) => {\n // Loaded lazily so hosts using a server provider never pull in Whisper.\n const { transcribeBlob } = await import('../AI/whisperTranscribe');\n // The shared worker cannot stop a running decode, so cancel only discards its result.\n if (signal.aborted) throw new Error('Dictation cancelled');\n return transcribeBlob(audio);\n};\n\nfunction toError(value: unknown): Error {\n if (value instanceof Error) return value;\n // DOMException (e.g. NotAllowedError) is not an Error subclass in every runtime; keep its `name`.\n if (\n value &&\n typeof value === 'object' &&\n 'name' in value &&\n 'message' in value\n )\n return value as Error;\n return new Error(String(value));\n}\n\nfunction liveAudio(stream: MediaStream | null | undefined) {\n return stream?.getAudioTracks().some((track) => track.readyState === 'live')\n ? stream\n : null;\n}\n\n/**\n * Headless speech-to-text for a single speaker: record, then transcribe to editable text.\n * Owns the mic lifecycle; every async step is tied to a session id so stale results are dropped.\n */\nexport function useDictation({\n onText,\n transcribe,\n onError,\n maxDurationSeconds = 300,\n getStream,\n}: UseDictationOptions): UseDictationResult {\n const [status, setStatus] = React.useState<DictationStatus>('idle');\n const [error, setError] = React.useState<Error | null>(null);\n const [elapsedMs, setElapsedMs] = React.useState(0);\n\n const callbacksRef = React.useRef({ onText, onError, transcribe, getStream });\n callbacksRef.current = { onText, onError, transcribe, getStream };\n const maxMsRef = React.useRef(maxDurationSeconds * 1000);\n maxMsRef.current = maxDurationSeconds * 1000;\n\n const sessionRef = React.useRef(0);\n const busyRef = React.useRef(false);\n const mountedRef = React.useRef(true);\n // Only streams the hook opened; a host-shared stream is never stored here, so it is never stopped.\n const streamRef = React.useRef<MediaStream | null>(null);\n const recorderRef = React.useRef<MediaRecorder | null>(null);\n const timerRef = React.useRef<ReturnType<typeof setInterval> | null>(null);\n const abortRef = React.useRef<AbortController | null>(null);\n\n const releaseMic = React.useCallback(() => {\n if (timerRef.current) clearInterval(timerRef.current);\n timerRef.current = null;\n streamRef.current?.getTracks().forEach((track) => track.stop());\n streamRef.current = null;\n }, []);\n\n const fail = React.useCallback(\n (err: unknown) => {\n releaseMic();\n recorderRef.current = null;\n busyRef.current = false;\n const e = toError(err);\n if (mountedRef.current) {\n setError(e);\n setStatus('error');\n }\n callbacksRef.current.onError?.(e);\n },\n [releaseMic]\n );\n\n const finish = React.useCallback(\n async (session: number, chunks: Blob[], mimeType: string) => {\n // A stale session must not touch refs that may already belong to a new one.\n if (session !== sessionRef.current) return;\n releaseMic();\n recorderRef.current = null;\n\n const audio = new Blob(chunks, { type: mimeType });\n if (audio.size === 0) {\n busyRef.current = false;\n if (mountedRef.current) setStatus('idle');\n return;\n }\n\n const controller = new AbortController();\n abortRef.current = controller;\n if (mountedRef.current) setStatus('transcribing');\n try {\n const run = callbacksRef.current.transcribe ?? onDeviceTranscribe;\n const text = (await run(audio, controller.signal)).trim();\n if (session !== sessionRef.current || controller.signal.aborted) return;\n busyRef.current = false;\n abortRef.current = null;\n if (mountedRef.current) setStatus('idle');\n if (text) callbacksRef.current.onText(text);\n } catch (err) {\n if (session !== sessionRef.current || controller.signal.aborted) return;\n abortRef.current = null;\n fail(err);\n }\n },\n [releaseMic, fail]\n );\n\n const cancel = React.useCallback(() => {\n sessionRef.current += 1;\n abortRef.current?.abort();\n abortRef.current = null;\n const recorder = recorderRef.current;\n recorderRef.current = null;\n if (recorder && recorder.state !== 'inactive') recorder.stop();\n releaseMic();\n busyRef.current = false;\n if (mountedRef.current) {\n setStatus('idle');\n setError(null);\n setElapsedMs(0);\n }\n }, [releaseMic]);\n\n const stop = React.useCallback(() => {\n const recorder = recorderRef.current;\n if (recorder) {\n // Already inactive means onstop is queued; cancelling here would drop the take.\n if (recorder.state !== 'inactive') recorder.stop();\n } else if (busyRef.current && !abortRef.current) {\n // Still waiting on the permission prompt: nothing recorded yet.\n cancel();\n }\n }, [cancel]);\n\n const start = React.useCallback(async () => {\n if (busyRef.current) return;\n busyRef.current = true;\n const session = ++sessionRef.current;\n setStatus('idle');\n setError(null);\n setElapsedMs(0);\n\n let shared: MediaStream | null;\n try {\n shared = liveAudio(callbacksRef.current.getStream?.());\n } catch (err) {\n fail(err);\n return;\n }\n if (\n typeof MediaRecorder === 'undefined' ||\n (!shared &&\n (typeof navigator === 'undefined' ||\n !navigator.mediaDevices?.getUserMedia))\n ) {\n fail(new Error('Microphone is not available in this context'));\n return;\n }\n\n let stream: MediaStream;\n if (shared) {\n stream = shared;\n } else {\n try {\n stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n } catch (err) {\n if (session === sessionRef.current) fail(err);\n return;\n }\n if (session !== sessionRef.current) {\n // Cancelled or unmounted while the permission prompt was open.\n stream.getTracks().forEach((track) => track.stop());\n return;\n }\n streamRef.current = stream;\n }\n\n let recorder: MediaRecorder;\n try {\n recorder = new MediaRecorder(stream);\n } catch (err) {\n fail(err);\n return;\n }\n\n const chunks: Blob[] = [];\n recorder.ondataavailable = (e) => {\n if (e.data.size > 0) chunks.push(e.data);\n };\n recorder.onstop = () => {\n void finish(session, chunks, recorder.mimeType || 'audio/webm');\n };\n recorder.onerror = (e) => {\n if (session !== sessionRef.current) return;\n sessionRef.current += 1;\n recorderRef.current = null;\n fail((e as Event & { error?: unknown }).error ?? e);\n };\n // Shared tracks live longer than one take; MediaRecorder stops by itself if they end.\n if (!shared) {\n stream.getAudioTracks().forEach((track) => {\n track.addEventListener('ended', () => {\n if (recorderRef.current === recorder && recorder.state !== 'inactive')\n recorder.stop();\n });\n });\n }\n\n recorderRef.current = recorder;\n try {\n recorder.start();\n } catch (err) {\n recorderRef.current = null;\n fail(err);\n return;\n }\n setStatus('recording');\n\n const startedAt = Date.now();\n timerRef.current = setInterval(() => {\n const elapsed = Date.now() - startedAt;\n setElapsedMs(elapsed);\n if (maxMsRef.current > 0 && elapsed >= maxMsRef.current) {\n if (recorder.state !== 'inactive') recorder.stop();\n }\n }, 250);\n }, [fail, finish]);\n\n React.useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n cancel();\n };\n }, [cancel]);\n\n return { status, error, elapsedMs, start, stop, cancel };\n}\n","import * as React from 'react';\nimport {\n RecordButton,\n formatDuration,\n type RecordButtonSize,\n type RecordButtonState,\n type RecordButtonVariant,\n} from '../RecordButton';\nimport { cn } from '../../utils/cn';\nimport {\n useDictation,\n type DictationStatus,\n type UseDictationOptions,\n} from './useDictation';\n\nexport interface DictationButtonLabels {\n start: string;\n stop: string;\n listening: string;\n transcribing: string;\n error: string;\n micBlocked: string;\n}\n\nexport const defaultDictationLabels: DictationButtonLabels = {\n start: 'Start dictation',\n stop: 'Stop dictation',\n listening: 'Listening…',\n transcribing: 'Transcribing…',\n error: 'Dictation failed. Try again.',\n micBlocked: 'Microphone access is blocked.',\n};\n\n/** Drive dictation from code, e.g. when a wake word fires. */\nexport interface DictationButtonHandle {\n /** Does nothing while `disabled` or while a take is already in progress. */\n start: () => void;\n /** Stop recording and transcribe. */\n stop: () => void;\n /** Discard the take; `onText` will not fire. */\n cancel: () => void;\n}\n\nexport interface DictationButtonProps\n extends\n UseDictationOptions,\n Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n // The ARIA attributes follow the dictation state; customise text through `labels`.\n | 'children'\n | 'onClick'\n | 'onError'\n | 'disabled'\n | 'className'\n | 'aria-label'\n | 'aria-pressed'\n | 'aria-busy'\n > {\n disabled?: boolean;\n size?: RecordButtonSize;\n variant?: RecordButtonVariant;\n /** Show `m:ss` while recording. */\n showDuration?: boolean;\n /** Show the listening/transcribing/error caption. It is always announced to screen readers. */\n showStatus?: boolean;\n /** Override any user-facing string (i18n). */\n labels?: Partial<DictationButtonLabels>;\n className?: string;\n /** Start, stop or cancel from code. `ref` stays the `<button>`. */\n handleRef?: React.Ref<DictationButtonHandle>;\n}\n\nconst buttonState: Record<DictationStatus, RecordButtonState> = {\n idle: 'idle',\n recording: 'recording',\n transcribing: 'processing',\n error: 'error',\n};\n\n/**\n * Mic button that turns speech into editable text via `onText`. Never sends anything itself.\n * Escape while recording discards the take.\n */\nexport const DictationButton = React.forwardRef<\n HTMLButtonElement,\n DictationButtonProps\n>(\n (\n {\n onText,\n transcribe,\n onError,\n maxDurationSeconds,\n getStream,\n disabled = false,\n size = 'sm',\n variant = 'ghost',\n showDuration = false,\n showStatus = false,\n labels: labelOverrides,\n className,\n handleRef,\n ...rest\n },\n ref\n ) => {\n const labels = { ...defaultDictationLabels, ...labelOverrides };\n const { status, error, elapsedMs, start, stop, cancel } = useDictation({\n onText,\n transcribe,\n onError,\n maxDurationSeconds,\n getStream,\n });\n\n // Covers a pending permission prompt (status still idle) and transcribing, not just recording.\n React.useEffect(() => {\n if (disabled) cancel();\n }, [disabled, cancel]);\n\n React.useImperativeHandle(\n handleRef,\n () => ({\n start: () => {\n if (!disabled) void start();\n },\n stop,\n cancel,\n }),\n [disabled, start, stop, cancel]\n );\n\n // Document-level so Escape works while focus stays in the composer.\n React.useEffect(() => {\n if (status !== 'recording') return;\n const onEscape = (e: KeyboardEvent) => {\n if (e.key !== 'Escape' || e.defaultPrevented) return;\n e.preventDefault();\n cancel();\n };\n document.addEventListener('keydown', onEscape);\n return () => document.removeEventListener('keydown', onEscape);\n }, [status, cancel]);\n\n const errorText =\n error?.name === 'NotAllowedError' ? labels.micBlocked : labels.error;\n const statusText =\n status === 'recording'\n ? labels.listening\n : status === 'transcribing'\n ? labels.transcribing\n : status === 'error'\n ? errorText\n : '';\n const ariaLabel =\n status === 'recording'\n ? labels.stop\n : status === 'transcribing'\n ? labels.transcribing\n : status === 'error'\n ? errorText\n : labels.start;\n\n return (\n <div\n data-slot=\"dictation-button\"\n className={cn('inline-flex items-center gap-2', className)}\n >\n <RecordButton\n {...rest}\n ref={ref}\n state={disabled ? 'disabled' : buttonState[status]}\n disabled={disabled}\n size={size}\n variant={variant}\n aria-label={ariaLabel}\n onClick={() => {\n if (status === 'recording') stop();\n else void start();\n }}\n />\n {showDuration && status === 'recording' && (\n <span\n data-slot=\"dictation-button-duration\"\n className=\"text-destructive font-mono text-xs tabular-nums\"\n >\n {formatDuration(elapsedMs / 1000)}\n </span>\n )}\n <span\n role=\"status\"\n data-slot=\"dictation-button-status\"\n className={cn(\n 'text-xs',\n status === 'error' ? 'text-destructive' : 'text-muted-foreground',\n !showStatus && 'sr-only'\n )}\n >\n {statusText}\n </span>\n </div>\n );\n }\n);\n\nDictationButton.displayName = 'DictationButton';\n"]}
|