@apia/ai 3.0.1 → 3.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,62 @@
1
- export { ChatController, TMessageType } from './components/chat/ChatController.js';
2
- export { ChatMessage } from './components/chat/messages/ChatMessage.js';
3
- export { MultipleChoiceMessage, TMultipleChoiceMessageOption } from './components/chat/messages/MultipleChoiceMessage.js';
1
+ import * as react from 'react';
2
+ import { ReactNode, ReactElement } from 'react';
3
+ import { EventEmitter } from '@apia/util';
4
+
5
+ declare class ChatMessage {
6
+ #private;
7
+ messageType: TMessageType;
8
+ id: number;
9
+ parseMessage(message: string): string;
10
+ constructor(message: ReactNode, messageType: TMessageType);
11
+ get message(): ReactNode;
12
+ }
13
+
14
+ type TMessageType = 'user' | 'system' | 'warning' | 'error' | 'information' | 'response' | 'multipleChoice';
15
+ declare class ChatController extends EventEmitter<{
16
+ listChange: ChatMessage[];
17
+ messageSubmited?: string;
18
+ }> {
19
+ #private;
20
+ id: string;
21
+ constructor(id: string, welcomeMessage?: string);
22
+ components: {
23
+ MessageHistory: () => react.JSX.Element;
24
+ Textarea: {
25
+ ({ hideDeleteButton, isLoading: outIsLoading, onSubmit, preventAppendUserMessages, }: {
26
+ hideDeleteButton?: boolean | undefined;
27
+ isLoading?: boolean | undefined;
28
+ onSubmit: (text: string) => Promise<void>;
29
+ preventAppendUserMessages?: boolean | undefined;
30
+ }): react.JSX.Element;
31
+ displayName: string;
32
+ };
33
+ };
34
+ history: {
35
+ add: (prompt: string) => void;
36
+ next: () => string;
37
+ previous: () => string | undefined;
38
+ useList: () => ChatMessage[];
39
+ };
40
+ messages: {
41
+ add: (message: ChatMessage) => void;
42
+ clear: () => void;
43
+ };
44
+ }
45
+
46
+ type TMultipleChoiceMessageOption<OptionProps> = {
47
+ label: string;
48
+ url: string;
49
+ additionalProps?: OptionProps;
50
+ };
51
+ declare class MultipleChoiceMessage<OptionProps> extends ChatMessage {
52
+ private question;
53
+ private options;
54
+ private Renderer?;
55
+ constructor(question: string, options: TMultipleChoiceMessageOption<OptionProps>[], Renderer?: ((props: {
56
+ item: TMultipleChoiceMessageOption<OptionProps>;
57
+ }) => ReactElement) | undefined);
58
+ get message(): react.JSX.Element;
59
+ }
60
+
61
+ export { ChatController, ChatMessage, MultipleChoiceMessage, type TMessageType, type TMultipleChoiceMessageOption };
4
62
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,4 +1,606 @@
1
- export { ChatController } from './components/chat/ChatController.js';
2
- export { ChatMessage } from './components/chat/messages/ChatMessage.js';
3
- export { MultipleChoiceMessage } from './components/chat/messages/MultipleChoiceMessage.js';
1
+ import { jsx, jsxs, Fragment } from '@apia/theme/jsx-runtime';
2
+ import { Box, getVariant, Textarea, Paragraph } from '@apia/theme';
3
+ import { getLabel, EventEmitter } from '@apia/util';
4
+ import { useRef, useCallback, useState, useEffect } from 'react';
5
+ import { IconButton, SimpleButton, ApiaUtil } from '@apia/components';
6
+
7
+ const AutoscrollContainer = ({ children }) => {
8
+ const observer = useRef(null);
9
+ const unsuscribe = useRef(null);
10
+ const isFullScrolled = useRef(false);
11
+ const hasInited = useRef(false);
12
+ const ref = useCallback((el) => {
13
+ if (!el)
14
+ return;
15
+ if (!hasInited.current) {
16
+ hasInited.current = true;
17
+ el.scrollTo({
18
+ top: el.getBoundingClientRect().height,
19
+ behavior: "auto"
20
+ });
21
+ isFullScrolled.current = true;
22
+ }
23
+ observer.current?.disconnect();
24
+ unsuscribe.current?.();
25
+ observer.current = new MutationObserver(([mutation]) => {
26
+ if (mutation && mutation.target instanceof HTMLElement && mutation.target === el) {
27
+ if (isFullScrolled.current && mutation.target.scrollTop !== mutation.target.scrollHeight - mutation.target.offsetHeight) {
28
+ mutation.target.scrollTo({
29
+ top: mutation.target.scrollHeight,
30
+ behavior: "smooth"
31
+ });
32
+ }
33
+ }
34
+ });
35
+ observer.current.observe(el, { childList: true, subtree: true });
36
+ const handleScroll = (ev) => {
37
+ if (ev.target === el && el instanceof HTMLElement) {
38
+ setTimeout(() => {
39
+ isFullScrolled.current = Math.abs(el.scrollTop - (el.scrollHeight - el.offsetHeight)) < 150;
40
+ }, 100);
41
+ }
42
+ };
43
+ el.addEventListener("scroll", handleScroll);
44
+ unsuscribe.current = () => {
45
+ el.removeEventListener("scroll", handleScroll);
46
+ };
47
+ }, []);
48
+ return /* @__PURE__ */ jsx(
49
+ Box,
50
+ {
51
+ ...getVariant("layout.common.components.autoscrollContainer"),
52
+ className: "autoscrollContainer",
53
+ ref,
54
+ children
55
+ }
56
+ );
57
+ };
58
+
59
+ function isImageFile(file) {
60
+ const IMAGE_EXTENSIONS = [
61
+ "jpg",
62
+ "jpeg",
63
+ "png",
64
+ "gif",
65
+ "bmp",
66
+ "webp",
67
+ "tiff",
68
+ "svg",
69
+ "jfif"
70
+ ];
71
+ return IMAGE_EXTENSIONS.includes(file.name.split(".").pop());
72
+ }
73
+ function getImageOcrMaker(lang) {
74
+ return new class ImageOcrMaker {
75
+ async processFile(file, onProgress) {
76
+ const tesseract = await import('tesseract.js');
77
+ const worker = await tesseract.createWorker(lang, 1, {
78
+ logger(arg) {
79
+ onProgress?.(arg.progress * 100);
80
+ }
81
+ });
82
+ const result = (await worker.recognize(file)).data.text;
83
+ return [result];
84
+ }
85
+ willProcessFile(file) {
86
+ return isImageFile(file);
87
+ }
88
+ }();
89
+ }
90
+
91
+ function isPdfFile(file) {
92
+ const IMAGE_EXTENSIONS = ["pdf"];
93
+ return IMAGE_EXTENSIONS.includes(file.name.split(".").pop());
94
+ }
95
+ function getPdfReader() {
96
+ return new class PdfReader {
97
+ async processFile(file, onProgress) {
98
+ onProgress?.(0);
99
+ const { getDocument, GlobalWorkerOptions } = await import('pdfjs-dist');
100
+ async function getPdfTextFromArrayBuffer(buffer) {
101
+ GlobalWorkerOptions.workerSrc = "../includes/pdf.worker.min.js";
102
+ const pdf = await getDocument({ data: buffer }).promise;
103
+ const pages = [];
104
+ for (let i = 1; i <= pdf.numPages; i++) {
105
+ const page = await pdf.getPage(i);
106
+ const textContent = await page.getTextContent();
107
+ pages.push(
108
+ textContent.items.map((item) => item.str).join(" ")
109
+ );
110
+ }
111
+ return pages;
112
+ }
113
+ return new Promise((resolve) => {
114
+ const reader = new FileReader();
115
+ reader.onload = async function(event) {
116
+ if (!event.target?.result) {
117
+ alert("Error al leer el archivo.");
118
+ return;
119
+ }
120
+ const buffer = event.target.result;
121
+ const text = await getPdfTextFromArrayBuffer(buffer);
122
+ onProgress?.(100);
123
+ resolve(text);
124
+ };
125
+ reader.readAsArrayBuffer(file);
126
+ });
127
+ }
128
+ willProcessFile(file) {
129
+ return isPdfFile(file);
130
+ }
131
+ }();
132
+ }
133
+
134
+ class WrongFormatError extends Error {
135
+ constructor(fileName) {
136
+ super(`File format not supported: ${fileName}`);
137
+ }
138
+ }
139
+ function useHandleFileUpload({
140
+ onContent
141
+ }) {
142
+ const [progress, setProgress] = useState(100);
143
+ const handleFileUpload = useCallback(
144
+ async (ev) => {
145
+ setProgress(0);
146
+ const imageProcessor = getImageOcrMaker();
147
+ const pdfProcessor = getPdfReader();
148
+ await (async () => {
149
+ const obtainedText = [];
150
+ const files = ev.target.files;
151
+ const filesLength = ev.target.files?.length ?? 0;
152
+ if (files) {
153
+ for (let i = 0; i < filesLength; i++) {
154
+ const file = files[i];
155
+ if (!isImageFile(file) && !isPdfFile(file)) {
156
+ setProgress(100);
157
+ throw new WrongFormatError(file.name);
158
+ }
159
+ const handleProgress = (progress2) => {
160
+ setProgress(
161
+ i / filesLength * 100 + 1 / filesLength * 100 * (progress2 / 100)
162
+ );
163
+ };
164
+ let result = "";
165
+ if (imageProcessor.willProcessFile(file)) {
166
+ try {
167
+ result = (await imageProcessor.processFile(file, handleProgress))[0];
168
+ } catch (e) {
169
+ console.error(e);
170
+ }
171
+ } else if (pdfProcessor.willProcessFile(file)) {
172
+ result = (await pdfProcessor.processFile(file, handleProgress)).join("\n\n");
173
+ }
174
+ if (result) {
175
+ obtainedText.push(result);
176
+ }
177
+ setProgress((i + 1) / filesLength * 100);
178
+ }
179
+ }
180
+ onContent(obtainedText);
181
+ })();
182
+ ev.target.value = "";
183
+ },
184
+ [onContent]
185
+ );
186
+ return { progress, handleFileUpload };
187
+ }
188
+
189
+ var __defProp$1 = Object.defineProperty;
190
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
191
+ var __publicField$1 = (obj, key, value) => {
192
+ __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
193
+ return value;
194
+ };
195
+ var __accessCheck$1 = (obj, member, msg) => {
196
+ if (!member.has(obj))
197
+ throw TypeError("Cannot " + msg);
198
+ };
199
+ var __privateGet$1 = (obj, member, getter) => {
200
+ __accessCheck$1(obj, member, "read from private field");
201
+ return getter ? getter.call(obj) : member.get(obj);
202
+ };
203
+ var __privateAdd$1 = (obj, member, value) => {
204
+ if (member.has(obj))
205
+ throw TypeError("Cannot add the same private member more than once");
206
+ member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
207
+ };
208
+ var __privateSet$1 = (obj, member, value, setter) => {
209
+ __accessCheck$1(obj, member, "write to private field");
210
+ setter ? setter.call(obj, value) : member.set(obj, value);
211
+ return value;
212
+ };
213
+ var _message;
214
+ let maxId = 0;
215
+ class ChatMessage {
216
+ constructor(message, messageType) {
217
+ this.messageType = messageType;
218
+ __publicField$1(this, "id");
219
+ __privateAdd$1(this, _message, void 0);
220
+ this.id = maxId++;
221
+ __privateSet$1(this, _message, message);
222
+ if (messageType === "response")
223
+ this.messageType = "system";
224
+ if (typeof message === "string")
225
+ __privateSet$1(this, _message, this.parseMessage(message));
226
+ }
227
+ parseMessage(message) {
228
+ let result = message;
229
+ result = result.replaceAll("[strong]", "<strong>");
230
+ result = result.replaceAll("[/strong]", "</strong>");
231
+ return result;
232
+ }
233
+ get message() {
234
+ return __privateGet$1(this, _message);
235
+ }
236
+ }
237
+ _message = new WeakMap();
238
+
239
+ const makeTextarea = (gptController) => {
240
+ const NewTextarea = ({
241
+ hideDeleteButton,
242
+ isLoading: outIsLoading,
243
+ onSubmit,
244
+ preventAppendUserMessages
245
+ }) => {
246
+ const [isLoading, setIsLoading] = useState(false);
247
+ const submit = useCallback(
248
+ (text) => {
249
+ if (preventAppendUserMessages !== true)
250
+ gptController.messages.add(new ChatMessage(text, "user"));
251
+ gptController.history.add(text);
252
+ onSubmit(text).finally(() => {
253
+ setIsLoading(false);
254
+ });
255
+ },
256
+ [onSubmit, preventAppendUserMessages]
257
+ );
258
+ const handleSubmit = useCallback(
259
+ (ev) => {
260
+ ev.preventDefault();
261
+ const textarea = document.getElementById(
262
+ `GPTMessage${gptController.id}`
263
+ );
264
+ if (textarea.value) {
265
+ setIsLoading(true);
266
+ submit(textarea.value);
267
+ }
268
+ textarea.focus();
269
+ textarea.value = "";
270
+ },
271
+ [submit]
272
+ );
273
+ const onKeyDown = useCallback((ev) => {
274
+ if (ev.target.readOnly)
275
+ return;
276
+ if (ev.code === "Enter" && !ev.shiftKey) {
277
+ ev.preventDefault();
278
+ ev.target.closest("form")?.querySelector('button[type="submit"]')?.click();
279
+ }
280
+ }, []);
281
+ const { progress, handleFileUpload } = useHandleFileUpload({
282
+ onContent(content) {
283
+ document.getElementById(
284
+ `GPTMessage${gptController.id}`
285
+ ).value = content.join("\n\n");
286
+ }
287
+ });
288
+ const actualIsLoading = isLoading || progress !== 100 || outIsLoading;
289
+ const [dragging, setDragging] = useState(false);
290
+ const handleDragLeave = (ev) => {
291
+ ev.preventDefault();
292
+ setDragging(false);
293
+ };
294
+ const handleDrop = (ev) => {
295
+ ev.preventDefault();
296
+ setDragging(false);
297
+ const fileElement = document.getElementById(
298
+ `gptUploadFile__${gptController.id}`
299
+ );
300
+ fileElement.files = ev.dataTransfer.files;
301
+ const event = new Event("change", { bubbles: true });
302
+ fileElement.dispatchEvent(event);
303
+ };
304
+ const handleDragOver = (ev) => {
305
+ ev.preventDefault();
306
+ };
307
+ const handleDragEnter = (ev) => {
308
+ ev.preventDefault();
309
+ setDragging(true);
310
+ };
311
+ return /* @__PURE__ */ jsxs(
312
+ "form",
313
+ {
314
+ onDrop: handleDrop,
315
+ onDragOver: handleDragOver,
316
+ onDragEnter: handleDragEnter,
317
+ onDragLeave: handleDragLeave,
318
+ onSubmit: handleSubmit,
319
+ className: "gpt__form",
320
+ action: "",
321
+ children: [
322
+ dragging ? /* @__PURE__ */ jsx(
323
+ Box,
324
+ {
325
+ sx: {
326
+ height: "150px",
327
+ border: "3px dashed #aaa",
328
+ width: "100%",
329
+ display: "flex",
330
+ alignItems: "center",
331
+ justifyContent: "center"
332
+ },
333
+ children: getLabel("msgAiDragAndDrop").text
334
+ }
335
+ ) : /* @__PURE__ */ jsx(
336
+ Textarea,
337
+ {
338
+ onKeyDown,
339
+ id: `GPTMessage${gptController.id}`,
340
+ readOnly: actualIsLoading
341
+ }
342
+ ),
343
+ /* @__PURE__ */ jsxs(Box, { className: "gpt__buttonsContainer", children: [
344
+ /* @__PURE__ */ jsx(Box, { sx: { display: "none" }, children: /* @__PURE__ */ jsx(
345
+ "input",
346
+ {
347
+ type: "file",
348
+ className: "gptUploadFile",
349
+ id: `gptUploadFile__${gptController.id}`,
350
+ onChange: (ev) => {
351
+ handleFileUpload(ev).catch((e) => {
352
+ if (e instanceof WrongFormatError) {
353
+ setIsLoading(false);
354
+ gptController.messages.add(
355
+ new ChatMessage(
356
+ getLabel("msgAiFileExtensionError").text,
357
+ "error"
358
+ )
359
+ );
360
+ } else {
361
+ throw e;
362
+ }
363
+ });
364
+ }
365
+ }
366
+ ) }),
367
+ /* @__PURE__ */ jsx(
368
+ IconButton,
369
+ {
370
+ title: getLabel("btnUploadFile").text,
371
+ icon: "File",
372
+ variant: "icon-outline",
373
+ disabled: actualIsLoading,
374
+ onClick: () => {
375
+ document.getElementById(
376
+ `gptUploadFile__${gptController.id}`
377
+ ).click();
378
+ },
379
+ size: "Lg"
380
+ }
381
+ ),
382
+ /* @__PURE__ */ jsx(
383
+ SimpleButton,
384
+ {
385
+ title: getLabel("btnAiPrevious").tooltip,
386
+ variant: "outline",
387
+ type: "button",
388
+ onClick: () => {
389
+ const historyValue = gptController.history.previous();
390
+ if (historyValue)
391
+ document.getElementById(
392
+ `GPTMessage${gptController.id}`
393
+ ).value = historyValue;
394
+ },
395
+ size: "sm",
396
+ children: getLabel("btnAiPrevious").text
397
+ }
398
+ ),
399
+ /* @__PURE__ */ jsx(
400
+ SimpleButton,
401
+ {
402
+ title: getLabel("btnAiNext").tooltip,
403
+ variant: "outline",
404
+ type: "button",
405
+ onClick: () => {
406
+ const historyValue = gptController.history.next();
407
+ document.getElementById(
408
+ `GPTMessage${gptController.id}`
409
+ ).value = historyValue ?? "";
410
+ },
411
+ size: "sm",
412
+ children: getLabel("btnAiNext").text
413
+ }
414
+ ),
415
+ !hideDeleteButton && /* @__PURE__ */ jsxs(Fragment, { children: [
416
+ /* @__PURE__ */ jsx(
417
+ SimpleButton,
418
+ {
419
+ title: getLabel("btnAiDelete").tooltip,
420
+ variant: "outline",
421
+ type: "button",
422
+ onClick: () => document.getElementById(
423
+ `GPTMessage${gptController.id}`
424
+ ).value = "",
425
+ size: "sm",
426
+ children: getLabel("btnAiDelete").text
427
+ }
428
+ ),
429
+ /* @__PURE__ */ jsx(
430
+ SimpleButton,
431
+ {
432
+ title: getLabel("btnAiDeleteMessages").tooltip,
433
+ variant: "outline",
434
+ type: "button",
435
+ onClick: () => gptController.messages.clear(),
436
+ size: "sm",
437
+ children: getLabel("btnAiDeleteMessages").text
438
+ }
439
+ )
440
+ ] }),
441
+ /* @__PURE__ */ jsx(
442
+ SimpleButton,
443
+ {
444
+ title: getLabel("btnAiSend").tooltip,
445
+ isLoading: actualIsLoading,
446
+ type: "submit",
447
+ size: "sm",
448
+ children: getLabel("btnAiSend").text
449
+ }
450
+ )
451
+ ] })
452
+ ]
453
+ }
454
+ );
455
+ };
456
+ NewTextarea.displayName = "";
457
+ return NewTextarea;
458
+ };
459
+
460
+ var __defProp = Object.defineProperty;
461
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
462
+ var __publicField = (obj, key, value) => {
463
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
464
+ return value;
465
+ };
466
+ var __accessCheck = (obj, member, msg) => {
467
+ if (!member.has(obj))
468
+ throw TypeError("Cannot " + msg);
469
+ };
470
+ var __privateGet = (obj, member, getter) => {
471
+ __accessCheck(obj, member, "read from private field");
472
+ return getter ? getter.call(obj) : member.get(obj);
473
+ };
474
+ var __privateAdd = (obj, member, value) => {
475
+ if (member.has(obj))
476
+ throw TypeError("Cannot add the same private member more than once");
477
+ member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
478
+ };
479
+ var __privateSet = (obj, member, value, setter) => {
480
+ __accessCheck(obj, member, "write to private field");
481
+ setter ? setter.call(obj, value) : member.set(obj, value);
482
+ return value;
483
+ };
484
+ var __privateWrapper = (obj, member, setter, getter) => ({
485
+ set _(value) {
486
+ __privateSet(obj, member, value, setter);
487
+ },
488
+ get _() {
489
+ return __privateGet(obj, member, getter);
490
+ }
491
+ });
492
+ var _messages, _promptsHistory, _currentHistoryIndex;
493
+ class ChatController extends EventEmitter {
494
+ constructor(id, welcomeMessage) {
495
+ super();
496
+ this.id = id;
497
+ __privateAdd(this, _messages, []);
498
+ __publicField(this, "components", {
499
+ MessageHistory: () => {
500
+ const messages = this.history.useList();
501
+ return /* @__PURE__ */ jsx(
502
+ Box,
503
+ {
504
+ ...getVariant("layout.common.components.chat"),
505
+ className: "history",
506
+ children: /* @__PURE__ */ jsx(AutoscrollContainer, { children: messages.map((current) => /* @__PURE__ */ jsx(
507
+ Box,
508
+ {
509
+ as: "pre",
510
+ className: `history__message ${current.messageType}`,
511
+ ...typeof current.message === "string" ? { dangerouslySetInnerHTML: { __html: current.message } } : { children: current.message }
512
+ },
513
+ current.id
514
+ )) })
515
+ }
516
+ );
517
+ },
518
+ Textarea: makeTextarea(this)
519
+ });
520
+ __privateAdd(this, _promptsHistory, []);
521
+ __privateAdd(this, _currentHistoryIndex, -1);
522
+ __publicField(this, "history", {
523
+ add: (prompt) => {
524
+ __privateSet(this, _currentHistoryIndex, -1);
525
+ if (prompt === __privateGet(this, _promptsHistory)[__privateGet(this, _promptsHistory).length]) {
526
+ return;
527
+ }
528
+ __privateSet(this, _promptsHistory, [
529
+ prompt,
530
+ ...__privateGet(this, _promptsHistory).slice(
531
+ Math.max(0, __privateGet(this, _promptsHistory).length - 10)
532
+ )
533
+ ]);
534
+ },
535
+ next: () => {
536
+ if (__privateGet(this, _promptsHistory)[__privateGet(this, _currentHistoryIndex) - 1])
537
+ return __privateGet(this, _promptsHistory)[--__privateWrapper(this, _currentHistoryIndex)._];
538
+ else {
539
+ __privateSet(this, _currentHistoryIndex, -1);
540
+ return "";
541
+ }
542
+ },
543
+ previous: () => {
544
+ if (__privateGet(this, _promptsHistory)[__privateGet(this, _currentHistoryIndex) + 1]) {
545
+ return __privateGet(this, _promptsHistory)[++__privateWrapper(this, _currentHistoryIndex)._];
546
+ }
547
+ },
548
+ useList: () => {
549
+ const [messages, setMessages] = useState(__privateGet(this, _messages));
550
+ useEffect(() => {
551
+ return this.on("listChange", (messages2) => setMessages(messages2));
552
+ }, []);
553
+ return messages;
554
+ }
555
+ });
556
+ __publicField(this, "messages", {
557
+ add: (message) => {
558
+ __privateGet(this, _messages).push(message);
559
+ this.emit("listChange", [...__privateGet(this, _messages)]);
560
+ },
561
+ clear: () => {
562
+ __privateSet(this, _messages, []);
563
+ this.emit("listChange", []);
564
+ }
565
+ });
566
+ if (welcomeMessage)
567
+ __privateGet(this, _messages).push(new ChatMessage(welcomeMessage, "system"));
568
+ }
569
+ }
570
+ _messages = new WeakMap();
571
+ _promptsHistory = new WeakMap();
572
+ _currentHistoryIndex = new WeakMap();
573
+
574
+ class MultipleChoiceMessage extends ChatMessage {
575
+ constructor(question, options, Renderer) {
576
+ super("", "multipleChoice");
577
+ this.question = question;
578
+ this.options = options;
579
+ this.Renderer = Renderer;
580
+ }
581
+ get message() {
582
+ const Renderer = this.Renderer;
583
+ if (Renderer) {
584
+ return /* @__PURE__ */ jsxs(Box, { className: "multipleChoiceMessage customRenderer", children: [
585
+ /* @__PURE__ */ jsx(Paragraph, { children: this.question }),
586
+ this.options.map((item) => /* @__PURE__ */ jsx(Renderer, { item }, item.url))
587
+ ] });
588
+ }
589
+ return /* @__PURE__ */ jsxs(Box, { className: "multipleChoiceMessage", children: [
590
+ /* @__PURE__ */ jsx(Paragraph, { children: this.question }),
591
+ !Renderer && /* @__PURE__ */ jsx(Box, { as: "ul", children: this.options.map((current) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
592
+ SimpleButton,
593
+ {
594
+ className: "multipleChoice__option",
595
+ onClick: () => {
596
+ ApiaUtil.instance.tabs.openTab(current.label, current.url);
597
+ },
598
+ children: current.label
599
+ }
600
+ ) }, current.label)) })
601
+ ] });
602
+ }
603
+ }
604
+
605
+ export { ChatController, ChatMessage, MultipleChoiceMessage };
4
606
  //# sourceMappingURL=index.js.map