@clikvn/agent-widget-embedded 0.0.10-dev → 0.0.12-dev

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 (73) hide show
  1. package/dist/commons/constants/variables.d.ts +4 -0
  2. package/dist/commons/constants/variables.d.ts.map +1 -1
  3. package/dist/components/Chat/Icons.d.ts +19 -1
  4. package/dist/components/Chat/Icons.d.ts.map +1 -1
  5. package/dist/components/Chat/Message.d.ts.map +1 -1
  6. package/dist/components/Chat/MultimodalInput.d.ts +1 -1
  7. package/dist/components/Chat/MultimodalInput.d.ts.map +1 -1
  8. package/dist/components/Chat/SuggestedActions.d.ts +12 -0
  9. package/dist/components/Chat/SuggestedActions.d.ts.map +1 -0
  10. package/dist/features/AgentWidget/index.d.ts +8 -2
  11. package/dist/features/AgentWidget/index.d.ts.map +1 -1
  12. package/dist/hooks/useConfiguration.d.ts +8 -1
  13. package/dist/hooks/useConfiguration.d.ts.map +1 -1
  14. package/dist/index.html +45 -44
  15. package/dist/types/common.type.d.ts +6 -0
  16. package/dist/types/common.type.d.ts.map +1 -1
  17. package/dist/web.js +1 -1
  18. package/package.json +3 -2
  19. package/.eslintrc +0 -34
  20. package/.prettierrc +0 -8
  21. package/dist/components/Chat/AudioRecording.d.ts +0 -9
  22. package/dist/components/Chat/AudioRecording.d.ts.map +0 -1
  23. package/dist/hooks/useConnection.d.ts +0 -15
  24. package/dist/hooks/useConnection.d.ts.map +0 -1
  25. package/dist/services/user.service.d.ts +0 -3
  26. package/dist/services/user.service.d.ts.map +0 -1
  27. package/dist/types/agentType.d.ts +0 -11
  28. package/dist/types/agentType.d.ts.map +0 -1
  29. package/src/assets/common.css +0 -148
  30. package/src/assets/tailwindcss.css +0 -3
  31. package/src/commons/constants/index.ts +0 -1
  32. package/src/commons/constants/variables.ts +0 -20
  33. package/src/components/Agent/index.tsx +0 -14
  34. package/src/components/Chat/AudioPlayer.tsx +0 -44
  35. package/src/components/Chat/Chat.tsx +0 -91
  36. package/src/components/Chat/Icons.tsx +0 -930
  37. package/src/components/Chat/Markdown.tsx +0 -335
  38. package/src/components/Chat/Message.tsx +0 -191
  39. package/src/components/Chat/MultimodalInput.tsx +0 -479
  40. package/src/components/Chat/Overview.tsx +0 -46
  41. package/src/components/Chat/PreviewAttachment.tsx +0 -46
  42. package/src/components/Chat/ui/Button.tsx +0 -55
  43. package/src/components/Chat/ui/Textarea.tsx +0 -23
  44. package/src/constants.ts +0 -1
  45. package/src/env.d.ts +0 -10
  46. package/src/features/AgentWidget/index.tsx +0 -57
  47. package/src/global.d.ts +0 -1
  48. package/src/hooks/useAudioRecording.ts +0 -50
  49. package/src/hooks/useChat.ts +0 -262
  50. package/src/hooks/useChatData.tsx +0 -68
  51. package/src/hooks/useConfiguration.tsx +0 -56
  52. package/src/hooks/useScrollToBottom.ts +0 -31
  53. package/src/index.ts +0 -1
  54. package/src/models/FlowiseClient.ts +0 -103
  55. package/src/models.ts +0 -1
  56. package/src/register.tsx +0 -85
  57. package/src/services/apis.ts +0 -12
  58. package/src/services/bot.service.ts +0 -15
  59. package/src/services/chat.service.ts +0 -199
  60. package/src/types/bot.type.ts +0 -10
  61. package/src/types/chat.type.ts +0 -11
  62. package/src/types/common.type.ts +0 -17
  63. package/src/types/flowise.type.ts +0 -108
  64. package/src/types/user.type.ts +0 -15
  65. package/src/types.ts +0 -0
  66. package/src/utils/audioRecording.ts +0 -371
  67. package/src/utils/commonUtils.ts +0 -47
  68. package/src/utils/functionUtils.ts +0 -17
  69. package/src/utils/requestUtils.ts +0 -113
  70. package/src/utils/streamUtils.ts +0 -18
  71. package/src/web.ts +0 -6
  72. package/src/window.ts +0 -43
  73. package/tsconfig.json +0 -24
@@ -1,479 +0,0 @@
1
- import {
2
- type ChangeEvent,
3
- FC,
4
- useCallback,
5
- useEffect,
6
- useRef,
7
- useState,
8
- } from 'react';
9
- import { motion } from 'framer-motion';
10
- import { useLocalStorage, useWindowSize } from 'usehooks-ts';
11
- import {
12
- cn,
13
- generateExtendedFileName,
14
- generateUUID,
15
- } from '../../utils/commonUtils';
16
- import { PreviewAttachment } from './PreviewAttachment';
17
- import {
18
- ArrowUpIcon,
19
- CircleDotIcon,
20
- MicrophoneIcon,
21
- PlusIcon,
22
- StopIcon,
23
- TrashIcon,
24
- VolumeIcon,
25
- } from './Icons';
26
- import { ChatMessageType, IFileUpload } from '../../types/flowise.type';
27
- import { BotType } from '../../types/bot.type';
28
-
29
- import { createAttachments } from '../../services/chat.service';
30
- import { Button } from './ui/Button';
31
- import { Textarea } from './ui/Textarea';
32
- import { useAudioRecording } from '../../hooks/useAudioRecording';
33
- import { useChatData } from '../../hooks/useChatData';
34
- import { useConfiguration } from '../../hooks/useConfiguration';
35
- import { SuggestionType } from 'types/common.type';
36
-
37
- type PropsType = {
38
- input: string;
39
- setInput: (value: string) => void;
40
- isLoading: boolean;
41
- stop: () => void;
42
- messages: ChatMessageType[];
43
- setMessages: (messages: ChatMessageType[]) => void;
44
- chatId: string;
45
- handleSubmit: (
46
- event?: { preventDefault?: () => void },
47
- files?: IFileUpload[]
48
- ) => void;
49
- className?: string;
50
- append?: (message: ChatMessageType) => Promise<void>;
51
- attachments?: IFileUpload[];
52
- setAttachments?: (func: (files: IFileUpload[]) => IFileUpload[]) => void;
53
- bot: BotType | null;
54
- apiHost: string;
55
- setEnableTTS: (value: boolean) => void;
56
- enableTTS: boolean;
57
- suggestedActions?: SuggestionType[];
58
- };
59
-
60
- export const MultimodalInput: FC<PropsType> = ({
61
- input,
62
- setInput,
63
- isLoading,
64
- stop,
65
- messages,
66
- setMessages,
67
- chatId,
68
- handleSubmit,
69
- className,
70
- append,
71
- attachments,
72
- setAttachments,
73
- bot,
74
- apiHost,
75
- setEnableTTS,
76
- enableTTS,
77
- suggestedActions,
78
- }) => {
79
- const { theme } = useConfiguration();
80
- const {
81
- isRecording,
82
- setIsRecording,
83
- onRecordingCancelled,
84
- onRecordingStopped,
85
- elapsedTime,
86
- isLoadingRecording,
87
- } = useAudioRecording();
88
- const textareaRef = useRef<HTMLTextAreaElement | null>(null);
89
- const { width } = useWindowSize();
90
- useEffect(() => {
91
- if (textareaRef.current) {
92
- adjustHeight();
93
- }
94
- }, []);
95
-
96
- const adjustHeight = () => {
97
- if (textareaRef.current) {
98
- (textareaRef.current as HTMLTextAreaElement).style.height = 'auto';
99
- (textareaRef.current as HTMLTextAreaElement).style.height =
100
- `${textareaRef.current?.scrollHeight + 2}px`;
101
- }
102
- };
103
-
104
- const [localStorageInput, setLocalStorageInput] = useLocalStorage(
105
- 'input',
106
- ''
107
- );
108
-
109
- useEffect(() => {
110
- if (textareaRef.current) {
111
- const domValue = textareaRef.current?.value;
112
- // Prefer DOM value over localStorage to handle hydration
113
- const finalValue = domValue || localStorageInput || '';
114
- setInput(finalValue);
115
- adjustHeight();
116
- }
117
- // Only run once after hydration
118
- // eslint-disable-next-line react-hooks/exhaustive-deps
119
- }, []);
120
-
121
- useEffect(() => {
122
- setLocalStorageInput(input);
123
- }, [input, setLocalStorageInput]);
124
-
125
- const handleInput = (event: ChangeEvent<HTMLTextAreaElement>) => {
126
- setInput(event.target.value);
127
- adjustHeight();
128
- };
129
-
130
- const fileInputRef = useRef<HTMLInputElement | null>(null);
131
- const [uploadQueue, setUploadQueue] = useState<Array<string>>([]);
132
-
133
- const submitForm = useCallback(async () => {
134
- handleSubmit(undefined, attachments);
135
- setLocalStorageInput('');
136
- if (setAttachments) {
137
- setAttachments((_) => []);
138
- if (fileInputRef.current) {
139
- (fileInputRef.current as HTMLInputElement).value = '';
140
- }
141
- }
142
- if (width && width > 768) {
143
- textareaRef.current?.focus();
144
- }
145
- }, [handleSubmit, setLocalStorageInput, width, attachments, chatId, bot]);
146
-
147
- const uploadFile = useCallback(
148
- async (file: File) => {
149
- const formData = new FormData();
150
- formData.append('file', file, generateExtendedFileName(file.name));
151
- try {
152
- return await createAttachments({
153
- chatId,
154
- apiHost,
155
- body: formData,
156
- });
157
- } catch (error) {
158
- console.error('Failed to upload file, please try again!');
159
- }
160
- },
161
- [chatId]
162
- );
163
-
164
- const toAudioBase64 = (blob: Blob) => {
165
- return new Promise<IFileUpload>((resolve) => {
166
- let mimeType = '';
167
- const pos = blob.type.indexOf(';');
168
- if (pos === -1) {
169
- mimeType = blob.type;
170
- } else {
171
- mimeType = blob.type.substring(0, pos);
172
- }
173
-
174
- // read blob and add to previews
175
- const reader = new FileReader();
176
- reader.readAsDataURL(blob);
177
- reader.onloadend = () => {
178
- const base64data = reader.result as string;
179
- const upload: IFileUpload = {
180
- tempId: generateUUID(),
181
- data: base64data,
182
- type: 'audio',
183
- name: `audio_${Date.now()}.wav`,
184
- mime: mimeType,
185
- };
186
- resolve(upload);
187
- };
188
- });
189
- };
190
-
191
- const toBase64 = async (
192
- file: File,
193
- type = 'file'
194
- ): Promise<IFileUpload | undefined> => {
195
- return new Promise((resolve, reject) => {
196
- const reader = new FileReader();
197
- reader.readAsDataURL(file);
198
- reader.onload = () => {
199
- resolve({
200
- tempId: generateUUID(),
201
- data: reader.result as string,
202
- type,
203
- name: generateExtendedFileName(file.name),
204
- mime: file.type,
205
- });
206
- };
207
- reader.onerror = () => {
208
- reject();
209
- };
210
- });
211
- };
212
-
213
- const checkUploadFile = useCallback(
214
- async (file: File): Promise<IFileUpload | undefined> => {
215
- if (file.type.startsWith('image')) {
216
- return toBase64(file);
217
- } else {
218
- setUploadQueue([file.name]);
219
- const response: any = await uploadFile(file);
220
- if (response?.type == 'file:full') {
221
- const f = response.result[0];
222
- if (!f) {
223
- return;
224
- }
225
- return {
226
- tempId: generateUUID(),
227
- data: f.content,
228
- name: f.name,
229
- mime: f.mimeType,
230
- type: response?.type,
231
- };
232
- } else if (response?.type == 'file:rag') {
233
- const { addedDocs } = response.result;
234
- if (!addedDocs.length) {
235
- return;
236
- }
237
- return toBase64(file, response?.type);
238
- }
239
- }
240
- },
241
- [setUploadQueue, uploadFile]
242
- );
243
-
244
- const handleFileChange = useCallback(
245
- async (event: ChangeEvent<HTMLInputElement>) => {
246
- const files = Array.from(event.target.files || []);
247
- try {
248
- const uploadPromises = files.map((file) => checkUploadFile(file));
249
- const uploadedAttachments = await Promise.all(uploadPromises);
250
- const successfullyUploadedAttachments = uploadedAttachments.filter(
251
- (attachment) => attachment !== undefined
252
- ) as IFileUpload[];
253
- if (setAttachments) {
254
- setAttachments((currentAttachments: IFileUpload[]) => [
255
- ...currentAttachments,
256
- ...successfullyUploadedAttachments,
257
- ]);
258
- }
259
- } catch (error) {
260
- console.error('Error uploading files!', error);
261
- } finally {
262
- setUploadQueue([]);
263
- }
264
- },
265
- [setAttachments, checkUploadFile]
266
- );
267
-
268
- const handleSubmitRecording = useCallback(
269
- async (blob: Blob) => {
270
- try {
271
- const audioFile = await toAudioBase64(blob);
272
- handleSubmit(undefined, [audioFile]);
273
- setIsRecording(false);
274
- } catch (error) {
275
- console.error('Error uploading files!', error);
276
- }
277
- },
278
- [handleSubmit, setIsRecording]
279
- );
280
-
281
- const handleSend = useCallback(async () => {
282
- if (isRecording) {
283
- onRecordingStopped(handleSubmitRecording);
284
- } else {
285
- submitForm();
286
- }
287
- }, [submitForm, onRecordingStopped, handleSubmitRecording]);
288
-
289
- return (
290
- <div className="relative w-full flex flex-col gap-4">
291
- {!!suggestedActions?.length && (
292
- <div className="grid sm:grid-cols-2 gap-2 w-full">
293
- {suggestedActions.map((suggestedAction, index) => (
294
- <motion.div
295
- initial={{ opacity: 0, y: 20 }}
296
- animate={{ opacity: 1, y: 0 }}
297
- exit={{ opacity: 0, y: 20 }}
298
- transition={{ delay: 0.05 * index }}
299
- key={`suggested-action-${suggestedAction.title}-${index}`}
300
- className={index > 1 ? 'hidden sm:block' : 'block'}
301
- >
302
- <Button
303
- variant="ghost"
304
- onClick={(e) => {
305
- e.preventDefault();
306
- if (append) {
307
- append({
308
- role: 'apiMessage',
309
- content: suggestedAction.action,
310
- });
311
- }
312
- }}
313
- className="text-left border rounded-xl px-4 py-3.5 text-sm flex-1 gap-1 sm:flex-col w-full h-auto justify-start items-start"
314
- >
315
- <span className="font-medium overflow-hidden whitespace-nowrap text-ellipsis w-full group-hover:overflow-visible group-hover:whitespace-normal">
316
- {suggestedAction.title}
317
- </span>
318
- {!!suggestedAction.label && (
319
- <span className="text-muted-foreground">
320
- {suggestedAction.label}
321
- </span>
322
- )}
323
- </Button>
324
- </motion.div>
325
- ))}
326
- </div>
327
- )}
328
-
329
- <input
330
- type="file"
331
- className="fixed -top-4 -left-4 size-0.5 opacity-0 pointer-events-none"
332
- ref={fileInputRef}
333
- multiple
334
- onChange={handleFileChange}
335
- tabIndex={-1}
336
- />
337
-
338
- {((attachments && attachments.length > 0) || uploadQueue.length > 0) && (
339
- <div className="flex flex-row gap-2 overflow-x-scroll items-end">
340
- {attachments?.map((attachment) => (
341
- <PreviewAttachment
342
- key={attachment.tempId}
343
- attachment={attachment}
344
- />
345
- ))}
346
-
347
- {uploadQueue.map((filename) => (
348
- <PreviewAttachment
349
- key={filename}
350
- attachment={{
351
- data: '',
352
- name: filename,
353
- mime: '',
354
- type: '',
355
- }}
356
- isUploading
357
- />
358
- ))}
359
- </div>
360
- )}
361
-
362
- <Textarea
363
- ref={textareaRef}
364
- placeholder={theme?.input?.placeholder || 'Send a message...'}
365
- value={input}
366
- onChange={handleInput}
367
- className={cn(
368
- 'min-h-[24px] max-h-[calc(75dvh)] overflow-hidden resize-none rounded-xl text-base bg-muted',
369
- className
370
- )}
371
- rows={3}
372
- autoFocus
373
- onKeyDown={(event) => {
374
- if (event.key === 'Enter' && !event.shiftKey) {
375
- event.preventDefault();
376
- if (isLoading) {
377
- console.error(
378
- 'Please wait for the model to finish its response!'
379
- );
380
- } else if (uploadQueue.length) {
381
- console.error('Please wait for file is uploading!');
382
- } else {
383
- handleSend();
384
- }
385
- }
386
- }}
387
- />
388
-
389
- {isLoading ? (
390
- <Button
391
- className="rounded-full p-1.5 h-fit absolute bottom-2 right-2 m-0.5 border dark:border-zinc-600"
392
- onClick={(event) => {
393
- event.preventDefault();
394
- stop();
395
- setMessages(messages);
396
- }}
397
- >
398
- <StopIcon size={14} />
399
- </Button>
400
- ) : (
401
- <Button
402
- className="rounded-full p-1.5 h-fit absolute bottom-2 right-2 m-0.5 border dark:border-zinc-600"
403
- onClick={(event) => {
404
- event.preventDefault();
405
- handleSend();
406
- }}
407
- disabled={
408
- !isRecording && (input.length === 0 || !!uploadQueue.length)
409
- } // zero input or uploading
410
- >
411
- <ArrowUpIcon size={14} />
412
- </Button>
413
- )}
414
- {isRecording ? (
415
- <>
416
- <div
417
- className="rounded-full bg-background flex absolute p-1 bottom-2 right-[80px]"
418
- data-testid="input"
419
- >
420
- <div className="flex items-center gap-3">
421
- <span>
422
- <CircleDotIcon color="red" />
423
- </span>
424
- <span>{elapsedTime || '00:00'}</span>
425
- {isLoadingRecording && <span className="ml-1.5">Sending...</span>}
426
- </div>
427
- </div>
428
- <Button
429
- className="rounded-full p-1.5 h-fit absolute bottom-2 right-11 m-0.5 dark:border-zinc-700"
430
- variant="outline"
431
- onClick={(event) => {
432
- event.preventDefault();
433
- onRecordingCancelled();
434
- }}
435
- >
436
- <TrashIcon size={14} color="red" />
437
- </Button>
438
- </>
439
- ) : (
440
- <>
441
- <Button
442
- className="rounded-full p-1.5 h-fit absolute bottom-2 right-11 m-0.5 dark:border-zinc-700"
443
- onClick={(event) => {
444
- event.preventDefault();
445
- setIsRecording(true);
446
- }}
447
- variant="outline"
448
- disabled={isLoading}
449
- >
450
- <MicrophoneIcon size={14} />
451
- </Button>
452
- <Button
453
- className={`rounded-full p-1.5 h-fit absolute bottom-2 right-[80px] m-0.5 dark:border-zinc-700 ${enableTTS ? 'text-white hover:bg-primary/90 bg-primary' : ''}`}
454
- onClick={(event) => {
455
- event.preventDefault();
456
- setEnableTTS(!enableTTS);
457
- }}
458
- variant="outline"
459
- disabled={isLoading}
460
- >
461
- <VolumeIcon />
462
- </Button>
463
- </>
464
- )}
465
-
466
- <Button
467
- className="rounded-full p-1.5 h-fit absolute bottom-2 left-2 m-0.5 dark:border-zinc-700"
468
- onClick={(event) => {
469
- event.preventDefault();
470
- fileInputRef.current?.click();
471
- }}
472
- variant="outline"
473
- disabled={isLoading || isRecording}
474
- >
475
- <PlusIcon size={14} />
476
- </Button>
477
- </div>
478
- );
479
- };
@@ -1,46 +0,0 @@
1
- import { motion } from 'framer-motion';
2
- import { FC } from 'react';
3
- import { BotType } from '../../types/bot.type';
4
- import { useConfiguration } from '../../hooks/useConfiguration';
5
-
6
- type PropsType = {
7
- bot: BotType | null;
8
- };
9
- export const Overview: FC<PropsType> = ({ bot }: PropsType) => {
10
- const { theme } = useConfiguration();
11
- return (
12
- <motion.div
13
- key="overview"
14
- className="max-w-3xl m-auto md:mt-20"
15
- initial={{ opacity: 0, scale: 0.98 }}
16
- animate={{ opacity: 1, scale: 1 }}
17
- exit={{ opacity: 0, scale: 0.98 }}
18
- transition={{ delay: 0.5 }}
19
- >
20
- <div className="rounded-xl p-6 flex flex-col gap-2 leading-relaxed text-center max-w-xl">
21
- <p className="flex flex-row justify-center gap-4 items-center"></p>
22
- {!theme?.overview ? (
23
- <>
24
- {bot?.avatar && (
25
- <img
26
- src={bot?.avatar}
27
- alt={bot?.name ?? 'Avatar'}
28
- width={40}
29
- height={40}
30
- className="rounded-full m-auto"
31
- />
32
- )}
33
- <p className="font-semibold text-xl">{bot?.name}</p>
34
- </>
35
- ) : (
36
- <>
37
- <p className="font-semibold text-xl">{theme?.overview?.title}</p>
38
- <p>{theme?.overview?.description}</p>
39
- </>
40
- )}
41
- </div>
42
- </motion.div>
43
- );
44
- };
45
-
46
- export default Overview;
@@ -1,46 +0,0 @@
1
- import { IFileUpload } from '../../types/flowise.type';
2
- import { LoaderIcon } from './Icons';
3
- import React from 'react';
4
-
5
- export const PreviewAttachment = ({
6
- attachment,
7
- isUploading = false,
8
- }: {
9
- attachment: IFileUpload;
10
- isUploading?: boolean;
11
- }) => {
12
- const { name, data, mime, tempId } = attachment;
13
- return (
14
- <div className="flex flex-col gap-2">
15
- <div className="w-30 p-0 max-w-[400px] bg-muted rounded-md relative flex flex-col items-center justify-center">
16
- {data ? (
17
- mime.startsWith('audio') ? (
18
- <audio controls>
19
- <source src={data} type={mime} />
20
- </audio>
21
- ) : mime.startsWith('image') ? (
22
- <img
23
- key={tempId}
24
- src={data}
25
- alt={name ?? 'An image attachment'}
26
- className="rounded-md size-full object-contain"
27
- />
28
- ) : (
29
- <div className="w-full text-left truncate">{name}</div>
30
- )
31
- ) : (
32
- <div className="w-full text-left truncate">{name}</div>
33
- )}
34
-
35
- {isUploading && (
36
- <div className="animate-spin absolute text-zinc-500">
37
- <LoaderIcon />
38
- </div>
39
- )}
40
- </div>
41
- {/*<div className="text-xs text-zinc-500 max-w-[200px] truncate ">*/}
42
- {/* {name}*/}
43
- {/*</div>*/}
44
- </div>
45
- );
46
- };
@@ -1,55 +0,0 @@
1
- import { Slot } from '@radix-ui/react-slot';
2
- import { cn } from '../../../utils/commonUtils';
3
- import { cva, type VariantProps } from 'class-variance-authority';
4
- import { ButtonHTMLAttributes, forwardRef } from 'react';
5
-
6
- const buttonVariants = cva(
7
- 'inline-flex items-center gap-2 justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
8
- {
9
- variants: {
10
- variant: {
11
- default: 'bg-primary text-primary-foreground hover:bg-primary/90',
12
- destructive:
13
- 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
14
- outline:
15
- 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
16
- secondary:
17
- 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
18
- ghost: 'hover:bg-accent hover:text-accent-foreground',
19
- link: 'text-primary underline-offset-4 hover:underline',
20
- },
21
- size: {
22
- default: 'h-10 px-4 py-2',
23
- sm: 'h-9 rounded-md px-3',
24
- lg: 'h-11 rounded-md px-8',
25
- icon: 'h-10 w-10',
26
- },
27
- },
28
- defaultVariants: {
29
- variant: 'default',
30
- size: 'default',
31
- },
32
- }
33
- );
34
-
35
- export interface ButtonProps
36
- extends ButtonHTMLAttributes<HTMLButtonElement>,
37
- VariantProps<typeof buttonVariants> {
38
- asChild?: boolean;
39
- }
40
-
41
- const Button = forwardRef<HTMLButtonElement, ButtonProps>(
42
- ({ className, variant, size, asChild = false, ...props }, ref) => {
43
- const Comp = asChild ? Slot : 'button';
44
- return (
45
- <Comp
46
- className={cn(buttonVariants({ variant, size, className }))}
47
- ref={ref}
48
- {...props}
49
- />
50
- );
51
- }
52
- );
53
- Button.displayName = 'Button';
54
-
55
- export { Button, buttonVariants };
@@ -1,23 +0,0 @@
1
- import { cn } from '../../../utils/commonUtils';
2
- import { forwardRef, TextareaHTMLAttributes } from 'react';
3
-
4
- export interface TextareaProps
5
- extends TextareaHTMLAttributes<HTMLTextAreaElement> {}
6
-
7
- const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
8
- ({ className, ...props }, ref) => {
9
- return (
10
- <textarea
11
- className={cn(
12
- 'flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
13
- className
14
- )}
15
- ref={ref}
16
- {...props}
17
- />
18
- );
19
- }
20
- );
21
- Textarea.displayName = 'Textarea';
22
-
23
- export { Textarea };
package/src/constants.ts DELETED
@@ -1 +0,0 @@
1
- export const agentWidgetElementName = 'clik-agent-widget';
package/src/env.d.ts DELETED
@@ -1,10 +0,0 @@
1
- // export {};
2
- //
3
- // declare module 'solid-js' {
4
- // namespace JSX {
5
- // interface CustomEvents {
6
- // click: MouseEvent;
7
- // pointerdown: PointerEvent;
8
- // }
9
- // }
10
- // }