@epicbagel/saas-kit 1.0.0 → 1.1.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.
Files changed (120) hide show
  1. package/README.md +38 -1
  2. package/THIRD_PARTY_NOTICES.md +13 -7
  3. package/dist/chunk-2AU7ZRGX.cjs +96 -0
  4. package/dist/chunk-2BTDBZYN.cjs +154 -0
  5. package/dist/chunk-2HV2KKOE.cjs +38 -0
  6. package/dist/chunk-2KFZQJH5.cjs +29 -0
  7. package/dist/chunk-32Q4XOTU.cjs +204 -0
  8. package/dist/chunk-42RTTHND.js +29 -0
  9. package/dist/chunk-6FC65AZQ.js +38 -0
  10. package/dist/chunk-6V4XMQ6D.js +118 -0
  11. package/dist/chunk-B765DSRG.cjs +66 -0
  12. package/dist/chunk-ELPV44S6.cjs +44 -0
  13. package/dist/chunk-EOUO3ORO.cjs +244 -0
  14. package/dist/chunk-EZCKWTH7.js +204 -0
  15. package/dist/chunk-F366BHWH.js +116 -0
  16. package/dist/chunk-GFG2R5BZ.js +132 -0
  17. package/dist/chunk-HAC32ALJ.js +244 -0
  18. package/dist/chunk-I5UQSBBZ.cjs +118 -0
  19. package/dist/chunk-INNGGLMZ.js +44 -0
  20. package/dist/chunk-IW4ZIXXG.js +66 -0
  21. package/dist/chunk-JZOBIPFC.js +96 -0
  22. package/dist/chunk-KENBU3NV.cjs +27 -0
  23. package/dist/chunk-MHYAVXOE.js +159 -0
  24. package/dist/chunk-RIWLAMME.cjs +159 -0
  25. package/dist/chunk-SUB4BAYE.cjs +73 -0
  26. package/dist/chunk-THWIJG5C.js +73 -0
  27. package/dist/chunk-V4YWTRLD.cjs +116 -0
  28. package/dist/chunk-VY5U4VGV.js +27 -0
  29. package/dist/chunk-XABXUP6L.cjs +132 -0
  30. package/dist/chunk-Z45YKVAM.js +154 -0
  31. package/dist/primitives/action-dock.cjs +8 -0
  32. package/dist/primitives/action-dock.d.cts +10 -0
  33. package/dist/primitives/action-dock.d.ts +10 -0
  34. package/dist/primitives/action-dock.js +8 -0
  35. package/dist/primitives/alert.d.cts +1 -1
  36. package/dist/primitives/alert.d.ts +1 -1
  37. package/dist/primitives/attachment.cjs +25 -203
  38. package/dist/primitives/attachment.d.cts +1 -1
  39. package/dist/primitives/attachment.d.ts +1 -1
  40. package/dist/primitives/attachment.js +12 -190
  41. package/dist/primitives/badge.d.cts +1 -1
  42. package/dist/primitives/badge.d.ts +1 -1
  43. package/dist/primitives/board-view.cjs +3 -3
  44. package/dist/primitives/board-view.js +2 -2
  45. package/dist/primitives/bubble.cjs +14 -0
  46. package/dist/primitives/bubble.d.cts +21 -0
  47. package/dist/primitives/bubble.d.ts +21 -0
  48. package/dist/primitives/bubble.js +14 -0
  49. package/dist/primitives/button.d.cts +2 -2
  50. package/dist/primitives/button.d.ts +2 -2
  51. package/dist/primitives/chat.cjs +864 -0
  52. package/dist/primitives/chat.d.cts +326 -0
  53. package/dist/primitives/chat.d.ts +326 -0
  54. package/dist/primitives/chat.js +864 -0
  55. package/dist/primitives/connection.cjs +6 -6
  56. package/dist/primitives/connection.js +7 -7
  57. package/dist/primitives/file-dropzone.cjs +7 -113
  58. package/dist/primitives/file-dropzone.js +6 -112
  59. package/dist/primitives/input-group.cjs +21 -0
  60. package/dist/primitives/input-group.d.cts +20 -0
  61. package/dist/primitives/input-group.d.ts +20 -0
  62. package/dist/primitives/input-group.js +21 -0
  63. package/dist/primitives/item.cjs +197 -0
  64. package/dist/primitives/item.d.cts +28 -0
  65. package/dist/primitives/item.d.ts +28 -0
  66. package/dist/primitives/item.js +197 -0
  67. package/dist/primitives/lazy-markdown.cjs +10 -0
  68. package/dist/primitives/lazy-markdown.d.cts +20 -0
  69. package/dist/primitives/lazy-markdown.d.ts +20 -0
  70. package/dist/primitives/lazy-markdown.js +10 -0
  71. package/dist/primitives/markdown.cjs +17 -0
  72. package/dist/primitives/markdown.d.cts +32 -0
  73. package/dist/primitives/markdown.d.ts +32 -0
  74. package/dist/primitives/markdown.js +17 -0
  75. package/dist/primitives/marker.cjs +14 -0
  76. package/dist/primitives/marker.d.cts +15 -0
  77. package/dist/primitives/marker.d.ts +15 -0
  78. package/dist/primitives/marker.js +14 -0
  79. package/dist/primitives/message-scroller.cjs +26 -0
  80. package/dist/primitives/message-scroller.d.cts +16 -0
  81. package/dist/primitives/message-scroller.d.ts +16 -0
  82. package/dist/primitives/message-scroller.js +26 -0
  83. package/dist/primitives/message.cjs +7 -84
  84. package/dist/primitives/message.js +8 -85
  85. package/dist/primitives/resource-list.cjs +3 -3
  86. package/dist/primitives/resource-list.js +2 -2
  87. package/dist/primitives/rich-text.cjs +3 -38
  88. package/dist/primitives/rich-text.js +3 -38
  89. package/dist/primitives/section-header.d.cts +1 -1
  90. package/dist/primitives/section-header.d.ts +1 -1
  91. package/dist/primitives/spinner.cjs +23 -0
  92. package/dist/primitives/spinner.d.cts +6 -0
  93. package/dist/primitives/spinner.d.ts +6 -0
  94. package/dist/primitives/spinner.js +23 -0
  95. package/dist/primitives/suggestion.cjs +11 -0
  96. package/dist/primitives/suggestion.d.cts +19 -0
  97. package/dist/primitives/suggestion.d.ts +19 -0
  98. package/dist/primitives/suggestion.js +11 -0
  99. package/dist/primitives/switch-field.cjs +2 -2
  100. package/dist/primitives/switch-field.js +3 -3
  101. package/dist/primitives/textarea.cjs +4 -33
  102. package/dist/primitives/textarea.js +3 -32
  103. package/dist/primitives/toggle-group.d.cts +2 -2
  104. package/dist/primitives/toggle-group.d.ts +2 -2
  105. package/dist/primitives/toggle.d.cts +2 -2
  106. package/dist/primitives/toggle.d.ts +2 -2
  107. package/dist/primitives/trace.cjs +23 -0
  108. package/dist/primitives/trace.d.cts +22 -0
  109. package/dist/primitives/trace.d.ts +22 -0
  110. package/dist/primitives/trace.js +23 -0
  111. package/dist/primitives/voice-dictation-button.cjs +5 -239
  112. package/dist/primitives/voice-dictation-button.js +4 -238
  113. package/package.json +125 -2
  114. package/src/styles/components/bubble.css +81 -0
  115. package/src/styles/components/marker.css +27 -0
  116. package/src/styles/components/message-scroller.css +11 -0
  117. package/src/styles/components.css +3 -0
  118. package/src/styles/utilities.css +3 -2
  119. package/dist/{chunk-UGF2K6NR.js → chunk-HRLP4BHJ.js} +6 -6
  120. package/dist/{chunk-RWWOFWLP.cjs → chunk-IH3COANJ.cjs} +3 -3
@@ -0,0 +1,118 @@
1
+ "use client";
2
+ import {
3
+ Text
4
+ } from "./chunk-EIY5LLSP.js";
5
+ import {
6
+ Tooltip,
7
+ TooltipContent,
8
+ TooltipTrigger
9
+ } from "./chunk-ZRLUUZHK.js";
10
+ import {
11
+ Button
12
+ } from "./chunk-HQRWRRZJ.js";
13
+ import {
14
+ cn
15
+ } from "./chunk-G6SRSWXB.js";
16
+
17
+ // src/primitives/file-dropzone.tsx
18
+ import { FileUp, Loader2 } from "lucide-react";
19
+ import { useRef, useState } from "react";
20
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
21
+ function FileDropzone({
22
+ onFile,
23
+ onFiles,
24
+ multiple = false,
25
+ accept,
26
+ disabled = false,
27
+ busy: externalBusy = false,
28
+ label = "Drop a file, or choose one",
29
+ description,
30
+ busyLabel = "Reading file\u2026",
31
+ icon,
32
+ variant = "dropzone",
33
+ className
34
+ }) {
35
+ const inputRef = useRef(null);
36
+ const [dragging, setDragging] = useState(false);
37
+ const [internalBusy, setInternalBusy] = useState(false);
38
+ const busy = externalBusy || internalBusy;
39
+ async function select(files) {
40
+ if (files.length === 0 || disabled || busy) return;
41
+ setInternalBusy(true);
42
+ try {
43
+ if (multiple) {
44
+ await onFiles?.(files);
45
+ } else {
46
+ const first = files[0];
47
+ if (first) await onFile?.(first);
48
+ }
49
+ } finally {
50
+ setInternalBusy(false);
51
+ if (inputRef.current) inputRef.current.value = "";
52
+ }
53
+ }
54
+ function onDrop(event) {
55
+ event.preventDefault();
56
+ setDragging(false);
57
+ void select(Array.from(event.dataTransfer.files ?? []));
58
+ }
59
+ const trigger = /* @__PURE__ */ jsxs(
60
+ Button,
61
+ {
62
+ type: "button",
63
+ "data-file-dropzone": "true",
64
+ variant: "outline",
65
+ size: variant === "icon" ? "icon" : "default",
66
+ "aria-label": variant === "icon" ? String(busy ? busyLabel : label) : void 0,
67
+ disabled: disabled || busy,
68
+ onClick: () => inputRef.current?.click(),
69
+ onDragEnter: (event) => {
70
+ event.preventDefault();
71
+ setDragging(true);
72
+ },
73
+ onDragOver: (event) => {
74
+ event.preventDefault();
75
+ setDragging(true);
76
+ },
77
+ onDragLeave: () => setDragging(false),
78
+ onDrop,
79
+ className: cn(
80
+ variant === "dropzone" ? "h-auto w-full flex-col whitespace-normal border-2 border-dashed px-6 py-8 text-center" : variant === "button" ? "w-fit" : "",
81
+ dragging && "border-primary bg-primary/5",
82
+ className
83
+ ),
84
+ children: [
85
+ /* @__PURE__ */ jsx("span", { className: cn(
86
+ "flex items-center justify-center text-muted-foreground",
87
+ variant === "dropzone" && "mb-2 h-10 w-10 rounded-full bg-muted"
88
+ ), children: busy ? /* @__PURE__ */ jsx(Loader2, { className: "h-5 w-5 animate-spin" }) : icon ?? /* @__PURE__ */ jsx(FileUp, { className: "h-5 w-5" }) }),
89
+ /* @__PURE__ */ jsx("span", { className: variant === "icon" ? "sr-only" : "font-medium", children: busy ? busyLabel : label }),
90
+ description && variant === "dropzone" && /* @__PURE__ */ jsx(Text, { variant: "muted", className: "mt-1 max-w-md text-xs", children: description })
91
+ ]
92
+ }
93
+ );
94
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
95
+ /* @__PURE__ */ jsx(
96
+ "input",
97
+ {
98
+ ref: inputRef,
99
+ type: "file",
100
+ accept,
101
+ multiple,
102
+ disabled: disabled || busy,
103
+ onChange: (event) => void select(Array.from(event.target.files ?? [])),
104
+ className: "sr-only",
105
+ tabIndex: -1,
106
+ "aria-hidden": "true"
107
+ }
108
+ ),
109
+ variant === "icon" && description ? /* @__PURE__ */ jsxs(Tooltip, { children: [
110
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: trigger }),
111
+ /* @__PURE__ */ jsx(TooltipContent, { children: description })
112
+ ] }) : trigger
113
+ ] });
114
+ }
115
+
116
+ export {
117
+ FileDropzone
118
+ };
@@ -0,0 +1,66 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
2
+
3
+
4
+ var _chunkKWLSBTB2cjs = require('./chunk-KWLSBTB2.cjs');
5
+
6
+ // src/primitives/marker.tsx
7
+ var _classvarianceauthority = require('class-variance-authority');
8
+ var _radixui = require('radix-ui');
9
+ var _jsxruntime = require('react/jsx-runtime');
10
+ var markerVariants = _classvarianceauthority.cva.call(void 0,
11
+ "cn-marker group/marker relative flex w-full items-center",
12
+ {
13
+ variants: {
14
+ variant: {
15
+ default: "cn-marker-variant-default",
16
+ separator: "cn-marker-variant-separator",
17
+ border: "cn-marker-variant-border"
18
+ }
19
+ }
20
+ }
21
+ );
22
+ function Marker({
23
+ className,
24
+ variant = "default",
25
+ asChild = false,
26
+ ...props
27
+ }) {
28
+ const Comp = asChild ? _radixui.Slot.Root : "div";
29
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
30
+ Comp,
31
+ {
32
+ "data-slot": "marker",
33
+ "data-variant": variant,
34
+ className: _chunkKWLSBTB2cjs.cn.call(void 0, markerVariants({ variant, className })),
35
+ ...props
36
+ }
37
+ );
38
+ }
39
+ function MarkerIcon({ className, ...props }) {
40
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
41
+ "span",
42
+ {
43
+ "data-slot": "marker-icon",
44
+ "aria-hidden": "true",
45
+ className: _chunkKWLSBTB2cjs.cn.call(void 0, "cn-marker-icon shrink-0", className),
46
+ ...props
47
+ }
48
+ );
49
+ }
50
+ function MarkerContent({ className, ...props }) {
51
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
52
+ "span",
53
+ {
54
+ "data-slot": "marker-content",
55
+ className: _chunkKWLSBTB2cjs.cn.call(void 0, "cn-marker-content min-w-0 wrap-break-word", className),
56
+ ...props
57
+ }
58
+ );
59
+ }
60
+
61
+
62
+
63
+
64
+
65
+
66
+ exports.markerVariants = markerVariants; exports.Marker = Marker; exports.MarkerIcon = MarkerIcon; exports.MarkerContent = MarkerContent;
@@ -0,0 +1,44 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
2
+
3
+
4
+ var _chunkKWLSBTB2cjs = require('./chunk-KWLSBTB2.cjs');
5
+
6
+ // src/primitives/rich-text.tsx
7
+ var _jsxruntime = require('react/jsx-runtime');
8
+ function RichText({ size = "sm", tone = "default", className, ...props }) {
9
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
10
+ "div",
11
+ {
12
+ "data-slot": "rich-text",
13
+ className: _chunkKWLSBTB2cjs.cn.call(void 0,
14
+ size === "sm" ? "text-sm" : "text-base",
15
+ tone === "soft" && "text-foreground/90",
16
+ tone === "muted" && "text-muted-foreground",
17
+ "leading-relaxed",
18
+ "[&_p]:mb-2 [&_p:last-child]:mb-0",
19
+ "[&_a]:font-medium [&_a]:underline [&_a]:underline-offset-4",
20
+ "[&_strong]:font-semibold",
21
+ "[&_h1]:mb-3 [&_h1]:mt-6 [&_h1]:text-xl [&_h1]:font-semibold [&_h1]:tracking-tight [&_h1:first-child]:mt-0",
22
+ "[&_h2]:mb-2 [&_h2]:mt-5 [&_h2]:text-base [&_h2]:font-semibold [&_h2]:tracking-tight [&_h2:first-child]:mt-0",
23
+ "[&_h3]:mb-2 [&_h3]:mt-4 [&_h3]:font-semibold [&_h3:first-child]:mt-0",
24
+ "[&_ul]:my-2 [&_ul]:list-disc [&_ul]:pl-5",
25
+ "[&_ol]:my-2 [&_ol]:list-decimal [&_ol]:pl-5",
26
+ "[&_li]:my-1 [&_li>p]:mb-0",
27
+ "[&_blockquote]:my-3 [&_blockquote]:border-l-2 [&_blockquote]:border-border [&_blockquote]:pl-4 [&_blockquote]:text-muted-foreground",
28
+ "[&_hr]:my-4 [&_hr]:border-border",
29
+ "[&_code]:rounded [&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_code]:font-mono [&_code]:text-[0.875em]",
30
+ "[&_pre]:my-3 [&_pre]:overflow-x-auto [&_pre]:rounded-md [&_pre]:border [&_pre]:border-border [&_pre]:bg-muted/40 [&_pre]:p-3",
31
+ "[&_pre_code]:bg-transparent [&_pre_code]:p-0",
32
+ "[&_table]:my-3 [&_table]:w-full [&_table]:border-collapse [&_table]:text-left",
33
+ "[&_th]:border-b [&_th]:border-border [&_th]:px-2 [&_th]:py-1.5 [&_th]:font-semibold",
34
+ "[&_td]:border-b [&_td]:border-border/70 [&_td]:px-2 [&_td]:py-1.5",
35
+ className
36
+ ),
37
+ ...props
38
+ }
39
+ );
40
+ }
41
+
42
+
43
+
44
+ exports.RichText = RichText;
@@ -0,0 +1,244 @@
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 _chunkL4DH72UFcjs = require('./chunk-L4DH72UF.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
+ _chunkL4DH72UFcjs.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
+ _chunkL4DH72UFcjs.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;
@@ -0,0 +1,204 @@
1
+ "use client";
2
+ import {
3
+ Button
4
+ } from "./chunk-HQRWRRZJ.js";
5
+ import {
6
+ cn
7
+ } from "./chunk-G6SRSWXB.js";
8
+
9
+ // src/primitives/attachment.tsx
10
+ import { cva } from "class-variance-authority";
11
+ import { Slot } from "radix-ui";
12
+ import { jsx } from "react/jsx-runtime";
13
+ var attachmentVariants = cva(
14
+ "cn-attachment group/attachment relative flex max-w-full min-w-0 shrink-0 flex-wrap border bg-card text-card-foreground transition-colors has-[>a,>button]:hover:bg-muted/50 data-[state=error]:border-destructive/30 data-[state=idle]:border-dashed",
15
+ {
16
+ variants: {
17
+ size: {
18
+ default: "cn-attachment-size-default",
19
+ sm: "cn-attachment-size-sm",
20
+ xs: "cn-attachment-size-xs"
21
+ },
22
+ orientation: {
23
+ horizontal: "cn-attachment-orientation-horizontal items-center",
24
+ vertical: "cn-attachment-orientation-vertical flex-col"
25
+ }
26
+ }
27
+ }
28
+ );
29
+ function Attachment({
30
+ className,
31
+ state = "done",
32
+ size = "default",
33
+ orientation = "horizontal",
34
+ ...props
35
+ }) {
36
+ const resolvedOrientation = orientation ?? "horizontal";
37
+ return /* @__PURE__ */ jsx(
38
+ "div",
39
+ {
40
+ "data-slot": "attachment",
41
+ "data-state": state,
42
+ "data-size": size,
43
+ "data-orientation": resolvedOrientation,
44
+ className: cn(attachmentVariants({ size, orientation }), className),
45
+ ...props
46
+ }
47
+ );
48
+ }
49
+ var attachmentMediaVariants = cva(
50
+ "cn-attachment-media relative flex aspect-square shrink-0 items-center justify-center overflow-hidden group-data-[state=error]/attachment:bg-destructive/10 group-data-[state=error]/attachment:text-destructive [&_svg]:pointer-events-none",
51
+ {
52
+ variants: {
53
+ variant: {
54
+ icon: "cn-attachment-media-variant-icon",
55
+ image: "cn-attachment-media-variant-image *:[img]:aspect-square *:[img]:w-full *:[img]:object-cover"
56
+ }
57
+ },
58
+ defaultVariants: {
59
+ variant: "icon"
60
+ }
61
+ }
62
+ );
63
+ function AttachmentMedia({
64
+ className,
65
+ variant = "icon",
66
+ ...props
67
+ }) {
68
+ return /* @__PURE__ */ jsx(
69
+ "div",
70
+ {
71
+ "data-slot": "attachment-media",
72
+ "data-variant": variant,
73
+ className: cn(attachmentMediaVariants({ variant }), className),
74
+ ...props
75
+ }
76
+ );
77
+ }
78
+ function AttachmentContent({
79
+ className,
80
+ ...props
81
+ }) {
82
+ return /* @__PURE__ */ jsx(
83
+ "div",
84
+ {
85
+ "data-slot": "attachment-content",
86
+ className: cn(
87
+ "cn-attachment-content max-w-full min-w-0 flex-1",
88
+ className
89
+ ),
90
+ ...props
91
+ }
92
+ );
93
+ }
94
+ function AttachmentTitle({
95
+ className,
96
+ ...props
97
+ }) {
98
+ return /* @__PURE__ */ jsx(
99
+ "span",
100
+ {
101
+ "data-slot": "attachment-title",
102
+ className: cn(
103
+ "cn-attachment-title block max-w-full min-w-0 truncate group-data-[state=processing]/attachment:shimmer group-data-[state=uploading]/attachment:shimmer",
104
+ className
105
+ ),
106
+ ...props
107
+ }
108
+ );
109
+ }
110
+ function AttachmentDescription({
111
+ className,
112
+ ...props
113
+ }) {
114
+ return /* @__PURE__ */ jsx(
115
+ "span",
116
+ {
117
+ "data-slot": "attachment-description",
118
+ className: cn(
119
+ "cn-attachment-description block min-w-0 truncate text-muted-foreground group-data-[state=error]/attachment:text-destructive/80",
120
+ "max-w-full",
121
+ className
122
+ ),
123
+ ...props
124
+ }
125
+ );
126
+ }
127
+ function AttachmentActions({
128
+ className,
129
+ ...props
130
+ }) {
131
+ return /* @__PURE__ */ jsx(
132
+ "div",
133
+ {
134
+ "data-slot": "attachment-actions",
135
+ className: cn(
136
+ "cn-attachment-actions flex shrink-0 items-center",
137
+ className
138
+ ),
139
+ ...props
140
+ }
141
+ );
142
+ }
143
+ function AttachmentAction({
144
+ className,
145
+ variant,
146
+ size = "icon-xs",
147
+ ...props
148
+ }) {
149
+ return /* @__PURE__ */ jsx(
150
+ Button,
151
+ {
152
+ "data-slot": "attachment-action",
153
+ variant: variant ?? "ghost",
154
+ size,
155
+ className: cn("cn-attachment-action", className),
156
+ ...props
157
+ }
158
+ );
159
+ }
160
+ function AttachmentTrigger({
161
+ className,
162
+ asChild = false,
163
+ type,
164
+ ...props
165
+ }) {
166
+ const Comp = asChild ? Slot.Root : "button";
167
+ return /* @__PURE__ */ jsx(
168
+ Comp,
169
+ {
170
+ "data-slot": "attachment-trigger",
171
+ type: asChild ? void 0 : type ?? "button",
172
+ className: cn(
173
+ "cn-attachment-trigger absolute inset-0 z-10 outline-none",
174
+ className
175
+ ),
176
+ ...props
177
+ }
178
+ );
179
+ }
180
+ function AttachmentGroup({ className, ...props }) {
181
+ return /* @__PURE__ */ jsx(
182
+ "div",
183
+ {
184
+ "data-slot": "attachment-group",
185
+ className: cn(
186
+ "cn-attachment-group flex min-w-0 scroll-fade-x snap-x snap-mandatory scrollbar-none overflow-x-auto overscroll-x-contain *:data-[slot=attachment]:flex-none *:data-[slot=attachment]:snap-start",
187
+ className
188
+ ),
189
+ ...props
190
+ }
191
+ );
192
+ }
193
+
194
+ export {
195
+ Attachment,
196
+ AttachmentMedia,
197
+ AttachmentContent,
198
+ AttachmentTitle,
199
+ AttachmentDescription,
200
+ AttachmentActions,
201
+ AttachmentAction,
202
+ AttachmentTrigger,
203
+ AttachmentGroup
204
+ };