@meshagent/meshagent-tailwind 0.39.8 → 0.40.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 (111) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/cjs/{ChatBotView.js → chat/chat-bot-view.js} +37 -22
  3. package/dist/cjs/{chat-hooks.d.ts → chat/chat-hooks.d.ts} +5 -1
  4. package/dist/cjs/{chat-hooks.js → chat/chat-hooks.js} +12 -2
  5. package/dist/cjs/{ChatInput.js → chat/chat-input.js} +9 -9
  6. package/dist/cjs/chat/chat-thread.d.ts +12 -0
  7. package/dist/cjs/{ChatThread.js → chat/chat-thread.js} +75 -28
  8. package/dist/cjs/{ChatTypingIndicator.js → chat/chat-typing-indicator.js} +4 -4
  9. package/dist/{esm → cjs/chat}/conversation-descriptor.d.ts +7 -1
  10. package/dist/cjs/{conversation-descriptor.js → chat/conversation-descriptor.js} +41 -7
  11. package/dist/cjs/chat/dataset-chat-thread.d.ts +13 -0
  12. package/dist/cjs/chat/dataset-chat-thread.js +1840 -0
  13. package/dist/cjs/{FileUploader.js → chat/file-uploader.js} +4 -4
  14. package/dist/cjs/{multi-thread-view.js → chat/multi-thread-view.js} +8 -3
  15. package/dist/cjs/chat/new-chat-thread.d.ts +17 -0
  16. package/dist/cjs/{Chat.js → chat/new-chat-thread.js} +43 -168
  17. package/dist/cjs/{UploadPill.js → chat/upload-pill.js} +5 -5
  18. package/dist/cjs/file-preview/file-preview.d.ts +34 -0
  19. package/dist/cjs/file-preview/file-preview.js +329 -0
  20. package/dist/cjs/forms/email-address.d.ts +10 -0
  21. package/dist/cjs/forms/email-address.js +105 -0
  22. package/dist/cjs/forms/form.d.ts +27 -0
  23. package/dist/cjs/forms/form.js +200 -0
  24. package/dist/cjs/forms/multi-select-autocomplete.d.ts +35 -0
  25. package/dist/cjs/forms/multi-select-autocomplete.js +294 -0
  26. package/dist/cjs/forms/select-users-dialog.d.ts +20 -0
  27. package/dist/cjs/forms/select-users-dialog.js +145 -0
  28. package/dist/cjs/forms/select-users.d.ts +16 -0
  29. package/dist/cjs/forms/select-users.js +117 -0
  30. package/dist/cjs/index.d.ts +19 -11
  31. package/dist/cjs/index.js +19 -11
  32. package/dist/cjs/meetings/audio-visualization.d.ts +7 -0
  33. package/dist/cjs/meetings/audio-visualization.js +74 -0
  34. package/dist/cjs/meetings/controls.d.ts +19 -0
  35. package/dist/cjs/meetings/controls.js +300 -0
  36. package/dist/cjs/meetings/meeting-scope.d.ts +83 -0
  37. package/dist/cjs/meetings/meeting-scope.js +309 -0
  38. package/dist/cjs/meetings/meetings.d.ts +5 -0
  39. package/dist/cjs/meetings/meetings.js +22 -0
  40. package/dist/cjs/meetings/participants.d.ts +13 -0
  41. package/dist/cjs/meetings/participants.js +154 -0
  42. package/dist/cjs/meetings/wake-lock.d.ts +4 -0
  43. package/dist/cjs/meetings/wake-lock.js +55 -0
  44. package/dist/esm/{ChatBotView.js → chat/chat-bot-view.js} +34 -19
  45. package/dist/esm/{chat-hooks.d.ts → chat/chat-hooks.d.ts} +5 -1
  46. package/dist/esm/{chat-hooks.js → chat/chat-hooks.js} +12 -2
  47. package/dist/esm/{ChatInput.js → chat/chat-input.js} +4 -4
  48. package/dist/esm/chat/chat-thread.d.ts +12 -0
  49. package/dist/esm/{ChatThread.js → chat/chat-thread.js} +70 -23
  50. package/dist/esm/{ChatTypingIndicator.js → chat/chat-typing-indicator.js} +1 -1
  51. package/dist/{cjs → esm/chat}/conversation-descriptor.d.ts +7 -1
  52. package/dist/esm/{conversation-descriptor.js → chat/conversation-descriptor.js} +41 -7
  53. package/dist/esm/chat/dataset-chat-thread.d.ts +13 -0
  54. package/dist/esm/chat/dataset-chat-thread.js +1815 -0
  55. package/dist/esm/{FileUploader.js → chat/file-uploader.js} +1 -1
  56. package/dist/esm/{multi-thread-view.js → chat/multi-thread-view.js} +8 -3
  57. package/dist/esm/chat/new-chat-thread.d.ts +17 -0
  58. package/dist/esm/{Chat.js → chat/new-chat-thread.js} +40 -165
  59. package/dist/esm/{UploadPill.js → chat/upload-pill.js} +2 -2
  60. package/dist/esm/file-preview/file-preview.d.ts +34 -0
  61. package/dist/esm/file-preview/file-preview.js +316 -0
  62. package/dist/esm/forms/email-address.d.ts +10 -0
  63. package/dist/esm/forms/email-address.js +85 -0
  64. package/dist/esm/forms/form.d.ts +27 -0
  65. package/dist/esm/forms/form.js +193 -0
  66. package/dist/esm/forms/multi-select-autocomplete.d.ts +35 -0
  67. package/dist/esm/forms/multi-select-autocomplete.js +274 -0
  68. package/dist/esm/forms/select-users-dialog.d.ts +20 -0
  69. package/dist/esm/forms/select-users-dialog.js +132 -0
  70. package/dist/esm/forms/select-users.d.ts +16 -0
  71. package/dist/esm/forms/select-users.js +97 -0
  72. package/dist/esm/index.d.ts +19 -11
  73. package/dist/esm/index.js +19 -11
  74. package/dist/esm/meetings/audio-visualization.d.ts +7 -0
  75. package/dist/esm/meetings/audio-visualization.js +54 -0
  76. package/dist/esm/meetings/controls.d.ts +19 -0
  77. package/dist/esm/meetings/controls.js +294 -0
  78. package/dist/esm/meetings/meeting-scope.d.ts +83 -0
  79. package/dist/esm/meetings/meeting-scope.js +294 -0
  80. package/dist/esm/meetings/meetings.d.ts +5 -0
  81. package/dist/esm/meetings/meetings.js +5 -0
  82. package/dist/esm/meetings/participants.d.ts +13 -0
  83. package/dist/esm/meetings/participants.js +137 -0
  84. package/dist/esm/meetings/wake-lock.d.ts +4 -0
  85. package/dist/esm/meetings/wake-lock.js +35 -0
  86. package/dist/index.css +2 -2
  87. package/package.json +7 -4
  88. package/dist/cjs/Chat.d.ts +0 -15
  89. package/dist/cjs/ChatThread.d.ts +0 -21
  90. package/dist/esm/Chat.d.ts +0 -15
  91. package/dist/esm/ChatThread.d.ts +0 -21
  92. /package/dist/cjs/{ChatBotView.d.ts → chat/chat-bot-view.d.ts} +0 -0
  93. /package/dist/cjs/{ChatInput.d.ts → chat/chat-input.d.ts} +0 -0
  94. /package/dist/cjs/{chat-message.d.ts → chat/chat-message.d.ts} +0 -0
  95. /package/dist/cjs/{chat-message.js → chat/chat-message.js} +0 -0
  96. /package/dist/cjs/{ChatTypingIndicator.d.ts → chat/chat-typing-indicator.d.ts} +0 -0
  97. /package/dist/cjs/{file-attachment.d.ts → chat/file-attachment.d.ts} +0 -0
  98. /package/dist/cjs/{file-attachment.js → chat/file-attachment.js} +0 -0
  99. /package/dist/cjs/{FileUploader.d.ts → chat/file-uploader.d.ts} +0 -0
  100. /package/dist/cjs/{multi-thread-view.d.ts → chat/multi-thread-view.d.ts} +0 -0
  101. /package/dist/cjs/{UploadPill.d.ts → chat/upload-pill.d.ts} +0 -0
  102. /package/dist/esm/{ChatBotView.d.ts → chat/chat-bot-view.d.ts} +0 -0
  103. /package/dist/esm/{ChatInput.d.ts → chat/chat-input.d.ts} +0 -0
  104. /package/dist/esm/{chat-message.d.ts → chat/chat-message.d.ts} +0 -0
  105. /package/dist/esm/{chat-message.js → chat/chat-message.js} +0 -0
  106. /package/dist/esm/{ChatTypingIndicator.d.ts → chat/chat-typing-indicator.d.ts} +0 -0
  107. /package/dist/esm/{file-attachment.d.ts → chat/file-attachment.d.ts} +0 -0
  108. /package/dist/esm/{file-attachment.js → chat/file-attachment.js} +0 -0
  109. /package/dist/esm/{FileUploader.d.ts → chat/file-uploader.d.ts} +0 -0
  110. /package/dist/esm/{multi-thread-view.d.ts → chat/multi-thread-view.d.ts} +0 -0
  111. /package/dist/esm/{UploadPill.d.ts → chat/upload-pill.d.ts} +0 -0
@@ -0,0 +1,329 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var file_preview_exports = {};
20
+ __export(file_preview_exports, {
21
+ FileKind: () => FileKind,
22
+ FilePreview: () => FilePreview,
23
+ FilePreviewDialog: () => FilePreviewDialog,
24
+ ImagePreview: () => ImagePreview,
25
+ PdfPreview: () => PdfPreview,
26
+ VideoPreview: () => VideoPreview,
27
+ classifyFile: () => classifyFile,
28
+ filePreviewName: () => filePreviewName,
29
+ isImagePath: () => isImagePath
30
+ });
31
+ module.exports = __toCommonJS(file_preview_exports);
32
+ var import_jsx_runtime = require("react/jsx-runtime");
33
+ var import_react = require("react");
34
+ var import_lucide_react = require("lucide-react");
35
+ var import_react_pdf = require("react-pdf");
36
+ var import_dialog = require("../components/ui/dialog");
37
+ var import_button = require("../components/ui/button");
38
+ var import_spinner = require("../components/ui/spinner");
39
+ var import_utils = require("../lib/utils");
40
+ import_react_pdf.pdfjs.GlobalWorkerOptions.workerSrc = `https://unpkg.com/pdfjs-dist@${import_react_pdf.pdfjs.version}/build/pdf.worker.min.mjs`;
41
+ var FileKind = /* @__PURE__ */ ((FileKind2) => {
42
+ FileKind2["Image"] = "image";
43
+ FileKind2["Video"] = "video";
44
+ FileKind2["Pdf"] = "pdf";
45
+ FileKind2["Unknown"] = "unknown";
46
+ return FileKind2;
47
+ })(FileKind || {});
48
+ const imageExtensions = /* @__PURE__ */ new Set([
49
+ "avif",
50
+ "bmp",
51
+ "gif",
52
+ "heic",
53
+ "heif",
54
+ "jfif",
55
+ "jpeg",
56
+ "jpg",
57
+ "png",
58
+ "svg",
59
+ "svgz",
60
+ "tif",
61
+ "tiff",
62
+ "webp"
63
+ ]);
64
+ const videoExtensions = /* @__PURE__ */ new Set(["m4v", "mkv", "mov", "mp4", "webm"]);
65
+ const pdfExtensions = /* @__PURE__ */ new Set(["pdf"]);
66
+ function basename(path) {
67
+ const withoutQuery = path.split("?")[0] ?? path;
68
+ const withoutHash = withoutQuery.split("#")[0] ?? withoutQuery;
69
+ return withoutHash.split("/").pop() ?? withoutHash;
70
+ }
71
+ function extension(path) {
72
+ const name = basename(path).trim();
73
+ const dotIndex = name.lastIndexOf(".");
74
+ if (dotIndex < 0 || dotIndex === name.length - 1) {
75
+ return "";
76
+ }
77
+ return name.slice(dotIndex + 1).toLowerCase();
78
+ }
79
+ function isHttpUrl(path) {
80
+ return /^https?:\/\//iu.test(path.trim());
81
+ }
82
+ function filePreviewName(path) {
83
+ const name = basename(path).trim();
84
+ return name === "" ? "Attachment" : name;
85
+ }
86
+ function classifyFile(path) {
87
+ const ext = extension(path);
88
+ if (imageExtensions.has(ext)) {
89
+ return "image" /* Image */;
90
+ }
91
+ if (videoExtensions.has(ext)) {
92
+ return "video" /* Video */;
93
+ }
94
+ if (pdfExtensions.has(ext)) {
95
+ return "pdf" /* Pdf */;
96
+ }
97
+ return "unknown" /* Unknown */;
98
+ }
99
+ function isImagePath(path) {
100
+ return classifyFile(path) === "image" /* Image */;
101
+ }
102
+ function useDownloadUrl(room, path) {
103
+ const [url, setUrl] = (0, import_react.useState)(null);
104
+ const [error, setError] = (0, import_react.useState)(null);
105
+ (0, import_react.useEffect)(() => {
106
+ let cancelled = false;
107
+ const normalizedPath = path.trim();
108
+ setUrl(null);
109
+ setError(null);
110
+ if (normalizedPath === "") {
111
+ return;
112
+ }
113
+ if (isHttpUrl(normalizedPath)) {
114
+ setUrl(normalizedPath);
115
+ return;
116
+ }
117
+ void room.storage.downloadUrl(normalizedPath).then((nextUrl) => {
118
+ if (!cancelled) {
119
+ setUrl(nextUrl);
120
+ }
121
+ }).catch((nextError) => {
122
+ if (!cancelled) {
123
+ setError(nextError);
124
+ }
125
+ });
126
+ return () => {
127
+ cancelled = true;
128
+ };
129
+ }, [path, room]);
130
+ return { url, error };
131
+ }
132
+ function usePdfUrl(room, path) {
133
+ const [url, setUrl] = (0, import_react.useState)(null);
134
+ const [error, setError] = (0, import_react.useState)(null);
135
+ (0, import_react.useEffect)(() => {
136
+ let cancelled = false;
137
+ let objectUrl = null;
138
+ const normalizedPath = path.trim();
139
+ setUrl(null);
140
+ setError(null);
141
+ if (normalizedPath === "") {
142
+ return;
143
+ }
144
+ if (isHttpUrl(normalizedPath)) {
145
+ setUrl(normalizedPath);
146
+ return;
147
+ }
148
+ void room.storage.download(normalizedPath).then((content) => {
149
+ if (cancelled) {
150
+ return;
151
+ }
152
+ objectUrl = URL.createObjectURL(new Blob([content.data], { type: "application/pdf" }));
153
+ setUrl(objectUrl);
154
+ }).catch((nextError) => {
155
+ if (!cancelled) {
156
+ setError(nextError);
157
+ }
158
+ });
159
+ return () => {
160
+ cancelled = true;
161
+ if (objectUrl != null) {
162
+ URL.revokeObjectURL(objectUrl);
163
+ }
164
+ };
165
+ }, [path, room]);
166
+ return { url, error };
167
+ }
168
+ function ErrorPreview({ message }) {
169
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex h-full min-h-48 items-center justify-center p-6 text-center text-sm text-destructive", children: message });
170
+ }
171
+ function LoadingPreview() {
172
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex h-full min-h-48 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_spinner.Spinner, { className: "h-6 w-6" }) });
173
+ }
174
+ function DownloadButton({ room, path }) {
175
+ const { url } = useDownloadUrl(room, path);
176
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
177
+ import_button.Button,
178
+ {
179
+ type: "button",
180
+ variant: "outline",
181
+ size: "sm",
182
+ disabled: url == null,
183
+ onClick: () => {
184
+ if (url != null) {
185
+ window.open(url, "_blank", "noopener,noreferrer");
186
+ }
187
+ },
188
+ children: [
189
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Download, { className: "h-4 w-4" }),
190
+ "Download"
191
+ ]
192
+ }
193
+ );
194
+ }
195
+ function ImagePreview({
196
+ room,
197
+ path,
198
+ alt = filePreviewName(path)
199
+ }) {
200
+ const { url, error } = useDownloadUrl(room, path);
201
+ if (error != null) {
202
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorPreview, { message: `Unable to load image preview: ${String(error)}` });
203
+ }
204
+ if (url == null) {
205
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoadingPreview, {});
206
+ }
207
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { src: url, alt, className: "h-full max-h-full w-full object-contain" });
208
+ }
209
+ function VideoPreview({ room, path }) {
210
+ const { url, error } = useDownloadUrl(room, path);
211
+ if (error != null) {
212
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorPreview, { message: `Unable to load video preview: ${String(error)}` });
213
+ }
214
+ if (url == null) {
215
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoadingPreview, {});
216
+ }
217
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
218
+ "video",
219
+ {
220
+ src: url,
221
+ controls: true,
222
+ playsInline: true,
223
+ className: "h-full max-h-full w-full bg-black object-contain"
224
+ }
225
+ );
226
+ }
227
+ function useElementWidth() {
228
+ const ref = (0, import_react.useRef)(null);
229
+ const [width, setWidth] = (0, import_react.useState)(0);
230
+ (0, import_react.useEffect)(() => {
231
+ const element = ref.current;
232
+ if (element == null) {
233
+ return;
234
+ }
235
+ const updateWidth = () => {
236
+ setWidth(element.clientWidth);
237
+ };
238
+ updateWidth();
239
+ const observer = new ResizeObserver(updateWidth);
240
+ observer.observe(element);
241
+ return () => {
242
+ observer.disconnect();
243
+ };
244
+ }, []);
245
+ return [ref, width];
246
+ }
247
+ function PdfPreview({ room, path }) {
248
+ const { url, error } = usePdfUrl(room, path);
249
+ const [numPages, setNumPages] = (0, import_react.useState)(0);
250
+ const [containerRef, containerWidth] = useElementWidth();
251
+ const pageWidth = Math.max(Math.min(containerWidth, 960), 320);
252
+ if (error != null) {
253
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorPreview, { message: `Unable to load PDF: ${String(error)}` });
254
+ }
255
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: containerRef, className: "h-full overflow-auto bg-muted/30 p-4", children: url == null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoadingPreview, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
256
+ import_react_pdf.Document,
257
+ {
258
+ file: url,
259
+ loading: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoadingPreview, {}),
260
+ error: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorPreview, { message: "Unable to render PDF preview." }),
261
+ onLoadSuccess: ({ numPages: nextNumPages }) => {
262
+ setNumPages(nextNumPages);
263
+ },
264
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex flex-col items-center gap-4", children: Array.from({ length: numPages }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
265
+ import_react_pdf.Page,
266
+ {
267
+ pageNumber: index + 1,
268
+ width: pageWidth,
269
+ renderAnnotationLayer: false,
270
+ renderTextLayer: false,
271
+ loading: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-40" }),
272
+ className: "overflow-hidden rounded-md bg-background shadow-sm"
273
+ },
274
+ `page_${index + 1}`
275
+ )) })
276
+ }
277
+ ) });
278
+ }
279
+ function UnsupportedPreview({ room, path }) {
280
+ const filename = filePreviewName(path);
281
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex h-full min-h-64 flex-col items-center justify-center gap-4 p-8 text-center", children: [
282
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex h-14 w-14 items-center justify-center rounded-md border bg-muted/50", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.FileText, { className: "h-7 w-7 text-muted-foreground" }) }),
283
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "max-w-md space-y-1", children: [
284
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "truncate text-sm font-medium text-foreground", children: filename }),
285
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-sm text-muted-foreground", children: "No preview available for this file type." })
286
+ ] }),
287
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DownloadButton, { room, path })
288
+ ] });
289
+ }
290
+ function FilePreview({ room, path }) {
291
+ const kind = (0, import_react.useMemo)(() => classifyFile(path), [path]);
292
+ switch (kind) {
293
+ case "image" /* Image */:
294
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ImagePreview, { room, path });
295
+ case "video" /* Video */:
296
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VideoPreview, { room, path });
297
+ case "pdf" /* Pdf */:
298
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PdfPreview, { room, path });
299
+ case "unknown" /* Unknown */:
300
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(UnsupportedPreview, { room, path });
301
+ }
302
+ }
303
+ function FilePreviewDialog({
304
+ room,
305
+ path,
306
+ children,
307
+ className
308
+ }) {
309
+ const filename = filePreviewName(path);
310
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_dialog.Dialog, { children: [
311
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dialog.DialogTrigger, { asChild: true, children }),
312
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
313
+ import_dialog.DialogContent,
314
+ {
315
+ className: (0, import_utils.cn)(
316
+ "h-[min(90vh,900px)] max-w-[min(96vw,1100px)] grid-rows-[auto_minmax(0,1fr)] gap-0 p-0",
317
+ className
318
+ ),
319
+ children: [
320
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_dialog.DialogHeader, { className: "border-b px-4 py-3 pr-12", children: [
321
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dialog.DialogTitle, { className: "truncate text-base", children: filename }),
322
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dialog.DialogDescription, { className: "sr-only", children: "File preview" })
323
+ ] }),
324
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "min-h-0 flex-1 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FilePreview, { room, path }) })
325
+ ]
326
+ }
327
+ )
328
+ ] });
329
+ }
@@ -0,0 +1,10 @@
1
+ export declare class Address {
2
+ readonly mailAddress: string;
3
+ readonly name: string | null;
4
+ private static readonly quotableNameRegExp;
5
+ constructor(mailAddress: string, name?: string | null);
6
+ get sanitizedName(): string | null;
7
+ get sanitizedAddress(): string;
8
+ toString(): string;
9
+ }
10
+ export declare function parseEmailList(addresses: string): Address[];
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var email_address_exports = {};
20
+ __export(email_address_exports, {
21
+ Address: () => Address,
22
+ parseEmailList: () => parseEmailList
23
+ });
24
+ module.exports = __toCommonJS(email_address_exports);
25
+ class Address {
26
+ mailAddress;
27
+ name;
28
+ static quotableNameRegExp = /[",]/u;
29
+ constructor(mailAddress, name = null) {
30
+ this.mailAddress = mailAddress;
31
+ this.name = name;
32
+ }
33
+ get sanitizedName() {
34
+ if (this.name == null) {
35
+ return null;
36
+ }
37
+ if (Address.quotableNameRegExp.test(this.name)) {
38
+ return `"${this.name.replace(/"/gu, '\\"')}"`;
39
+ }
40
+ return this.name;
41
+ }
42
+ get sanitizedAddress() {
43
+ return this.mailAddress;
44
+ }
45
+ toString() {
46
+ return this.name == null ? this.mailAddress : `${this.name} <${this.mailAddress}>`;
47
+ }
48
+ }
49
+ function parseEmailList(addresses) {
50
+ const result = [];
51
+ const nameOrEmail = [];
52
+ const email = [];
53
+ const name = [];
54
+ let inQuote = false;
55
+ let inAngleBrackets = false;
56
+ const addAddress = () => {
57
+ if (nameOrEmail.length > 0) {
58
+ if (email.length === 0) {
59
+ email.push(...nameOrEmail);
60
+ } else if (name.length === 0) {
61
+ name.push(...nameOrEmail);
62
+ }
63
+ }
64
+ if (email.length > 0) {
65
+ const parsedName = name.join("").trim();
66
+ result.push(new Address(email.join("").trim(), parsedName === "" ? null : parsedName));
67
+ }
68
+ email.length = 0;
69
+ name.length = 0;
70
+ nameOrEmail.length = 0;
71
+ inAngleBrackets = false;
72
+ inQuote = false;
73
+ };
74
+ for (let index = 0; index < addresses.length; index += 1) {
75
+ const char = addresses[index];
76
+ if (inQuote) {
77
+ if (char === '"') {
78
+ inQuote = false;
79
+ } else if (char === "\\") {
80
+ index += 1;
81
+ if (index < addresses.length) {
82
+ name.push(addresses[index] ?? "");
83
+ }
84
+ } else if (char != null) {
85
+ name.push(char);
86
+ }
87
+ } else if (inAngleBrackets) {
88
+ if (char === ">") {
89
+ inAngleBrackets = false;
90
+ } else if (char != null) {
91
+ email.push(char);
92
+ }
93
+ } else if (char === "," || char === ";") {
94
+ addAddress();
95
+ } else if (char === '"') {
96
+ inQuote = true;
97
+ } else if (char === "<") {
98
+ inAngleBrackets = true;
99
+ } else if (char != null) {
100
+ nameOrEmail.push(char);
101
+ }
102
+ }
103
+ addAddress();
104
+ return result;
105
+ }
@@ -0,0 +1,27 @@
1
+ import type { ReactElement } from "react";
2
+ import { Element as MeshElement, MeshDocument, RoomClient } from "@meshagent/meshagent";
3
+ export type FormDocumentValue = string;
4
+ export type FormDocumentValues = Record<string, FormDocumentValue>;
5
+ type FormDocumentForm = any;
6
+ export declare function FormDocumentViewer({ document, client: _client, onSubmit, submitLabel, }: {
7
+ client?: RoomClient;
8
+ document: MeshDocument;
9
+ onSubmit?: (values: FormDocumentValues) => void;
10
+ submitLabel?: string;
11
+ }): ReactElement | null;
12
+ export declare function FormDocumentField({ element, name, form, }: {
13
+ element: MeshElement;
14
+ name: string;
15
+ form: FormDocumentForm;
16
+ }): ReactElement;
17
+ export declare function FormDocumentSelect({ element, name, form, }: {
18
+ element: MeshElement;
19
+ name: string;
20
+ form: FormDocumentForm;
21
+ }): ReactElement;
22
+ export declare function FormDocumentInput({ element, name, form, }: {
23
+ element: MeshElement;
24
+ name: string;
25
+ form: FormDocumentForm;
26
+ }): ReactElement;
27
+ export {};
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var form_exports = {};
20
+ __export(form_exports, {
21
+ FormDocumentField: () => FormDocumentField,
22
+ FormDocumentInput: () => FormDocumentInput,
23
+ FormDocumentSelect: () => FormDocumentSelect,
24
+ FormDocumentViewer: () => FormDocumentViewer
25
+ });
26
+ module.exports = __toCommonJS(form_exports);
27
+ var import_jsx_runtime = require("react/jsx-runtime");
28
+ var import_react = require("react");
29
+ var import_meshagent = require("@meshagent/meshagent");
30
+ var import_react_form = require("@tanstack/react-form");
31
+ var import_button = require("../components/ui/button");
32
+ var import_card = require("../components/ui/card");
33
+ var import_input = require("../components/ui/input");
34
+ var import_label = require("../components/ui/label");
35
+ var import_select = require("../components/ui/select");
36
+ var import_textarea = require("../components/ui/textarea");
37
+ function stringAttribute(element, name) {
38
+ const value = element.getAttribute(name);
39
+ return typeof value === "string" ? value : null;
40
+ }
41
+ function fieldName(element, index) {
42
+ return stringAttribute(element, "name") ?? stringAttribute(element, "$id") ?? stringAttribute(element, "id") ?? `${element.tagName}_${index}`;
43
+ }
44
+ function fieldDefaultValue(element) {
45
+ return stringAttribute(element, "value") ?? stringAttribute(element, "default_value") ?? stringAttribute(element, "defaultValue") ?? "";
46
+ }
47
+ function elementChildren(element) {
48
+ return element.getChildren().filter((child) => child instanceof import_meshagent.Element);
49
+ }
50
+ function formFields(document) {
51
+ return elementChildren(document.root);
52
+ }
53
+ function formDefaultValues(document) {
54
+ const values = {};
55
+ formFields(document).forEach((field, index) => {
56
+ values[fieldName(field, index)] = fieldDefaultValue(field);
57
+ });
58
+ return values;
59
+ }
60
+ function useDocumentVersion(document) {
61
+ const [version, setVersion] = (0, import_react.useState)(0);
62
+ (0, import_react.useEffect)(() => {
63
+ const onUpdated = () => setVersion((current) => current + 1);
64
+ document.on("updated", onUpdated);
65
+ return () => {
66
+ document.off("updated", onUpdated);
67
+ };
68
+ }, [document]);
69
+ return version;
70
+ }
71
+ function FieldText({
72
+ element,
73
+ fallbackName
74
+ }) {
75
+ return {
76
+ name: fallbackName,
77
+ label: stringAttribute(element, "label"),
78
+ description: stringAttribute(element, "description")
79
+ };
80
+ }
81
+ function FormDocumentViewer({
82
+ document,
83
+ client: _client,
84
+ onSubmit,
85
+ submitLabel = "Submit"
86
+ }) {
87
+ const version = useDocumentVersion(document);
88
+ const fields = (0, import_react.useMemo)(() => formFields(document), [document, version]);
89
+ const defaultValues = (0, import_react.useMemo)(() => formDefaultValues(document), [document, version]);
90
+ const title = stringAttribute(document.root, "title");
91
+ const description = stringAttribute(document.root, "description");
92
+ const form = (0, import_react_form.useForm)({
93
+ defaultValues,
94
+ onSubmit: ({ value }) => {
95
+ onSubmit?.(value);
96
+ }
97
+ });
98
+ (0, import_react.useEffect)(() => {
99
+ form.reset(defaultValues);
100
+ }, [defaultValues, form]);
101
+ if (fields.length === 0) {
102
+ return null;
103
+ }
104
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "px-4", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_card.Card, { children: [
105
+ title != null || description != null ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_card.CardHeader, { children: [
106
+ title != null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_card.CardTitle, { children: title }) : null,
107
+ description != null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_card.CardDescription, { children: description }) : null
108
+ ] }) : null,
109
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
110
+ "form",
111
+ {
112
+ onSubmit: (event) => {
113
+ event.preventDefault();
114
+ event.stopPropagation();
115
+ void form.handleSubmit();
116
+ },
117
+ children: [
118
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_card.CardContent, { className: "grid gap-6", children: fields.map((field, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
119
+ FormDocumentField,
120
+ {
121
+ element: field,
122
+ name: fieldName(field, index),
123
+ form
124
+ },
125
+ field.id ?? `${field.tagName}:${index}`
126
+ )) }),
127
+ onSubmit != null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_card.CardFooter, { className: "justify-end pt-6", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_button.Button, { type: "submit", children: submitLabel }) }) : null
128
+ ]
129
+ }
130
+ )
131
+ ] }) });
132
+ }
133
+ function FormDocumentField({
134
+ element,
135
+ name,
136
+ form
137
+ }) {
138
+ if (element.tagName === "select") {
139
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FormDocumentSelect, { element, name, form });
140
+ }
141
+ if (element.tagName === "input") {
142
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FormDocumentInput, { element, name, form });
143
+ }
144
+ throw new Error("Unexpected form field type");
145
+ }
146
+ function FormDocumentSelect({
147
+ element,
148
+ name,
149
+ form
150
+ }) {
151
+ const text = FieldText({ element, fallbackName: name });
152
+ const options = elementChildren(element).map((option) => ({
153
+ value: stringAttribute(option, "value") ?? "",
154
+ text: stringAttribute(option, "text") ?? stringAttribute(option, "value") ?? ""
155
+ }));
156
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(form.Field, { name, children: (field) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid gap-2", children: [
157
+ text.label != null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_label.Label, { htmlFor: field.name, children: text.label }) : null,
158
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
159
+ import_select.Select,
160
+ {
161
+ value: field.state.value,
162
+ onValueChange: (value) => field.handleChange(value),
163
+ children: [
164
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_select.SelectTrigger, { id: field.name, className: "w-full", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_select.SelectValue, { placeholder: "pick a value" }) }),
165
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_select.SelectContent, { children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_select.SelectItem, { value: option.value, children: option.text }, option.value)) })
166
+ ]
167
+ }
168
+ ),
169
+ text.description != null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm text-muted-foreground", children: text.description }) : null
170
+ ] }) });
171
+ }
172
+ function FormDocumentInput({
173
+ element,
174
+ name,
175
+ form
176
+ }) {
177
+ const text = FieldText({ element, fallbackName: name });
178
+ const multiline = element.getAttribute("multiline") === true || stringAttribute(element, "multiline") === "true";
179
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(form.Field, { name, children: (field) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid gap-2", children: [
180
+ text.label != null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_label.Label, { htmlFor: field.name, children: text.label }) : null,
181
+ multiline ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
182
+ import_textarea.Textarea,
183
+ {
184
+ id: field.name,
185
+ value: field.state.value,
186
+ onBlur: field.handleBlur,
187
+ onChange: (event) => field.handleChange(event.currentTarget.value)
188
+ }
189
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
190
+ import_input.Input,
191
+ {
192
+ id: field.name,
193
+ value: field.state.value,
194
+ onBlur: field.handleBlur,
195
+ onChange: (event) => field.handleChange(event.currentTarget.value)
196
+ }
197
+ ),
198
+ text.description != null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm text-muted-foreground", children: text.description }) : null
199
+ ] }) });
200
+ }