@epicbagel/saas-kit 1.7.0 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -1
- package/THIRD_PARTY_NOTICES.md +14 -0
- package/dist/chunk-2BSFYU22.cjs +71 -0
- package/dist/chunk-5OF6D3GH.js +158 -0
- package/dist/chunk-7QTFYEPE.cjs +153 -0
- package/dist/{chunk-GTVSRRE3.cjs → chunk-BGCNGYPL.cjs} +2 -2
- package/dist/{chunk-QTWJQQDH.cjs → chunk-FBVZRRA4.cjs} +6 -6
- package/dist/chunk-GJ7S3L6R.js +71 -0
- package/dist/chunk-HLAHOVEI.js +412 -0
- package/dist/{chunk-F3B4M6DU.js → chunk-HTPPNW74.js} +1 -1
- package/dist/chunk-KQBXAQAY.cjs +221 -0
- package/dist/{chunk-JN6JOSZG.js → chunk-LQPJGZIE.js} +7 -7
- package/dist/chunk-NKWHDI4C.cjs +158 -0
- package/dist/chunk-T3XMHWYV.js +221 -0
- package/dist/chunk-UOVA4YKW.js +153 -0
- package/dist/chunk-ZZ7ICQR2.cjs +412 -0
- package/dist/hooks/use-agent-audio-visualizer-bar.cjs +8 -0
- package/dist/hooks/use-agent-audio-visualizer-bar.d.cts +4 -0
- package/dist/hooks/use-agent-audio-visualizer-bar.d.ts +4 -0
- package/dist/hooks/use-agent-audio-visualizer-bar.js +8 -0
- package/dist/hooks/use-dictation.cjs +10 -0
- package/dist/hooks/use-dictation.d.cts +61 -0
- package/dist/hooks/use-dictation.d.ts +61 -0
- package/dist/hooks/use-dictation.js +10 -0
- package/dist/primitives/activity-feed.cjs +3 -3
- package/dist/primitives/activity-feed.js +4 -4
- package/dist/primitives/agent-audio-visualizer-bar.cjs +16 -0
- package/dist/primitives/agent-audio-visualizer-bar.d.cts +75 -0
- package/dist/primitives/agent-audio-visualizer-bar.d.ts +75 -0
- package/dist/primitives/agent-audio-visualizer-bar.js +16 -0
- package/dist/primitives/alert.d.cts +1 -1
- package/dist/primitives/alert.d.ts +1 -1
- package/dist/primitives/archive-confirmation-dialog.cjs +2 -2
- package/dist/primitives/archive-confirmation-dialog.js +3 -3
- package/dist/primitives/attachment.d.cts +1 -1
- package/dist/primitives/attachment.d.ts +1 -1
- package/dist/primitives/badge.d.cts +1 -1
- package/dist/primitives/badge.d.ts +1 -1
- package/dist/primitives/board-view.cjs +6 -6
- package/dist/primitives/board-view.js +5 -5
- package/dist/primitives/bubble.d.cts +1 -1
- package/dist/primitives/bubble.d.ts +1 -1
- package/dist/primitives/button.d.cts +2 -2
- package/dist/primitives/button.d.ts +2 -2
- package/dist/primitives/chat.cjs +59 -28
- package/dist/primitives/chat.d.cts +8 -3
- package/dist/primitives/chat.d.ts +8 -3
- package/dist/primitives/chat.js +56 -25
- package/dist/primitives/code-block.cjs +4 -4
- package/dist/primitives/code-block.js +3 -3
- package/dist/primitives/connection.cjs +6 -6
- package/dist/primitives/connection.js +7 -7
- package/dist/primitives/copy-button.cjs +3 -3
- package/dist/primitives/copy-button.js +2 -2
- package/dist/primitives/dictation-provider.cjs +8 -0
- package/dist/primitives/dictation-provider.d.cts +2 -0
- package/dist/primitives/dictation-provider.d.ts +2 -0
- package/dist/primitives/dictation-provider.js +8 -0
- package/dist/primitives/editable-list.cjs +1 -1
- package/dist/primitives/editable-list.js +1 -1
- package/dist/primitives/file-dropzone.cjs +3 -3
- package/dist/primitives/file-dropzone.js +2 -2
- package/dist/primitives/file-preview.cjs +6 -6
- package/dist/primitives/file-preview.js +5 -5
- package/dist/primitives/filter-bar.cjs +4 -4
- package/dist/primitives/filter-bar.js +3 -3
- package/dist/primitives/input-group.d.cts +1 -1
- package/dist/primitives/input-group.d.ts +1 -1
- package/dist/primitives/item.d.cts +2 -2
- package/dist/primitives/item.d.ts +2 -2
- package/dist/primitives/resource-list.cjs +6 -6
- package/dist/primitives/resource-list.js +5 -5
- package/dist/primitives/section-header.d.cts +1 -1
- package/dist/primitives/section-header.d.ts +1 -1
- package/dist/primitives/section.cjs +2 -2
- package/dist/primitives/section.js +3 -3
- package/dist/primitives/sheet.d.cts +1 -1
- package/dist/primitives/sheet.d.ts +1 -1
- package/dist/primitives/switch-field.cjs +2 -2
- package/dist/primitives/switch-field.js +3 -3
- package/dist/primitives/theme-selector.cjs +3 -3
- package/dist/primitives/theme-selector.js +4 -4
- package/dist/primitives/toggle-group.d.cts +2 -2
- package/dist/primitives/toggle-group.d.ts +2 -2
- package/dist/primitives/toggle.d.cts +2 -2
- package/dist/primitives/toggle.d.ts +2 -2
- package/dist/primitives/voice-dictation-button.cjs +5 -2
- package/dist/primitives/voice-dictation-button.d.cts +5 -9
- package/dist/primitives/voice-dictation-button.d.ts +5 -9
- package/dist/primitives/voice-dictation-button.js +4 -1
- package/dist/primitives/voice-session-controls.cjs +12 -0
- package/dist/primitives/voice-session-controls.d.cts +31 -0
- package/dist/primitives/voice-session-controls.d.ts +31 -0
- package/dist/primitives/voice-session-controls.js +12 -0
- package/package.json +51 -1
- package/dist/chunk-LKPM6DQP.cjs +0 -244
- package/dist/chunk-TI57GAQP.js +0 -244
- package/dist/{chunk-HREEZUKL.js → chunk-DILYV4FI.js} +3 -3
- package/dist/{chunk-MU4F3DSW.cjs → chunk-FARCLWLU.cjs} +2 -2
- package/dist/{chunk-CRTH5GJ5.cjs → chunk-MW67PHAQ.cjs} +3 -3
- package/dist/{chunk-KNKV25WS.js → chunk-UFFHGKI7.js} +3 -3
- package/dist/{chunk-HBRVOGLA.js → chunk-WHDHUYS6.js} +3 -3
- package/dist/{chunk-Z3JJSNR5.cjs → chunk-ZLEM2SAU.cjs} +2 -2
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
"use client";
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunkKQBXAQAYcjs = require('../chunk-KQBXAQAY.cjs');
|
|
6
|
+
require('../chunk-NKWHDI4C.cjs');
|
|
6
7
|
require('../chunk-JDEXZGIY.cjs');
|
|
7
8
|
require('../chunk-KWLSBTB2.cjs');
|
|
9
|
+
require('../chunk-2BSFYU22.cjs');
|
|
10
|
+
require('../chunk-ZZ7ICQR2.cjs');
|
|
8
11
|
|
|
9
12
|
|
|
10
|
-
exports.VoiceDictationButton =
|
|
13
|
+
exports.VoiceDictationButton = _chunkKQBXAQAYcjs.VoiceDictationButton;
|
|
@@ -6,9 +6,9 @@ interface VoiceDictationButtonProps {
|
|
|
6
6
|
onCommit: (text: string) => void;
|
|
7
7
|
/** Fired if the user closes the overlay without committing. */
|
|
8
8
|
onCancel?: () => void;
|
|
9
|
-
/**
|
|
9
|
+
/** Title shown in the compact recorder. */
|
|
10
10
|
title?: ReactNode;
|
|
11
|
-
/**
|
|
11
|
+
/** Recording status label. Defaults to "Recording". */
|
|
12
12
|
caption?: string;
|
|
13
13
|
/** BCP-47 language tag. Defaults to "en-US". */
|
|
14
14
|
lang?: string;
|
|
@@ -28,13 +28,9 @@ interface VoiceDictationButtonProps {
|
|
|
28
28
|
shrink?: boolean;
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* focus on speaking.
|
|
35
|
-
*
|
|
36
|
-
* Sibling to `<VoiceInput>` which streams chunks inline. Use this when
|
|
37
|
-
* dictation should take over the screen instead of typing-into-an-input.
|
|
31
|
+
* Opens a compact portaled recorder. A fixed panel also works when its
|
|
32
|
+
* trigger is hidden or sits inside another dialog. Done finishes the take
|
|
33
|
+
* and commits its transcript once; Cancel discards it.
|
|
38
34
|
*/
|
|
39
35
|
declare function VoiceDictationButton({ onCommit, onCancel, title, caption, lang, continuous, className, size, showLabel, children, disabled, visibility, shrink, }: VoiceDictationButtonProps): react_jsx_runtime.JSX.Element | null;
|
|
40
36
|
|
|
@@ -6,9 +6,9 @@ interface VoiceDictationButtonProps {
|
|
|
6
6
|
onCommit: (text: string) => void;
|
|
7
7
|
/** Fired if the user closes the overlay without committing. */
|
|
8
8
|
onCancel?: () => void;
|
|
9
|
-
/**
|
|
9
|
+
/** Title shown in the compact recorder. */
|
|
10
10
|
title?: ReactNode;
|
|
11
|
-
/**
|
|
11
|
+
/** Recording status label. Defaults to "Recording". */
|
|
12
12
|
caption?: string;
|
|
13
13
|
/** BCP-47 language tag. Defaults to "en-US". */
|
|
14
14
|
lang?: string;
|
|
@@ -28,13 +28,9 @@ interface VoiceDictationButtonProps {
|
|
|
28
28
|
shrink?: boolean;
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* focus on speaking.
|
|
35
|
-
*
|
|
36
|
-
* Sibling to `<VoiceInput>` which streams chunks inline. Use this when
|
|
37
|
-
* dictation should take over the screen instead of typing-into-an-input.
|
|
31
|
+
* Opens a compact portaled recorder. A fixed panel also works when its
|
|
32
|
+
* trigger is hidden or sits inside another dialog. Done finishes the take
|
|
33
|
+
* and commits its transcript once; Cancel discards it.
|
|
38
34
|
*/
|
|
39
35
|
declare function VoiceDictationButton({ onCommit, onCancel, title, caption, lang, continuous, className, size, showLabel, children, disabled, visibility, shrink, }: VoiceDictationButtonProps): react_jsx_runtime.JSX.Element | null;
|
|
40
36
|
|
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
"use client";
|
|
3
3
|
import {
|
|
4
4
|
VoiceDictationButton
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-T3XMHWYV.js";
|
|
6
|
+
import "../chunk-5OF6D3GH.js";
|
|
6
7
|
import "../chunk-W326GKML.js";
|
|
7
8
|
import "../chunk-G6SRSWXB.js";
|
|
9
|
+
import "../chunk-GJ7S3L6R.js";
|
|
10
|
+
import "../chunk-HLAHOVEI.js";
|
|
8
11
|
export {
|
|
9
12
|
VoiceDictationButton
|
|
10
13
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
var _chunk7QTFYEPEcjs = require('../chunk-7QTFYEPE.cjs');
|
|
6
|
+
require('../chunk-NKWHDI4C.cjs');
|
|
7
|
+
require('../chunk-JDEXZGIY.cjs');
|
|
8
|
+
require('../chunk-KWLSBTB2.cjs');
|
|
9
|
+
require('../chunk-2BSFYU22.cjs');
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
exports.VoiceSessionControls = _chunk7QTFYEPEcjs.VoiceSessionControls;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
type VoiceSessionState = "disconnected" | "connecting" | "listening" | "thinking" | "speaking" | "reconnecting" | "error";
|
|
4
|
+
interface VoiceAudioLevelsSource {
|
|
5
|
+
subscribe: (listener: () => void) => () => void;
|
|
6
|
+
getSnapshot: () => number[];
|
|
7
|
+
}
|
|
8
|
+
interface VoiceSessionControlsProps {
|
|
9
|
+
/** The host owns the connection, audio tracks and their cleanup. */
|
|
10
|
+
state: VoiceSessionState;
|
|
11
|
+
onStart: () => void;
|
|
12
|
+
onEnd: () => void;
|
|
13
|
+
muted?: boolean;
|
|
14
|
+
onMutedChange: (muted: boolean) => void;
|
|
15
|
+
/** Prevent starting a new session; ending an active session stays available. */
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
error?: string | null;
|
|
18
|
+
/** The latest user utterance supplied by the host; never submits a message. */
|
|
19
|
+
transcript?: string;
|
|
20
|
+
/** Audio levels supplied by the host; no media connection is created by the kit. */
|
|
21
|
+
volumeBands?: number[];
|
|
22
|
+
/** Optional external audio store, so level changes only re-render these controls. */
|
|
23
|
+
audioLevels?: VoiceAudioLevelsSource;
|
|
24
|
+
labels?: Partial<Record<VoiceSessionState | "start" | "end" | "mute" | "unmute" | "muted" | "retry" | "endShort" | "muteShort" | "unmuteShort" | "transcriptPlaceholder", string>>;
|
|
25
|
+
size?: "icon" | "hero";
|
|
26
|
+
className?: string;
|
|
27
|
+
}
|
|
28
|
+
/** Transport-independent voice controls. The conversation stays visible while speaking. */
|
|
29
|
+
declare function VoiceSessionControls({ state, onStart, onEnd, muted, onMutedChange, disabled, error, transcript, volumeBands, audioLevels, labels, size, className, }: VoiceSessionControlsProps): react_jsx_runtime.JSX.Element;
|
|
30
|
+
|
|
31
|
+
export { type VoiceAudioLevelsSource, VoiceSessionControls, type VoiceSessionControlsProps, type VoiceSessionState };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
type VoiceSessionState = "disconnected" | "connecting" | "listening" | "thinking" | "speaking" | "reconnecting" | "error";
|
|
4
|
+
interface VoiceAudioLevelsSource {
|
|
5
|
+
subscribe: (listener: () => void) => () => void;
|
|
6
|
+
getSnapshot: () => number[];
|
|
7
|
+
}
|
|
8
|
+
interface VoiceSessionControlsProps {
|
|
9
|
+
/** The host owns the connection, audio tracks and their cleanup. */
|
|
10
|
+
state: VoiceSessionState;
|
|
11
|
+
onStart: () => void;
|
|
12
|
+
onEnd: () => void;
|
|
13
|
+
muted?: boolean;
|
|
14
|
+
onMutedChange: (muted: boolean) => void;
|
|
15
|
+
/** Prevent starting a new session; ending an active session stays available. */
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
error?: string | null;
|
|
18
|
+
/** The latest user utterance supplied by the host; never submits a message. */
|
|
19
|
+
transcript?: string;
|
|
20
|
+
/** Audio levels supplied by the host; no media connection is created by the kit. */
|
|
21
|
+
volumeBands?: number[];
|
|
22
|
+
/** Optional external audio store, so level changes only re-render these controls. */
|
|
23
|
+
audioLevels?: VoiceAudioLevelsSource;
|
|
24
|
+
labels?: Partial<Record<VoiceSessionState | "start" | "end" | "mute" | "unmute" | "muted" | "retry" | "endShort" | "muteShort" | "unmuteShort" | "transcriptPlaceholder", string>>;
|
|
25
|
+
size?: "icon" | "hero";
|
|
26
|
+
className?: string;
|
|
27
|
+
}
|
|
28
|
+
/** Transport-independent voice controls. The conversation stays visible while speaking. */
|
|
29
|
+
declare function VoiceSessionControls({ state, onStart, onEnd, muted, onMutedChange, disabled, error, transcript, volumeBands, audioLevels, labels, size, className, }: VoiceSessionControlsProps): react_jsx_runtime.JSX.Element;
|
|
30
|
+
|
|
31
|
+
export { type VoiceAudioLevelsSource, VoiceSessionControls, type VoiceSessionControlsProps, type VoiceSessionState };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
import {
|
|
4
|
+
VoiceSessionControls
|
|
5
|
+
} from "../chunk-UOVA4YKW.js";
|
|
6
|
+
import "../chunk-5OF6D3GH.js";
|
|
7
|
+
import "../chunk-W326GKML.js";
|
|
8
|
+
import "../chunk-G6SRSWXB.js";
|
|
9
|
+
import "../chunk-GJ7S3L6R.js";
|
|
10
|
+
export {
|
|
11
|
+
VoiceSessionControls
|
|
12
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@epicbagel/saas-kit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.0",
|
|
4
4
|
"description": "Accessible React primitives, layout components and design tokens for SaaS apps, built on Radix UI and Tailwind CSS v4.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -50,6 +50,16 @@
|
|
|
50
50
|
"default": "./dist/primitives/activity-log.cjs"
|
|
51
51
|
}
|
|
52
52
|
},
|
|
53
|
+
"./primitives/agent-audio-visualizer-bar": {
|
|
54
|
+
"import": {
|
|
55
|
+
"types": "./dist/primitives/agent-audio-visualizer-bar.d.ts",
|
|
56
|
+
"default": "./dist/primitives/agent-audio-visualizer-bar.js"
|
|
57
|
+
},
|
|
58
|
+
"require": {
|
|
59
|
+
"types": "./dist/primitives/agent-audio-visualizer-bar.d.cts",
|
|
60
|
+
"default": "./dist/primitives/agent-audio-visualizer-bar.cjs"
|
|
61
|
+
}
|
|
62
|
+
},
|
|
53
63
|
"./primitives/agent-comment": {
|
|
54
64
|
"import": {
|
|
55
65
|
"types": "./dist/primitives/agent-comment.d.ts",
|
|
@@ -410,6 +420,16 @@
|
|
|
410
420
|
"default": "./dist/primitives/dialog.cjs"
|
|
411
421
|
}
|
|
412
422
|
},
|
|
423
|
+
"./primitives/dictation-provider": {
|
|
424
|
+
"import": {
|
|
425
|
+
"types": "./dist/primitives/dictation-provider.d.ts",
|
|
426
|
+
"default": "./dist/primitives/dictation-provider.js"
|
|
427
|
+
},
|
|
428
|
+
"require": {
|
|
429
|
+
"types": "./dist/primitives/dictation-provider.d.cts",
|
|
430
|
+
"default": "./dist/primitives/dictation-provider.cjs"
|
|
431
|
+
}
|
|
432
|
+
},
|
|
413
433
|
"./primitives/document-preview": {
|
|
414
434
|
"import": {
|
|
415
435
|
"types": "./dist/primitives/document-preview.d.ts",
|
|
@@ -1240,6 +1260,26 @@
|
|
|
1240
1260
|
"default": "./dist/primitives/voice-dictation-button.cjs"
|
|
1241
1261
|
}
|
|
1242
1262
|
},
|
|
1263
|
+
"./primitives/voice-session-controls": {
|
|
1264
|
+
"import": {
|
|
1265
|
+
"types": "./dist/primitives/voice-session-controls.d.ts",
|
|
1266
|
+
"default": "./dist/primitives/voice-session-controls.js"
|
|
1267
|
+
},
|
|
1268
|
+
"require": {
|
|
1269
|
+
"types": "./dist/primitives/voice-session-controls.d.cts",
|
|
1270
|
+
"default": "./dist/primitives/voice-session-controls.cjs"
|
|
1271
|
+
}
|
|
1272
|
+
},
|
|
1273
|
+
"./hooks/use-agent-audio-visualizer-bar": {
|
|
1274
|
+
"import": {
|
|
1275
|
+
"types": "./dist/hooks/use-agent-audio-visualizer-bar.d.ts",
|
|
1276
|
+
"default": "./dist/hooks/use-agent-audio-visualizer-bar.js"
|
|
1277
|
+
},
|
|
1278
|
+
"require": {
|
|
1279
|
+
"types": "./dist/hooks/use-agent-audio-visualizer-bar.d.cts",
|
|
1280
|
+
"default": "./dist/hooks/use-agent-audio-visualizer-bar.cjs"
|
|
1281
|
+
}
|
|
1282
|
+
},
|
|
1243
1283
|
"./hooks/use-copy-to-clipboard": {
|
|
1244
1284
|
"import": {
|
|
1245
1285
|
"types": "./dist/hooks/use-copy-to-clipboard.d.ts",
|
|
@@ -1250,6 +1290,16 @@
|
|
|
1250
1290
|
"default": "./dist/hooks/use-copy-to-clipboard.cjs"
|
|
1251
1291
|
}
|
|
1252
1292
|
},
|
|
1293
|
+
"./hooks/use-dictation": {
|
|
1294
|
+
"import": {
|
|
1295
|
+
"types": "./dist/hooks/use-dictation.d.ts",
|
|
1296
|
+
"default": "./dist/hooks/use-dictation.js"
|
|
1297
|
+
},
|
|
1298
|
+
"require": {
|
|
1299
|
+
"types": "./dist/hooks/use-dictation.d.cts",
|
|
1300
|
+
"default": "./dist/hooks/use-dictation.cjs"
|
|
1301
|
+
}
|
|
1302
|
+
},
|
|
1253
1303
|
"./hooks/use-layout-preference": {
|
|
1254
1304
|
"import": {
|
|
1255
1305
|
"types": "./dist/hooks/use-layout-preference.d.ts",
|
package/dist/chunk-LKPM6DQP.cjs
DELETED
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }"use client";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var _chunkJDEXZGIYcjs = require('./chunk-JDEXZGIY.cjs');
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
var _chunkKWLSBTB2cjs = require('./chunk-KWLSBTB2.cjs');
|
|
8
|
-
|
|
9
|
-
// src/primitives/voice-dictation-button.tsx
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
var _react = require('react');
|
|
16
|
-
var _reactdialog = require('@radix-ui/react-dialog'); var DialogPrimitive = _interopRequireWildcard(_reactdialog);
|
|
17
|
-
var _lucidereact = require('lucide-react');
|
|
18
|
-
var _jsxruntime = require('react/jsx-runtime');
|
|
19
|
-
function VoiceDictationButton({
|
|
20
|
-
onCommit,
|
|
21
|
-
onCancel,
|
|
22
|
-
title = "Dictate your message",
|
|
23
|
-
caption = "listening",
|
|
24
|
-
lang = "en-US",
|
|
25
|
-
continuous = true,
|
|
26
|
-
className,
|
|
27
|
-
size = "sm",
|
|
28
|
-
showLabel = false,
|
|
29
|
-
children,
|
|
30
|
-
disabled = false,
|
|
31
|
-
visibility = "visible",
|
|
32
|
-
shrink = true
|
|
33
|
-
}) {
|
|
34
|
-
const [supported, setSupported] = _react.useState.call(void 0, false);
|
|
35
|
-
const [open, setOpen] = _react.useState.call(void 0, false);
|
|
36
|
-
const [transcript, setTranscript] = _react.useState.call(void 0, "");
|
|
37
|
-
const [interim, setInterim] = _react.useState.call(void 0, "");
|
|
38
|
-
const [errored, setErrored] = _react.useState.call(void 0, false);
|
|
39
|
-
const recognitionRef = _react.useRef.call(void 0, null);
|
|
40
|
-
_react.useEffect.call(void 0, () => {
|
|
41
|
-
const w = window;
|
|
42
|
-
const Ctor = _nullishCoalesce(w.SpeechRecognition, () => ( w.webkitSpeechRecognition));
|
|
43
|
-
setSupported(typeof Ctor === "function");
|
|
44
|
-
}, []);
|
|
45
|
-
const stop = _react.useCallback.call(void 0, () => {
|
|
46
|
-
_optionalChain([recognitionRef, 'access', _ => _.current, 'optionalAccess', _2 => _2.stop, 'call', _3 => _3()]);
|
|
47
|
-
recognitionRef.current = null;
|
|
48
|
-
}, []);
|
|
49
|
-
const startRecognition = _react.useCallback.call(void 0, () => {
|
|
50
|
-
const w = window;
|
|
51
|
-
const Ctor = _nullishCoalesce(w.SpeechRecognition, () => ( w.webkitSpeechRecognition));
|
|
52
|
-
if (!Ctor) return;
|
|
53
|
-
const rec = new Ctor();
|
|
54
|
-
rec.continuous = continuous;
|
|
55
|
-
rec.interimResults = true;
|
|
56
|
-
rec.lang = lang;
|
|
57
|
-
rec.onresult = (event) => {
|
|
58
|
-
let finalChunk = "";
|
|
59
|
-
let interimChunk = "";
|
|
60
|
-
for (let i = event.resultIndex; i < event.results.length; i++) {
|
|
61
|
-
const r = event.results[i];
|
|
62
|
-
if (!r) continue;
|
|
63
|
-
if (r.isFinal) finalChunk += r[0].transcript;
|
|
64
|
-
else interimChunk += r[0].transcript;
|
|
65
|
-
}
|
|
66
|
-
if (finalChunk) {
|
|
67
|
-
setTranscript((prev) => prev ? prev + " " + finalChunk : finalChunk);
|
|
68
|
-
setInterim("");
|
|
69
|
-
} else if (interimChunk) {
|
|
70
|
-
setInterim(interimChunk);
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
rec.onerror = () => {
|
|
74
|
-
setErrored(true);
|
|
75
|
-
};
|
|
76
|
-
rec.onend = () => {
|
|
77
|
-
recognitionRef.current = null;
|
|
78
|
-
};
|
|
79
|
-
recognitionRef.current = rec;
|
|
80
|
-
setErrored(false);
|
|
81
|
-
rec.start();
|
|
82
|
-
}, [continuous, lang]);
|
|
83
|
-
const openOverlay = _react.useCallback.call(void 0, () => {
|
|
84
|
-
setTranscript("");
|
|
85
|
-
setInterim("");
|
|
86
|
-
setOpen(true);
|
|
87
|
-
startRecognition();
|
|
88
|
-
}, [startRecognition]);
|
|
89
|
-
const closeOverlay = _react.useCallback.call(void 0, () => {
|
|
90
|
-
stop();
|
|
91
|
-
setOpen(false);
|
|
92
|
-
setInterim("");
|
|
93
|
-
}, [stop]);
|
|
94
|
-
const handleDone = _react.useCallback.call(void 0, () => {
|
|
95
|
-
const final = `${transcript} ${interim}`.trim();
|
|
96
|
-
closeOverlay();
|
|
97
|
-
if (final) onCommit(final);
|
|
98
|
-
else _optionalChain([onCancel, 'optionalCall', _4 => _4()]);
|
|
99
|
-
}, [transcript, interim, onCommit, onCancel, closeOverlay]);
|
|
100
|
-
const handleCancel = _react.useCallback.call(void 0, () => {
|
|
101
|
-
closeOverlay();
|
|
102
|
-
_optionalChain([onCancel, 'optionalCall', _5 => _5()]);
|
|
103
|
-
}, [closeOverlay, onCancel]);
|
|
104
|
-
_react.useEffect.call(void 0, () => {
|
|
105
|
-
if (!open) return;
|
|
106
|
-
const onKey = (e) => {
|
|
107
|
-
if (e.key === "Enter" && !e.shiftKey) handleDone();
|
|
108
|
-
};
|
|
109
|
-
document.addEventListener("keydown", onKey);
|
|
110
|
-
return () => document.removeEventListener("keydown", onKey);
|
|
111
|
-
}, [open, handleDone]);
|
|
112
|
-
_react.useEffect.call(void 0, () => {
|
|
113
|
-
return () => {
|
|
114
|
-
_optionalChain([recognitionRef, 'access', _6 => _6.current, 'optionalAccess', _7 => _7.abort, 'call', _8 => _8()]);
|
|
115
|
-
};
|
|
116
|
-
}, []);
|
|
117
|
-
if (!supported) return null;
|
|
118
|
-
const displayTranscript = `${transcript}${interim ? (transcript ? " " : "") + interim : ""}`;
|
|
119
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
120
|
-
children ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
121
|
-
"button",
|
|
122
|
-
{
|
|
123
|
-
type: "button",
|
|
124
|
-
onClick: openOverlay,
|
|
125
|
-
disabled,
|
|
126
|
-
"aria-label": "Start dictation",
|
|
127
|
-
className: _chunkKWLSBTB2cjs.cn.call(void 0, visibility === "hidden" && "hidden", className),
|
|
128
|
-
children
|
|
129
|
-
}
|
|
130
|
-
) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
131
|
-
_chunkJDEXZGIYcjs.Button,
|
|
132
|
-
{
|
|
133
|
-
type: "button",
|
|
134
|
-
onClick: openOverlay,
|
|
135
|
-
disabled,
|
|
136
|
-
variant: "outline",
|
|
137
|
-
size,
|
|
138
|
-
"aria-label": "Start dictation",
|
|
139
|
-
className: _chunkKWLSBTB2cjs.cn.call(void 0, "transition-colors", visibility === "hidden" && "hidden", !shrink && "shrink-0", className),
|
|
140
|
-
children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "flex items-center justify-center gap-2", children: [
|
|
141
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Mic, { className: "h-4 w-4" }),
|
|
142
|
-
showLabel && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: "Speak" })
|
|
143
|
-
] })
|
|
144
|
-
}
|
|
145
|
-
),
|
|
146
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
147
|
-
DialogPrimitive.Root,
|
|
148
|
-
{
|
|
149
|
-
open,
|
|
150
|
-
onOpenChange: (next) => {
|
|
151
|
-
if (!next) closeOverlay();
|
|
152
|
-
},
|
|
153
|
-
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogPrimitive.Portal, { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
154
|
-
DialogPrimitive.Content,
|
|
155
|
-
{
|
|
156
|
-
"aria-label": "Voice dictation",
|
|
157
|
-
onOpenAutoFocus: (e) => e.preventDefault(),
|
|
158
|
-
onMouseDown: (e) => {
|
|
159
|
-
if (e.target === e.currentTarget) handleCancel();
|
|
160
|
-
},
|
|
161
|
-
className: "fixed inset-0 z-[200] flex flex-col bg-background outline-hidden md:items-center md:justify-center md:bg-black/40 md:backdrop-blur-sm",
|
|
162
|
-
children: [
|
|
163
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogPrimitive.Title, { className: "sr-only", children: "Voice dictation" }),
|
|
164
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1 md:flex-initial w-full md:max-w-lg md:rounded-xl bg-background flex flex-col md:max-h-[80vh] md:shadow-2xl md:border md:border-border", children: [
|
|
165
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-between px-4 py-3 border-b border-border md:rounded-t-xl", children: [
|
|
166
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-mono text-xs uppercase tracking-wider text-muted-foreground", children: caption }),
|
|
167
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
168
|
-
"button",
|
|
169
|
-
{
|
|
170
|
-
type: "button",
|
|
171
|
-
onClick: handleCancel,
|
|
172
|
-
"aria-label": "Cancel",
|
|
173
|
-
className: "p-1 -m-1 rounded-sm hover:bg-muted/60 transition-colors",
|
|
174
|
-
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.X, { className: "h-4 w-4" })
|
|
175
|
-
}
|
|
176
|
-
)
|
|
177
|
-
] }),
|
|
178
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1 flex flex-col items-center justify-center px-6 text-center", children: [
|
|
179
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative w-24 h-24 mb-10 flex items-center justify-center", children: [
|
|
180
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
181
|
-
"span",
|
|
182
|
-
{
|
|
183
|
-
"aria-hidden": true,
|
|
184
|
-
className: _chunkKWLSBTB2cjs.cn.call(void 0,
|
|
185
|
-
"absolute inset-0 rounded-full",
|
|
186
|
-
errored ? "bg-destructive/20" : "bg-destructive/20 animate-ping"
|
|
187
|
-
)
|
|
188
|
-
}
|
|
189
|
-
),
|
|
190
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
191
|
-
"span",
|
|
192
|
-
{
|
|
193
|
-
"aria-hidden": true,
|
|
194
|
-
className: _chunkKWLSBTB2cjs.cn.call(void 0,
|
|
195
|
-
"absolute inset-2 rounded-full",
|
|
196
|
-
errored ? "bg-destructive/40" : "bg-destructive/40"
|
|
197
|
-
)
|
|
198
|
-
}
|
|
199
|
-
),
|
|
200
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Mic, { className: "relative h-9 w-9 text-destructive-foreground" })
|
|
201
|
-
] }),
|
|
202
|
-
title && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-base font-medium text-muted-foreground mb-3", children: title }),
|
|
203
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xl md:text-2xl leading-relaxed min-h-[5rem] max-w-xl text-foreground", children: displayTranscript ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
204
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: transcript }),
|
|
205
|
-
interim && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "text-muted-foreground", children: [
|
|
206
|
-
transcript ? " " : "",
|
|
207
|
-
interim
|
|
208
|
-
] })
|
|
209
|
-
] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-muted-foreground italic text-base", children: "Start speaking \u2014 I'm listening." }) }),
|
|
210
|
-
errored && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-destructive mt-4", children: "Couldn't access the microphone. Check permissions." })
|
|
211
|
-
] }),
|
|
212
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "border-t border-border px-4 py-4 pb-[calc(1rem+env(safe-area-inset-bottom))] md:pb-4 md:rounded-b-xl flex flex-col items-stretch gap-2", children: [
|
|
213
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
214
|
-
_chunkJDEXZGIYcjs.Button,
|
|
215
|
-
{
|
|
216
|
-
size: "lg",
|
|
217
|
-
className: "h-12 w-full",
|
|
218
|
-
onClick: handleDone,
|
|
219
|
-
disabled: !displayTranscript.trim(),
|
|
220
|
-
children: "Done"
|
|
221
|
-
}
|
|
222
|
-
),
|
|
223
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
224
|
-
"button",
|
|
225
|
-
{
|
|
226
|
-
type: "button",
|
|
227
|
-
onClick: handleCancel,
|
|
228
|
-
className: "text-sm text-muted-foreground hover:text-foreground py-1",
|
|
229
|
-
children: "Cancel"
|
|
230
|
-
}
|
|
231
|
-
)
|
|
232
|
-
] })
|
|
233
|
-
] })
|
|
234
|
-
]
|
|
235
|
-
}
|
|
236
|
-
) })
|
|
237
|
-
}
|
|
238
|
-
)
|
|
239
|
-
] });
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
exports.VoiceDictationButton = VoiceDictationButton;
|