@mieweb/ui 0.6.1-dev.149 → 0.6.1-dev.151

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 (82) hide show
  1. package/dist/brands/index.cjs +22 -22
  2. package/dist/brands/index.js +5 -5
  3. package/dist/chunk-2T4JU5RH.cjs +1156 -0
  4. package/dist/chunk-2T4JU5RH.cjs.map +1 -0
  5. package/dist/chunk-3SSXDWD7.js +363 -0
  6. package/dist/chunk-3SSXDWD7.js.map +1 -0
  7. package/dist/{chunk-MARLXJQO.cjs → chunk-6R2ZPDN7.cjs} +7 -7
  8. package/dist/{chunk-MARLXJQO.cjs.map → chunk-6R2ZPDN7.cjs.map} +1 -1
  9. package/dist/{chunk-WHUD3XHR.cjs → chunk-7PA26KBF.cjs} +15 -3
  10. package/dist/chunk-7PA26KBF.cjs.map +1 -0
  11. package/dist/chunk-ASLZUFH4.js +1967 -0
  12. package/dist/chunk-ASLZUFH4.js.map +1 -0
  13. package/dist/chunk-FADQVM4M.cjs +2017 -0
  14. package/dist/chunk-FADQVM4M.cjs.map +1 -0
  15. package/dist/{chunk-DFT7TYKL.cjs → chunk-H4T5T65N.cjs} +6 -3
  16. package/dist/chunk-H4T5T65N.cjs.map +1 -0
  17. package/dist/chunk-I6CY5C6A.js +12 -0
  18. package/dist/chunk-I6CY5C6A.js.map +1 -0
  19. package/dist/chunk-JFLC7SHM.cjs +35 -0
  20. package/dist/chunk-JFLC7SHM.cjs.map +1 -0
  21. package/dist/chunk-LZPPH5BW.cjs +368 -0
  22. package/dist/chunk-LZPPH5BW.cjs.map +1 -0
  23. package/dist/{chunk-3OHVUXDG.js → chunk-M7BLVBL4.js} +6 -3
  24. package/dist/chunk-M7BLVBL4.js.map +1 -0
  25. package/dist/chunk-PM2I3QKM.cjs +1419 -0
  26. package/dist/chunk-PM2I3QKM.cjs.map +1 -0
  27. package/dist/{chunk-TW6DXMSD.js → chunk-R6PBBPU3.js} +2 -2
  28. package/dist/{chunk-TW6DXMSD.js.map → chunk-R6PBBPU3.js.map} +1 -1
  29. package/dist/{chunk-33PO3J4O.js → chunk-RXY5SD3O.js} +15 -3
  30. package/dist/chunk-RXY5SD3O.js.map +1 -0
  31. package/dist/{chunk-AEGYWRSL.js → chunk-TXYTMU3K.js} +3 -3
  32. package/dist/{chunk-AEGYWRSL.js.map → chunk-TXYTMU3K.js.map} +1 -1
  33. package/dist/chunk-UHPQYBXQ.js +1124 -0
  34. package/dist/chunk-UHPQYBXQ.js.map +1 -0
  35. package/dist/chunk-XQE26F3G.js +1383 -0
  36. package/dist/chunk-XQE26F3G.js.map +1 -0
  37. package/dist/{chunk-26YNFCOC.cjs → chunk-Z6NRP4Z5.cjs} +2 -2
  38. package/dist/{chunk-26YNFCOC.cjs.map → chunk-Z6NRP4Z5.cjs.map} +1 -1
  39. package/dist/components/Dropdown/index.cjs +7 -7
  40. package/dist/components/Dropdown/index.d.cts +1 -1
  41. package/dist/components/Dropdown/index.d.ts +1 -1
  42. package/dist/components/Dropdown/index.js +1 -1
  43. package/dist/components/RichTextEditor/index.cjs +5 -5
  44. package/dist/components/RichTextEditor/index.js +2 -2
  45. package/dist/components/SuperChat/index.cjs +1319 -0
  46. package/dist/components/SuperChat/index.cjs.map +1 -0
  47. package/dist/components/SuperChat/index.d.cts +189 -0
  48. package/dist/components/SuperChat/index.d.ts +189 -0
  49. package/dist/components/SuperChat/index.js +1282 -0
  50. package/dist/components/SuperChat/index.js.map +1 -0
  51. package/dist/components/SuperChat/plugins/index.cjs +1221 -0
  52. package/dist/components/SuperChat/plugins/index.cjs.map +1 -0
  53. package/dist/components/SuperChat/plugins/index.d.cts +253 -0
  54. package/dist/components/SuperChat/plugins/index.d.ts +253 -0
  55. package/dist/components/SuperChat/plugins/index.js +1181 -0
  56. package/dist/components/SuperChat/plugins/index.js.map +1 -0
  57. package/dist/datavis.cjs +18 -362
  58. package/dist/datavis.cjs.map +1 -1
  59. package/dist/datavis.js +1 -361
  60. package/dist/datavis.js.map +1 -1
  61. package/dist/index.cjs +1297 -5412
  62. package/dist/index.cjs.map +1 -1
  63. package/dist/index.d.cts +44 -240
  64. package/dist/index.d.ts +44 -240
  65. package/dist/index.js +759 -5037
  66. package/dist/index.js.map +1 -1
  67. package/dist/nitroTableGrid-FWRCDE4N.js +22 -0
  68. package/dist/nitroTableGrid-FWRCDE4N.js.map +1 -0
  69. package/dist/nitroTableGrid-IY75TQJ2.cjs +44 -0
  70. package/dist/nitroTableGrid-IY75TQJ2.cjs.map +1 -0
  71. package/dist/styles.css +1 -1
  72. package/dist/tailwind-preset.cjs +4 -4
  73. package/dist/tailwind-preset.js +1 -1
  74. package/dist/types-BFFgW6qy.d.ts +240 -0
  75. package/dist/types-BzeY_kYO.d.cts +242 -0
  76. package/dist/types-BzeY_kYO.d.ts +242 -0
  77. package/dist/types-CRt5IPNL.d.cts +240 -0
  78. package/package.json +42 -5
  79. package/dist/chunk-33PO3J4O.js.map +0 -1
  80. package/dist/chunk-3OHVUXDG.js.map +0 -1
  81. package/dist/chunk-DFT7TYKL.cjs.map +0 -1
  82. package/dist/chunk-WHUD3XHR.cjs.map +0 -1
@@ -0,0 +1,1156 @@
1
+ 'use strict';
2
+
3
+ var chunkOR5DRJCW_cjs = require('./chunk-OR5DRJCW.cjs');
4
+ var React2 = require('react');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+ var classVarianceAuthority = require('class-variance-authority');
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 React2__namespace = /*#__PURE__*/_interopNamespace(React2);
27
+
28
+ function getFileType(mimeType) {
29
+ if (mimeType.startsWith("image/")) return "image";
30
+ if (mimeType.startsWith("video/")) return "video";
31
+ if (mimeType.startsWith("audio/")) return "audio";
32
+ if (mimeType.includes("pdf") || mimeType.includes("document") || mimeType.includes("text")) {
33
+ return "document";
34
+ }
35
+ return "file";
36
+ }
37
+ function formatFileSize(bytes) {
38
+ if (bytes < 1024) return `${bytes} B`;
39
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
40
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
41
+ }
42
+ function validateFile(file, acceptedTypes, maxSize) {
43
+ if (acceptedTypes && acceptedTypes.length > 0) {
44
+ const isAccepted = acceptedTypes.some((type) => {
45
+ if (type.startsWith(".")) {
46
+ return file.name.toLowerCase().endsWith(type.toLowerCase());
47
+ }
48
+ if (type.endsWith("/*")) {
49
+ return file.type.startsWith(type.replace("/*", "/"));
50
+ }
51
+ return file.type === type;
52
+ });
53
+ if (!isAccepted) {
54
+ return { valid: false, error: "File type not supported" };
55
+ }
56
+ }
57
+ if (maxSize && file.size > maxSize) {
58
+ return {
59
+ valid: false,
60
+ error: `File too large (max ${formatFileSize(maxSize)})`
61
+ };
62
+ }
63
+ return { valid: true };
64
+ }
65
+ function generateAttachmentId() {
66
+ return `attachment-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
67
+ }
68
+ function AttachmentPreviewItem({
69
+ attachment,
70
+ onRemove,
71
+ onRetry,
72
+ className
73
+ }) {
74
+ const { file, previewUrl, type, state, progress } = attachment;
75
+ const isImage = type === "image";
76
+ const isVideo = type === "video";
77
+ const isUploading = state === "uploading";
78
+ const isFailed = state === "failed";
79
+ return /* @__PURE__ */ jsxRuntime.jsxs(
80
+ "div",
81
+ {
82
+ className: chunkOR5DRJCW_cjs.cn(
83
+ "group relative overflow-hidden rounded-lg",
84
+ "bg-neutral-100 dark:bg-neutral-800",
85
+ "border border-neutral-200 dark:border-neutral-700",
86
+ isFailed && "border-red-500",
87
+ className
88
+ ),
89
+ children: [
90
+ (isImage || isVideo) && previewUrl ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative h-20 w-20", children: [
91
+ /* @__PURE__ */ jsxRuntime.jsx(
92
+ "img",
93
+ {
94
+ src: previewUrl,
95
+ alt: file.name,
96
+ className: chunkOR5DRJCW_cjs.cn(
97
+ "h-full w-full object-cover",
98
+ (isUploading || isFailed) && "opacity-50"
99
+ )
100
+ }
101
+ ),
102
+ isVideo && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
103
+ "svg",
104
+ {
105
+ "aria-hidden": "true",
106
+ className: "h-6 w-6 text-white drop-shadow",
107
+ fill: "currentColor",
108
+ viewBox: "0 0 24 24",
109
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 5v14l11-7z" })
110
+ }
111
+ ) })
112
+ ] }) : (
113
+ /* File preview */
114
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-20 w-20 flex-col items-center justify-center p-2", children: [
115
+ /* @__PURE__ */ jsxRuntime.jsx(
116
+ "svg",
117
+ {
118
+ "aria-hidden": "true",
119
+ className: "h-8 w-8 text-neutral-500",
120
+ fill: "none",
121
+ viewBox: "0 0 24 24",
122
+ stroke: "currentColor",
123
+ children: /* @__PURE__ */ jsxRuntime.jsx(
124
+ "path",
125
+ {
126
+ strokeLinecap: "round",
127
+ strokeLinejoin: "round",
128
+ strokeWidth: 2,
129
+ d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
130
+ }
131
+ )
132
+ }
133
+ ),
134
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-1 max-w-full truncate px-1 text-xs text-neutral-500", children: file.name.split(".").pop()?.toUpperCase() })
135
+ ] })
136
+ ),
137
+ isUploading && progress !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-black/50", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center text-white", children: [
138
+ /* @__PURE__ */ jsxRuntime.jsxs(
139
+ "svg",
140
+ {
141
+ "aria-hidden": "true",
142
+ className: "mx-auto h-6 w-6 animate-spin",
143
+ fill: "none",
144
+ viewBox: "0 0 24 24",
145
+ children: [
146
+ /* @__PURE__ */ jsxRuntime.jsx(
147
+ "circle",
148
+ {
149
+ className: "opacity-25",
150
+ cx: "12",
151
+ cy: "12",
152
+ r: "10",
153
+ stroke: "currentColor",
154
+ strokeWidth: "4"
155
+ }
156
+ ),
157
+ /* @__PURE__ */ jsxRuntime.jsx(
158
+ "path",
159
+ {
160
+ className: "opacity-75",
161
+ fill: "currentColor",
162
+ d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
163
+ }
164
+ )
165
+ ]
166
+ }
167
+ ),
168
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "mt-1 text-xs", children: [
169
+ progress,
170
+ "%"
171
+ ] })
172
+ ] }) }),
173
+ isFailed && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-black/50", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
174
+ /* @__PURE__ */ jsxRuntime.jsx(
175
+ "svg",
176
+ {
177
+ "aria-hidden": "true",
178
+ className: "mx-auto h-6 w-6 text-red-400",
179
+ fill: "none",
180
+ viewBox: "0 0 24 24",
181
+ stroke: "currentColor",
182
+ children: /* @__PURE__ */ jsxRuntime.jsx(
183
+ "path",
184
+ {
185
+ strokeLinecap: "round",
186
+ strokeLinejoin: "round",
187
+ strokeWidth: 2,
188
+ d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
189
+ }
190
+ )
191
+ }
192
+ ),
193
+ onRetry && /* @__PURE__ */ jsxRuntime.jsx(
194
+ "button",
195
+ {
196
+ type: "button",
197
+ onClick: onRetry,
198
+ className: "mt-1 text-xs text-white underline hover:no-underline",
199
+ children: "Retry"
200
+ }
201
+ )
202
+ ] }) }),
203
+ /* @__PURE__ */ jsxRuntime.jsx(
204
+ "button",
205
+ {
206
+ type: "button",
207
+ onClick: onRemove,
208
+ className: chunkOR5DRJCW_cjs.cn(
209
+ "absolute -top-1 -right-1 z-10",
210
+ "rounded-full p-1",
211
+ "bg-neutral-900 text-white",
212
+ "opacity-0 group-hover:opacity-100",
213
+ "focus:ring-primary-500 focus:opacity-100 focus:ring-2 focus:outline-none",
214
+ "transition-opacity"
215
+ ),
216
+ "aria-label": `Remove ${file.name}`,
217
+ children: /* @__PURE__ */ jsxRuntime.jsx(
218
+ "svg",
219
+ {
220
+ "aria-hidden": "true",
221
+ className: "h-3 w-3",
222
+ fill: "none",
223
+ viewBox: "0 0 24 24",
224
+ stroke: "currentColor",
225
+ children: /* @__PURE__ */ jsxRuntime.jsx(
226
+ "path",
227
+ {
228
+ strokeLinecap: "round",
229
+ strokeLinejoin: "round",
230
+ strokeWidth: 2,
231
+ d: "M6 18L18 6M6 6l12 12"
232
+ }
233
+ )
234
+ }
235
+ )
236
+ }
237
+ ),
238
+ /* @__PURE__ */ jsxRuntime.jsx(
239
+ "div",
240
+ {
241
+ className: chunkOR5DRJCW_cjs.cn(
242
+ "absolute right-0 bottom-0 left-0",
243
+ "bg-black/70 px-1 py-0.5",
244
+ "opacity-0 group-hover:opacity-100",
245
+ "transition-opacity"
246
+ ),
247
+ children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate text-xs text-white", children: file.name })
248
+ }
249
+ )
250
+ ]
251
+ }
252
+ );
253
+ }
254
+ AttachmentPreviewItem.displayName = "AttachmentPreviewItem";
255
+ var AttachmentPicker = React2__namespace.forwardRef(
256
+ ({
257
+ onFilesSelected,
258
+ acceptedTypes = ["image/*", "video/*", ".pdf", ".doc", ".docx"],
259
+ maxFileSize = 25 * 1024 * 1024,
260
+ // 25MB
261
+ maxFiles = 10,
262
+ multiple = true,
263
+ disabled = false,
264
+ onError,
265
+ className,
266
+ children
267
+ }, ref) => {
268
+ const inputRef = React2__namespace.useRef(null);
269
+ React2__namespace.useImperativeHandle(ref, () => inputRef.current);
270
+ const handleClick = () => {
271
+ inputRef.current?.click();
272
+ };
273
+ const handleChange = (event) => {
274
+ const files = Array.from(event.target.files || []);
275
+ if (files.length === 0) return;
276
+ const validFiles = [];
277
+ for (const file of files.slice(0, maxFiles)) {
278
+ const validation = validateFile(file, acceptedTypes, maxFileSize);
279
+ if (validation.valid) {
280
+ validFiles.push(file);
281
+ } else if (onError) {
282
+ onError(`${file.name}: ${validation.error}`);
283
+ }
284
+ }
285
+ if (files.length > maxFiles && onError) {
286
+ onError(`Maximum ${maxFiles} files allowed`);
287
+ }
288
+ if (validFiles.length > 0) {
289
+ onFilesSelected(validFiles);
290
+ }
291
+ event.target.value = "";
292
+ };
293
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
294
+ /* @__PURE__ */ jsxRuntime.jsx(
295
+ "input",
296
+ {
297
+ ref: inputRef,
298
+ type: "file",
299
+ accept: acceptedTypes.join(","),
300
+ multiple,
301
+ onChange: handleChange,
302
+ disabled,
303
+ className: "sr-only",
304
+ "aria-label": "Select files to attach"
305
+ }
306
+ ),
307
+ /* @__PURE__ */ jsxRuntime.jsx(
308
+ "button",
309
+ {
310
+ type: "button",
311
+ onClick: handleClick,
312
+ disabled,
313
+ "data-slot": "attachment-picker-button",
314
+ className: chunkOR5DRJCW_cjs.cn(
315
+ "inline-flex items-center justify-center",
316
+ "rounded-full p-2",
317
+ "text-neutral-500 hover:text-neutral-700",
318
+ "dark:text-neutral-400 dark:hover:text-neutral-200",
319
+ "hover:bg-neutral-100 dark:hover:bg-neutral-800",
320
+ "focus:ring-primary-500 focus:ring-2 focus:outline-none",
321
+ "disabled:cursor-not-allowed disabled:opacity-50",
322
+ "transition-colors",
323
+ className
324
+ ),
325
+ "aria-label": "Attach files",
326
+ children: children || /* @__PURE__ */ jsxRuntime.jsx(
327
+ "svg",
328
+ {
329
+ "aria-hidden": "true",
330
+ className: "h-5 w-5",
331
+ fill: "none",
332
+ viewBox: "0 0 24 24",
333
+ stroke: "currentColor",
334
+ children: /* @__PURE__ */ jsxRuntime.jsx(
335
+ "path",
336
+ {
337
+ strokeLinecap: "round",
338
+ strokeLinejoin: "round",
339
+ strokeWidth: 2,
340
+ d: "M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13"
341
+ }
342
+ )
343
+ }
344
+ )
345
+ }
346
+ )
347
+ ] });
348
+ }
349
+ );
350
+ AttachmentPicker.displayName = "AttachmentPicker";
351
+ function DragDropZone({
352
+ onFilesDropped,
353
+ acceptedTypes,
354
+ maxFileSize,
355
+ maxFiles = 10,
356
+ disabled = false,
357
+ onError,
358
+ children,
359
+ className
360
+ }) {
361
+ const [isDragging, setIsDragging] = React2__namespace.useState(false);
362
+ const dragCounterRef = React2__namespace.useRef(0);
363
+ const handleDragEnter = (event) => {
364
+ event.preventDefault();
365
+ event.stopPropagation();
366
+ if (disabled) return;
367
+ dragCounterRef.current++;
368
+ if (event.dataTransfer.items && event.dataTransfer.items.length > 0) {
369
+ setIsDragging(true);
370
+ }
371
+ };
372
+ const handleDragLeave = (event) => {
373
+ event.preventDefault();
374
+ event.stopPropagation();
375
+ if (disabled) return;
376
+ dragCounterRef.current--;
377
+ if (dragCounterRef.current === 0) {
378
+ setIsDragging(false);
379
+ }
380
+ };
381
+ const handleDragOver = (event) => {
382
+ event.preventDefault();
383
+ event.stopPropagation();
384
+ };
385
+ const handleDrop = (event) => {
386
+ event.preventDefault();
387
+ event.stopPropagation();
388
+ if (disabled) return;
389
+ setIsDragging(false);
390
+ dragCounterRef.current = 0;
391
+ const files = Array.from(event.dataTransfer.files);
392
+ if (files.length === 0) return;
393
+ const validFiles = [];
394
+ for (const file of files.slice(0, maxFiles)) {
395
+ const validation = validateFile(file, acceptedTypes, maxFileSize);
396
+ if (validation.valid) {
397
+ validFiles.push(file);
398
+ } else if (onError) {
399
+ onError(`${file.name}: ${validation.error}`);
400
+ }
401
+ }
402
+ if (files.length > maxFiles && onError) {
403
+ onError(`Maximum ${maxFiles} files allowed`);
404
+ }
405
+ if (validFiles.length > 0) {
406
+ onFilesDropped(validFiles);
407
+ }
408
+ };
409
+ return /* @__PURE__ */ jsxRuntime.jsxs(
410
+ "div",
411
+ {
412
+ onDragEnter: handleDragEnter,
413
+ onDragLeave: handleDragLeave,
414
+ onDragOver: handleDragOver,
415
+ onDrop: handleDrop,
416
+ className: chunkOR5DRJCW_cjs.cn("relative", className),
417
+ children: [
418
+ children,
419
+ isDragging && /* @__PURE__ */ jsxRuntime.jsx(
420
+ "div",
421
+ {
422
+ className: chunkOR5DRJCW_cjs.cn(
423
+ "absolute inset-0 z-50",
424
+ "flex items-center justify-center",
425
+ "bg-primary-50/90 dark:bg-primary-900/90",
426
+ "border-primary-500 border-2 border-dashed",
427
+ "rounded-lg"
428
+ ),
429
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
430
+ /* @__PURE__ */ jsxRuntime.jsx(
431
+ "svg",
432
+ {
433
+ "aria-hidden": "true",
434
+ className: "text-primary-800 mx-auto h-12 w-12",
435
+ fill: "none",
436
+ viewBox: "0 0 24 24",
437
+ stroke: "currentColor",
438
+ children: /* @__PURE__ */ jsxRuntime.jsx(
439
+ "path",
440
+ {
441
+ strokeLinecap: "round",
442
+ strokeLinejoin: "round",
443
+ strokeWidth: 2,
444
+ d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
445
+ }
446
+ )
447
+ }
448
+ ),
449
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-primary-700 dark:text-primary-300 mt-2 text-sm font-medium", children: "Drop files here" })
450
+ ] })
451
+ }
452
+ )
453
+ ]
454
+ }
455
+ );
456
+ }
457
+ DragDropZone.displayName = "DragDropZone";
458
+ function CameraButton({
459
+ onCapture,
460
+ useFrontCamera = false,
461
+ disabled = false,
462
+ className
463
+ }) {
464
+ const inputRef = React2__namespace.useRef(null);
465
+ const handleClick = () => {
466
+ inputRef.current?.click();
467
+ };
468
+ const handleChange = (event) => {
469
+ const file = event.target.files?.[0];
470
+ if (file) {
471
+ onCapture(file);
472
+ }
473
+ event.target.value = "";
474
+ };
475
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
476
+ /* @__PURE__ */ jsxRuntime.jsx(
477
+ "input",
478
+ {
479
+ ref: inputRef,
480
+ type: "file",
481
+ accept: "image/*",
482
+ capture: useFrontCamera ? "user" : "environment",
483
+ onChange: handleChange,
484
+ disabled,
485
+ className: "sr-only",
486
+ "aria-label": "Take a photo"
487
+ }
488
+ ),
489
+ /* @__PURE__ */ jsxRuntime.jsx(
490
+ "button",
491
+ {
492
+ type: "button",
493
+ onClick: handleClick,
494
+ disabled,
495
+ className: chunkOR5DRJCW_cjs.cn(
496
+ "inline-flex items-center justify-center",
497
+ "rounded-full p-2",
498
+ "text-neutral-500 hover:text-neutral-700",
499
+ "dark:text-neutral-400 dark:hover:text-neutral-200",
500
+ "hover:bg-neutral-100 dark:hover:bg-neutral-800",
501
+ "focus:ring-primary-500 focus:ring-2 focus:outline-none",
502
+ "disabled:cursor-not-allowed disabled:opacity-50",
503
+ "transition-colors",
504
+ className
505
+ ),
506
+ "aria-label": "Take a photo",
507
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
508
+ "svg",
509
+ {
510
+ "aria-hidden": "true",
511
+ className: "h-5 w-5",
512
+ fill: "none",
513
+ viewBox: "0 0 24 24",
514
+ stroke: "currentColor",
515
+ children: [
516
+ /* @__PURE__ */ jsxRuntime.jsx(
517
+ "path",
518
+ {
519
+ strokeLinecap: "round",
520
+ strokeLinejoin: "round",
521
+ strokeWidth: 2,
522
+ d: "M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z"
523
+ }
524
+ ),
525
+ /* @__PURE__ */ jsxRuntime.jsx(
526
+ "path",
527
+ {
528
+ strokeLinecap: "round",
529
+ strokeLinejoin: "round",
530
+ strokeWidth: 2,
531
+ d: "M15 13a3 3 0 11-6 0 3 3 0 016 0z"
532
+ }
533
+ )
534
+ ]
535
+ }
536
+ )
537
+ }
538
+ )
539
+ ] });
540
+ }
541
+ CameraButton.displayName = "CameraButton";
542
+ function activeMentionQuery(value, caret) {
543
+ const upToCaret = value.slice(0, caret);
544
+ const match = /(^|\s)@([^\s@]*)$/.exec(upToCaret);
545
+ if (!match) return null;
546
+ const query = match[2];
547
+ return { query, start: caret - query.length - 1 };
548
+ }
549
+ function isFileAccepted(file, accepted) {
550
+ if (!accepted || accepted.length === 0) return true;
551
+ const mime = file.type;
552
+ const name = file.name.toLowerCase();
553
+ return accepted.some((token) => {
554
+ if (token.startsWith(".")) return name.endsWith(token.toLowerCase());
555
+ if (token.endsWith("/*")) return mime.startsWith(token.slice(0, -1));
556
+ if (token.includes("/")) return mime === token;
557
+ return false;
558
+ });
559
+ }
560
+ function CharacterCounter({
561
+ current,
562
+ max,
563
+ showWarningAt = 0.9,
564
+ className
565
+ }) {
566
+ const percentage = current / max;
567
+ const isWarning = percentage >= showWarningAt && percentage < 1;
568
+ const isOver = current > max;
569
+ return /* @__PURE__ */ jsxRuntime.jsxs(
570
+ "span",
571
+ {
572
+ className: chunkOR5DRJCW_cjs.cn(
573
+ "text-xs tabular-nums",
574
+ isOver ? "font-medium text-red-700 dark:text-red-400" : isWarning ? "text-amber-700 dark:text-amber-400" : "text-neutral-600 dark:text-neutral-400",
575
+ className
576
+ ),
577
+ "aria-live": "polite",
578
+ "aria-label": `${current} of ${max} characters`,
579
+ children: [
580
+ current,
581
+ "/",
582
+ max
583
+ ]
584
+ }
585
+ );
586
+ }
587
+ CharacterCounter.displayName = "CharacterCounter";
588
+ var sendButtonVariants = classVarianceAuthority.cva(
589
+ [
590
+ "inline-flex items-center justify-center",
591
+ "rounded-full p-3 self-start",
592
+ "transition-all duration-200",
593
+ "focus:outline-none focus:ring-2 focus:ring-primary-500",
594
+ "disabled:opacity-50 disabled:cursor-not-allowed"
595
+ ],
596
+ {
597
+ variants: {
598
+ variant: {
599
+ primary: [
600
+ "bg-primary-800 text-white",
601
+ "hover:bg-primary-900",
602
+ "active:scale-95"
603
+ ],
604
+ subtle: [
605
+ "bg-transparent text-primary-800",
606
+ "hover:bg-primary-50 dark:hover:bg-primary-900/20"
607
+ ]
608
+ },
609
+ canSend: {
610
+ true: "",
611
+ false: "opacity-50 cursor-not-allowed"
612
+ }
613
+ },
614
+ defaultVariants: {
615
+ variant: "primary",
616
+ canSend: false
617
+ }
618
+ }
619
+ );
620
+ var SendButton = React2__namespace.forwardRef(
621
+ ({ className, variant, canSend, isLoading, disabled, ...props }, ref) => {
622
+ return /* @__PURE__ */ jsxRuntime.jsx(
623
+ "button",
624
+ {
625
+ ref,
626
+ type: "submit",
627
+ disabled: disabled || !canSend || isLoading,
628
+ "data-slot": "composer-send-button",
629
+ className: chunkOR5DRJCW_cjs.cn(sendButtonVariants({ variant, canSend }), className),
630
+ "aria-label": isLoading ? "Sending message" : "Send message",
631
+ ...props,
632
+ children: isLoading ? /* @__PURE__ */ jsxRuntime.jsxs(
633
+ "svg",
634
+ {
635
+ "aria-hidden": "true",
636
+ className: "h-5 w-5 animate-spin",
637
+ fill: "none",
638
+ viewBox: "0 0 24 24",
639
+ children: [
640
+ /* @__PURE__ */ jsxRuntime.jsx(
641
+ "circle",
642
+ {
643
+ className: "opacity-25",
644
+ cx: "12",
645
+ cy: "12",
646
+ r: "10",
647
+ stroke: "currentColor",
648
+ strokeWidth: "4"
649
+ }
650
+ ),
651
+ /* @__PURE__ */ jsxRuntime.jsx(
652
+ "path",
653
+ {
654
+ className: "opacity-75",
655
+ fill: "currentColor",
656
+ d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
657
+ }
658
+ )
659
+ ]
660
+ }
661
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
662
+ "svg",
663
+ {
664
+ "aria-hidden": "true",
665
+ className: "h-5 w-5",
666
+ fill: "none",
667
+ viewBox: "0 0 24 24",
668
+ stroke: "currentColor",
669
+ children: /* @__PURE__ */ jsxRuntime.jsx(
670
+ "path",
671
+ {
672
+ strokeLinecap: "round",
673
+ strokeLinejoin: "round",
674
+ strokeWidth: 2,
675
+ d: "M12 19l9 2-9-18-9 18 9-2zm0 0v-8"
676
+ }
677
+ )
678
+ }
679
+ )
680
+ }
681
+ );
682
+ }
683
+ );
684
+ SendButton.displayName = "SendButton";
685
+ var MessageComposer = React2__namespace.forwardRef(
686
+ ({
687
+ onSend,
688
+ onTypingStart,
689
+ onTypingStop,
690
+ value: controlledValue,
691
+ onValueChange,
692
+ placeholder = "Type a message...",
693
+ maxLength = 1600,
694
+ showCharacterCount = false,
695
+ disabled = false,
696
+ isSending = false,
697
+ showAttachmentPicker = true,
698
+ showCameraButton = false,
699
+ acceptedFileTypes = ["image/*", "video/*", ".pdf", ".doc", ".docx"],
700
+ maxFileSize = 25 * 1024 * 1024,
701
+ maxAttachments = 10,
702
+ onError,
703
+ autoFocus = false,
704
+ replyTo = null,
705
+ onCancelReply,
706
+ variant = "default",
707
+ inputTrailing,
708
+ mentionOptions,
709
+ className
710
+ }, ref) => {
711
+ const textareaRef = React2__namespace.useRef(null);
712
+ const [internalContent, setInternalContent] = React2__namespace.useState("");
713
+ const isControlled = controlledValue !== void 0;
714
+ const content = isControlled ? controlledValue : internalContent;
715
+ const setContent = React2__namespace.useCallback(
716
+ (val) => {
717
+ if (isControlled) {
718
+ const newVal = typeof val === "function" ? val(controlledValue) : val;
719
+ onValueChange?.(newVal);
720
+ } else {
721
+ setInternalContent(val);
722
+ }
723
+ },
724
+ [isControlled, controlledValue, onValueChange]
725
+ );
726
+ const [attachments, setAttachments] = React2__namespace.useState(
727
+ []
728
+ );
729
+ const [isTyping, setIsTyping] = React2__namespace.useState(false);
730
+ const typingTimeoutRef = React2__namespace.useRef(null);
731
+ React2__namespace.useImperativeHandle(ref, () => textareaRef.current);
732
+ React2__namespace.useEffect(() => {
733
+ const textarea = textareaRef.current;
734
+ if (textarea) {
735
+ textarea.style.height = "auto";
736
+ textarea.style.height = `${Math.min(textarea.scrollHeight, 150)}px`;
737
+ }
738
+ }, [content]);
739
+ React2__namespace.useEffect(() => {
740
+ if (content.length > 0 && !isTyping) {
741
+ setIsTyping(true);
742
+ onTypingStart?.();
743
+ }
744
+ if (typingTimeoutRef.current) {
745
+ clearTimeout(typingTimeoutRef.current);
746
+ }
747
+ typingTimeoutRef.current = setTimeout(() => {
748
+ if (isTyping) {
749
+ setIsTyping(false);
750
+ onTypingStop?.();
751
+ }
752
+ }, 2e3);
753
+ return () => {
754
+ if (typingTimeoutRef.current) {
755
+ clearTimeout(typingTimeoutRef.current);
756
+ }
757
+ };
758
+ }, [content, isTyping, onTypingStart, onTypingStop]);
759
+ React2__namespace.useEffect(() => {
760
+ if (autoFocus) {
761
+ textareaRef.current?.focus();
762
+ }
763
+ }, [autoFocus]);
764
+ React2__namespace.useEffect(() => {
765
+ if (replyTo) {
766
+ textareaRef.current?.focus();
767
+ }
768
+ }, [replyTo]);
769
+ const mentionsEnabled = !!mentionOptions && mentionOptions.length > 0;
770
+ const [mention, setMention] = React2__namespace.useState(null);
771
+ const [mentionHighlight, setMentionHighlight] = React2__namespace.useState(0);
772
+ const mentionListId = React2__namespace.useId();
773
+ const mentionOptionId = (i) => `${mentionListId}-option-${i}`;
774
+ const mentionSuggestions = React2__namespace.useMemo(() => {
775
+ if (!mention || !mentionOptions) return [];
776
+ const q = mention.query.toLowerCase();
777
+ return mentionOptions.filter((o) => o.label.toLowerCase().includes(q));
778
+ }, [mention, mentionOptions]);
779
+ const mentionMenuOpen = mentionsEnabled && mention !== null && mentionSuggestions.length > 0;
780
+ const clampedMentionHighlight = mentionMenuOpen ? Math.min(mentionHighlight, mentionSuggestions.length - 1) : -1;
781
+ const activeMentionOptionId = mentionMenuOpen ? mentionOptionId(clampedMentionHighlight) : void 0;
782
+ const syncMention = React2__namespace.useCallback(
783
+ (value, caret) => {
784
+ if (!mentionsEnabled) return;
785
+ setMention(activeMentionQuery(value, caret));
786
+ setMentionHighlight(0);
787
+ },
788
+ [mentionsEnabled]
789
+ );
790
+ const insertMention = (option) => {
791
+ if (!mention) return;
792
+ const insertValue = option.value ?? option.label.split(" ")[0];
793
+ const before = content.slice(0, mention.start);
794
+ const after = content.slice(mention.start + 1 + mention.query.length);
795
+ const insert = `@${insertValue} `;
796
+ setContent(before + insert + after);
797
+ setMention(null);
798
+ const caret = before.length + insert.length;
799
+ requestAnimationFrame(() => {
800
+ const el = textareaRef.current;
801
+ if (el) {
802
+ el.focus();
803
+ el.setSelectionRange(caret, caret);
804
+ }
805
+ });
806
+ };
807
+ const canSend = (content.trim().length > 0 || attachments.length > 0) && content.length <= maxLength && !disabled && !isSending;
808
+ const handleSubmit = async (event) => {
809
+ event.preventDefault();
810
+ if (!canSend) return;
811
+ const message = {
812
+ content: content.trim(),
813
+ attachments: attachments.map((a) => a.file),
814
+ replyToId: replyTo?.id
815
+ };
816
+ setContent("");
817
+ setAttachments([]);
818
+ setIsTyping(false);
819
+ onTypingStop?.();
820
+ try {
821
+ await onSend(message);
822
+ } catch {
823
+ setContent(message.content);
824
+ onError?.("Failed to send message");
825
+ }
826
+ };
827
+ const handleKeyDown = (event) => {
828
+ if (mentionMenuOpen) {
829
+ if (event.key === "ArrowDown") {
830
+ event.preventDefault();
831
+ setMentionHighlight((h) => (h + 1) % mentionSuggestions.length);
832
+ return;
833
+ }
834
+ if (event.key === "ArrowUp") {
835
+ event.preventDefault();
836
+ setMentionHighlight(
837
+ (h) => (h - 1 + mentionSuggestions.length) % mentionSuggestions.length
838
+ );
839
+ return;
840
+ }
841
+ if (event.key === "Enter" || event.key === "Tab") {
842
+ event.preventDefault();
843
+ const chosen = mentionSuggestions[mentionHighlight] ?? mentionSuggestions[0];
844
+ if (chosen) insertMention(chosen);
845
+ return;
846
+ }
847
+ if (event.key === "Escape") {
848
+ event.preventDefault();
849
+ setMention(null);
850
+ return;
851
+ }
852
+ }
853
+ if (event.key === "Enter" && !event.shiftKey) {
854
+ event.preventDefault();
855
+ if (canSend) {
856
+ handleSubmit(event);
857
+ }
858
+ }
859
+ };
860
+ const handleFilesSelected = (files) => {
861
+ const remainingSlots = maxAttachments - attachments.length;
862
+ const filesToAdd = files.slice(0, remainingSlots);
863
+ if (files.length > remainingSlots) {
864
+ onError?.(`Maximum ${maxAttachments} attachments allowed`);
865
+ }
866
+ const newAttachments = filesToAdd.map((file) => {
867
+ const type = getFileType(file.type);
868
+ let previewUrl;
869
+ if (type === "image" || type === "video") {
870
+ previewUrl = URL.createObjectURL(file);
871
+ }
872
+ return {
873
+ id: generateAttachmentId(),
874
+ file,
875
+ previewUrl,
876
+ type,
877
+ state: "pending"
878
+ };
879
+ });
880
+ setAttachments((prev) => [...prev, ...newAttachments]);
881
+ };
882
+ const handlePaste = (event) => {
883
+ if (!showAttachmentPicker || disabled) return;
884
+ const pasted = Array.from(event.clipboardData.items).filter((item) => item.kind === "file").map((item) => item.getAsFile()).filter((f) => f !== null).filter((f) => isFileAccepted(f, acceptedFileTypes));
885
+ if (pasted.length === 0) return;
886
+ event.preventDefault();
887
+ handleFilesSelected(pasted);
888
+ };
889
+ const handleRemoveAttachment = (attachmentId) => {
890
+ setAttachments((prev) => {
891
+ const attachment = prev.find((a) => a.id === attachmentId);
892
+ if (attachment?.previewUrl) {
893
+ URL.revokeObjectURL(attachment.previewUrl);
894
+ }
895
+ return prev.filter((a) => a.id !== attachmentId);
896
+ });
897
+ };
898
+ React2__namespace.useEffect(() => {
899
+ const currentAttachments = attachments;
900
+ return () => {
901
+ currentAttachments.forEach((a) => {
902
+ if (a.previewUrl) {
903
+ URL.revokeObjectURL(a.previewUrl);
904
+ }
905
+ });
906
+ };
907
+ }, [attachments]);
908
+ return /* @__PURE__ */ jsxRuntime.jsx(
909
+ DragDropZone,
910
+ {
911
+ onFilesDropped: handleFilesSelected,
912
+ acceptedTypes: acceptedFileTypes,
913
+ maxFileSize,
914
+ maxFiles: maxAttachments - attachments.length,
915
+ disabled: disabled || attachments.length >= maxAttachments,
916
+ onError,
917
+ className: chunkOR5DRJCW_cjs.cn("w-full", className),
918
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
919
+ "form",
920
+ {
921
+ onSubmit: handleSubmit,
922
+ "data-slot": "message-composer",
923
+ className: "w-full",
924
+ children: [
925
+ replyTo && /* @__PURE__ */ jsxRuntime.jsxs(
926
+ "div",
927
+ {
928
+ "data-slot": "composer-reply-preview",
929
+ className: chunkOR5DRJCW_cjs.cn(
930
+ "flex items-center gap-2 px-4 py-2",
931
+ "bg-neutral-50 dark:bg-neutral-800/50",
932
+ "border-primary-500 border-l-4"
933
+ ),
934
+ children: [
935
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
936
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-primary-800 dark:text-primary-400 text-xs font-medium", children: [
937
+ "Replying to ",
938
+ replyTo.senderName
939
+ ] }),
940
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate text-sm text-neutral-600 dark:text-neutral-300", children: replyTo.content })
941
+ ] }),
942
+ /* @__PURE__ */ jsxRuntime.jsx(
943
+ "button",
944
+ {
945
+ type: "button",
946
+ onClick: onCancelReply,
947
+ className: chunkOR5DRJCW_cjs.cn(
948
+ "shrink-0 rounded p-1",
949
+ "text-neutral-500 hover:text-neutral-700",
950
+ "dark:text-neutral-400 dark:hover:text-neutral-200",
951
+ "focus:ring-primary-500 focus:ring-2 focus:outline-none"
952
+ ),
953
+ "aria-label": "Cancel reply",
954
+ children: /* @__PURE__ */ jsxRuntime.jsx(
955
+ "svg",
956
+ {
957
+ "aria-hidden": "true",
958
+ className: "h-4 w-4",
959
+ fill: "none",
960
+ viewBox: "0 0 24 24",
961
+ stroke: "currentColor",
962
+ children: /* @__PURE__ */ jsxRuntime.jsx(
963
+ "path",
964
+ {
965
+ strokeLinecap: "round",
966
+ strokeLinejoin: "round",
967
+ strokeWidth: 2,
968
+ d: "M6 18L18 6M6 6l12 12"
969
+ }
970
+ )
971
+ }
972
+ )
973
+ }
974
+ )
975
+ ]
976
+ }
977
+ ),
978
+ attachments.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
979
+ "div",
980
+ {
981
+ "data-slot": "composer-attachments",
982
+ className: chunkOR5DRJCW_cjs.cn(
983
+ "flex flex-wrap gap-2 p-3",
984
+ "border-t border-neutral-200 dark:border-neutral-700"
985
+ ),
986
+ children: attachments.map((attachment) => /* @__PURE__ */ jsxRuntime.jsx(
987
+ AttachmentPreviewItem,
988
+ {
989
+ attachment,
990
+ onRemove: () => handleRemoveAttachment(attachment.id)
991
+ },
992
+ attachment.id
993
+ ))
994
+ }
995
+ ),
996
+ /* @__PURE__ */ jsxRuntime.jsxs(
997
+ "div",
998
+ {
999
+ "data-slot": "composer-input-area",
1000
+ className: chunkOR5DRJCW_cjs.cn(
1001
+ "flex items-center gap-2 p-3",
1002
+ "bg-white dark:bg-neutral-900",
1003
+ variant === "default" && "border-t border-neutral-200 dark:border-neutral-700"
1004
+ ),
1005
+ children: [
1006
+ showAttachmentPicker && /* @__PURE__ */ jsxRuntime.jsx(
1007
+ AttachmentPicker,
1008
+ {
1009
+ onFilesSelected: handleFilesSelected,
1010
+ acceptedTypes: acceptedFileTypes,
1011
+ maxFileSize,
1012
+ maxFiles: maxAttachments - attachments.length,
1013
+ disabled: disabled || attachments.length >= maxAttachments,
1014
+ onError
1015
+ }
1016
+ ),
1017
+ showCameraButton && /* @__PURE__ */ jsxRuntime.jsx(
1018
+ CameraButton,
1019
+ {
1020
+ onCapture: (file) => handleFilesSelected([file]),
1021
+ disabled: disabled || attachments.length >= maxAttachments
1022
+ }
1023
+ ),
1024
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "composer-input-wrapper", className: "relative flex-1", children: [
1025
+ mentionMenuOpen && /* @__PURE__ */ jsxRuntime.jsx(
1026
+ "ul",
1027
+ {
1028
+ id: mentionListId,
1029
+ role: "listbox",
1030
+ "aria-label": "Mention",
1031
+ "data-slot": "composer-mention-list",
1032
+ className: "absolute bottom-full left-0 z-10 mb-1 max-h-56 w-64 overflow-y-auto rounded-lg border border-neutral-200 bg-white py-1 shadow-lg dark:border-neutral-700 dark:bg-neutral-800",
1033
+ children: mentionSuggestions.map((option, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsxs(
1034
+ "button",
1035
+ {
1036
+ type: "button",
1037
+ id: mentionOptionId(i),
1038
+ role: "option",
1039
+ "aria-selected": i === clampedMentionHighlight,
1040
+ onMouseDown: (e) => {
1041
+ e.preventDefault();
1042
+ insertMention(option);
1043
+ },
1044
+ onMouseEnter: () => setMentionHighlight(i),
1045
+ className: chunkOR5DRJCW_cjs.cn(
1046
+ "flex w-full items-center gap-2 px-3 py-1.5 text-left text-sm",
1047
+ i === clampedMentionHighlight ? "bg-primary-100 text-primary-900 dark:bg-primary-900/40 dark:text-primary-100" : "text-neutral-700 dark:text-neutral-200"
1048
+ ),
1049
+ children: [
1050
+ option.icon,
1051
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 flex-1 truncate", children: [
1052
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: option.label }),
1053
+ option.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-xs text-neutral-400", children: option.description })
1054
+ ] }),
1055
+ option.meta && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-neutral-400", children: option.meta })
1056
+ ]
1057
+ }
1058
+ ) }, option.id))
1059
+ }
1060
+ ),
1061
+ /* @__PURE__ */ jsxRuntime.jsx(
1062
+ "textarea",
1063
+ {
1064
+ ref: textareaRef,
1065
+ "data-slot": "composer-input",
1066
+ value: content,
1067
+ onChange: (e) => {
1068
+ setContent(e.target.value);
1069
+ syncMention(
1070
+ e.target.value,
1071
+ e.target.selectionStart ?? e.target.value.length
1072
+ );
1073
+ },
1074
+ onClick: (e) => {
1075
+ const el = e.currentTarget;
1076
+ syncMention(el.value, el.selectionStart ?? el.value.length);
1077
+ },
1078
+ onKeyDown: handleKeyDown,
1079
+ onPaste: handlePaste,
1080
+ placeholder,
1081
+ disabled: disabled || isSending,
1082
+ rows: 1,
1083
+ className: chunkOR5DRJCW_cjs.cn(
1084
+ "w-full resize-none rounded-2xl py-2.5",
1085
+ inputTrailing ? "pr-10 pl-4" : "px-4",
1086
+ "bg-neutral-100 dark:bg-neutral-800",
1087
+ "text-neutral-900 dark:text-neutral-100",
1088
+ "placeholder:text-neutral-400 dark:placeholder:text-neutral-500",
1089
+ "focus:ring-primary-500 focus:ring-2 focus:outline-none",
1090
+ "disabled:cursor-not-allowed disabled:opacity-50",
1091
+ "transition-colors",
1092
+ "max-h-[150px]"
1093
+ ),
1094
+ "aria-label": "Message",
1095
+ "aria-describedby": showCharacterCount ? "char-count" : void 0,
1096
+ ...mentionsEnabled ? {
1097
+ role: "combobox",
1098
+ "aria-expanded": mentionMenuOpen,
1099
+ "aria-controls": mentionMenuOpen ? mentionListId : void 0,
1100
+ "aria-activedescendant": activeMentionOptionId,
1101
+ "aria-autocomplete": "list",
1102
+ "aria-haspopup": "listbox"
1103
+ } : {}
1104
+ }
1105
+ ),
1106
+ inputTrailing && /* @__PURE__ */ jsxRuntime.jsx(
1107
+ "div",
1108
+ {
1109
+ "data-slot": "composer-input-trailing",
1110
+ className: "pointer-events-none absolute top-0 right-1 flex h-[44px] items-center [&>*]:pointer-events-auto",
1111
+ children: inputTrailing
1112
+ }
1113
+ ),
1114
+ showCharacterCount && /* @__PURE__ */ jsxRuntime.jsx(
1115
+ "div",
1116
+ {
1117
+ "data-slot": "composer-char-count",
1118
+ id: "char-count",
1119
+ className: "absolute right-3 bottom-1.5",
1120
+ children: /* @__PURE__ */ jsxRuntime.jsx(CharacterCounter, { current: content.length, max: maxLength })
1121
+ }
1122
+ )
1123
+ ] }),
1124
+ /* @__PURE__ */ jsxRuntime.jsx(
1125
+ SendButton,
1126
+ {
1127
+ canSend,
1128
+ isLoading: isSending,
1129
+ disabled
1130
+ }
1131
+ )
1132
+ ]
1133
+ }
1134
+ )
1135
+ ]
1136
+ }
1137
+ )
1138
+ }
1139
+ );
1140
+ }
1141
+ );
1142
+ MessageComposer.displayName = "MessageComposer";
1143
+
1144
+ exports.AttachmentPicker = AttachmentPicker;
1145
+ exports.AttachmentPreviewItem = AttachmentPreviewItem;
1146
+ exports.CameraButton = CameraButton;
1147
+ exports.CharacterCounter = CharacterCounter;
1148
+ exports.DragDropZone = DragDropZone;
1149
+ exports.MessageComposer = MessageComposer;
1150
+ exports.SendButton = SendButton;
1151
+ exports.generateAttachmentId = generateAttachmentId;
1152
+ exports.getFileType = getFileType;
1153
+ exports.sendButtonVariants = sendButtonVariants;
1154
+ exports.validateFile = validateFile;
1155
+ //# sourceMappingURL=chunk-2T4JU5RH.cjs.map
1156
+ //# sourceMappingURL=chunk-2T4JU5RH.cjs.map