funda-ui 4.5.712 → 4.5.766

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 (501) hide show
  1. package/Chatbox/index.d.ts +54 -0
  2. package/{publish/lib/cjs/Date → Chatbox}/index.js +2465 -3802
  3. package/README.md +4 -105
  4. package/Utils/useStreamController.d.ts +71 -0
  5. package/Utils/useStreamController.js +494 -0
  6. package/{publish/all.d.ts → all.d.ts} +1 -0
  7. package/{publish/all.js → all.js} +1 -0
  8. package/lib/cjs/Chatbox/index.d.ts +54 -0
  9. package/lib/cjs/Chatbox/index.js +4863 -0
  10. package/lib/cjs/Utils/useStreamController.d.ts +71 -0
  11. package/lib/cjs/Utils/useStreamController.js +494 -0
  12. package/lib/cjs/index.d.ts +1 -0
  13. package/lib/cjs/index.js +1 -0
  14. package/lib/esm/Chatbox/PureLoader.tsx +45 -0
  15. package/lib/esm/Chatbox/TypingEffect.tsx +32 -0
  16. package/lib/esm/Chatbox/index.scss +502 -0
  17. package/lib/esm/Chatbox/index.tsx +1171 -0
  18. package/lib/esm/Chatbox/useStreamController.tsx +277 -0
  19. package/lib/esm/Chatbox/utils/func.ts +107 -0
  20. package/lib/esm/Textarea/index.tsx +1 -0
  21. package/lib/esm/Utils/hooks/useStreamController.tsx +277 -0
  22. package/lib/esm/index.js +1 -0
  23. package/package.json +44 -41
  24. package/.gitattributes +0 -2
  25. package/README_PUBLISH.md +0 -126
  26. package/logo.png +0 -0
  27. package/preview.png +0 -0
  28. package/publish/LICENSE +0 -21
  29. package/publish/README.md +0 -126
  30. package/publish/lib/cjs/Accordion/index.d.ts +0 -2
  31. package/publish/lib/cjs/Accordion/index.js +0 -1035
  32. package/publish/lib/cjs/BackToTop/index.d.ts +0 -17
  33. package/publish/lib/cjs/BackToTop/index.js +0 -904
  34. package/publish/lib/cjs/CascadingSelect/index.d.ts +0 -60
  35. package/publish/lib/cjs/CascadingSelect/index.js +0 -2943
  36. package/publish/lib/cjs/CascadingSelectE2E/index.d.ts +0 -71
  37. package/publish/lib/cjs/CascadingSelectE2E/index.js +0 -3540
  38. package/publish/lib/cjs/Checkbox/index.d.ts +0 -28
  39. package/publish/lib/cjs/Checkbox/index.js +0 -662
  40. package/publish/lib/cjs/ColorPicker/index.d.ts +0 -27
  41. package/publish/lib/cjs/ColorPicker/index.js +0 -662
  42. package/publish/lib/cjs/Date/index.d.ts +0 -70
  43. package/publish/lib/cjs/DigitalClock/index.d.ts +0 -7
  44. package/publish/lib/cjs/DigitalClock/index.js +0 -402
  45. package/publish/lib/cjs/DragDropList/index.d.ts +0 -44
  46. package/publish/lib/cjs/DragDropList/index.js +0 -1587
  47. package/publish/lib/cjs/DropdownMenu/index.d.ts +0 -38
  48. package/publish/lib/cjs/DropdownMenu/index.js +0 -1498
  49. package/publish/lib/cjs/DynamicFields/index.d.ts +0 -40
  50. package/publish/lib/cjs/DynamicFields/index.js +0 -810
  51. package/publish/lib/cjs/EventCalendar/index.d.ts +0 -61
  52. package/publish/lib/cjs/EventCalendar/index.js +0 -3740
  53. package/publish/lib/cjs/EventCalendarTimeline/index.d.ts +0 -100
  54. package/publish/lib/cjs/EventCalendarTimeline/index.js +0 -6084
  55. package/publish/lib/cjs/File/index.d.ts +0 -40
  56. package/publish/lib/cjs/File/index.js +0 -1751
  57. package/publish/lib/cjs/HorizontalScrollContent/index.d.ts +0 -14
  58. package/publish/lib/cjs/HorizontalScrollContent/index.js +0 -426
  59. package/publish/lib/cjs/Input/index.d.ts +0 -59
  60. package/publish/lib/cjs/Input/index.js +0 -1455
  61. package/publish/lib/cjs/LiveSearch/index.d.ts +0 -69
  62. package/publish/lib/cjs/LiveSearch/index.js +0 -3626
  63. package/publish/lib/cjs/MasonryLayout/index.d.ts +0 -14
  64. package/publish/lib/cjs/MasonryLayout/index.js +0 -689
  65. package/publish/lib/cjs/ModalDialog/index.d.ts +0 -79
  66. package/publish/lib/cjs/ModalDialog/index.js +0 -1695
  67. package/publish/lib/cjs/ModeSwitch/index.d.ts +0 -17
  68. package/publish/lib/cjs/ModeSwitch/index.js +0 -202
  69. package/publish/lib/cjs/MultilevelDropdownMenu/index.d.ts +0 -20
  70. package/publish/lib/cjs/MultilevelDropdownMenu/index.js +0 -930
  71. package/publish/lib/cjs/MultipleCheckboxes/index.d.ts +0 -41
  72. package/publish/lib/cjs/MultipleCheckboxes/index.js +0 -1717
  73. package/publish/lib/cjs/MultipleSelect/index.d.ts +0 -65
  74. package/publish/lib/cjs/MultipleSelect/index.js +0 -3704
  75. package/publish/lib/cjs/NativeSelect/index.d.ts +0 -37
  76. package/publish/lib/cjs/NativeSelect/index.js +0 -1631
  77. package/publish/lib/cjs/NumberInput/index.d.ts +0 -40
  78. package/publish/lib/cjs/NumberInput/index.js +0 -1188
  79. package/publish/lib/cjs/Pagination/index.d.ts +0 -51
  80. package/publish/lib/cjs/Pagination/index.js +0 -612
  81. package/publish/lib/cjs/Radio/index.d.ts +0 -45
  82. package/publish/lib/cjs/Radio/index.js +0 -1391
  83. package/publish/lib/cjs/RangeSlider/index.d.ts +0 -22
  84. package/publish/lib/cjs/RangeSlider/index.js +0 -2665
  85. package/publish/lib/cjs/RootPortal/index.d.ts +0 -8
  86. package/publish/lib/cjs/RootPortal/index.js +0 -141
  87. package/publish/lib/cjs/ScrollReveal/index.d.ts +0 -21
  88. package/publish/lib/cjs/ScrollReveal/index.js +0 -401
  89. package/publish/lib/cjs/Scrollbar/index.d.ts +0 -17
  90. package/publish/lib/cjs/Scrollbar/index.js +0 -1107
  91. package/publish/lib/cjs/SearchBar/index.d.ts +0 -41
  92. package/publish/lib/cjs/SearchBar/index.js +0 -701
  93. package/publish/lib/cjs/Select/index.d.ts +0 -99
  94. package/publish/lib/cjs/Select/index.js +0 -5697
  95. package/publish/lib/cjs/ShowMoreLess/index.d.ts +0 -36
  96. package/publish/lib/cjs/ShowMoreLess/index.js +0 -387
  97. package/publish/lib/cjs/Switch/index.d.ts +0 -25
  98. package/publish/lib/cjs/Switch/index.js +0 -628
  99. package/publish/lib/cjs/Table/index.d.ts +0 -12
  100. package/publish/lib/cjs/Table/index.js +0 -2062
  101. package/publish/lib/cjs/Tabs/index.d.ts +0 -3
  102. package/publish/lib/cjs/Tabs/index.js +0 -771
  103. package/publish/lib/cjs/TagInput/index.d.ts +0 -31
  104. package/publish/lib/cjs/TagInput/index.js +0 -1144
  105. package/publish/lib/cjs/Textarea/index.d.ts +0 -50
  106. package/publish/lib/cjs/Textarea/index.js +0 -1784
  107. package/publish/lib/cjs/Toast/index.d.ts +0 -34
  108. package/publish/lib/cjs/Toast/index.js +0 -861
  109. package/publish/lib/cjs/Tooltip/index.d.ts +0 -23
  110. package/publish/lib/cjs/Tooltip/index.js +0 -1674
  111. package/publish/lib/cjs/Tree/index.d.ts +0 -62
  112. package/publish/lib/cjs/Tree/index.js +0 -1960
  113. package/publish/lib/cjs/Utils/anim.d.ts +0 -11
  114. package/publish/lib/cjs/Utils/anim.js +0 -400
  115. package/publish/lib/cjs/Utils/bodyScrollLock.d.ts +0 -8
  116. package/publish/lib/cjs/Utils/bodyScrollLock.js +0 -311
  117. package/publish/lib/cjs/Utils/buffer.d.ts +0 -67
  118. package/publish/lib/cjs/Utils/buffer.js +0 -343
  119. package/publish/lib/cjs/Utils/cls.d.ts +0 -15
  120. package/publish/lib/cjs/Utils/cls.js +0 -124
  121. package/publish/lib/cjs/Utils/convert.d.ts +0 -25
  122. package/publish/lib/cjs/Utils/convert.js +0 -109
  123. package/publish/lib/cjs/Utils/date.d.ts +0 -217
  124. package/publish/lib/cjs/Utils/date.js +0 -567
  125. package/publish/lib/cjs/Utils/dom.d.ts +0 -13
  126. package/publish/lib/cjs/Utils/dom.js +0 -215
  127. package/publish/lib/cjs/Utils/easing.d.ts +0 -29
  128. package/publish/lib/cjs/Utils/easing.js +0 -221
  129. package/publish/lib/cjs/Utils/extract.d.ts +0 -28
  130. package/publish/lib/cjs/Utils/extract.js +0 -130
  131. package/publish/lib/cjs/Utils/getElementProperty.d.ts +0 -52
  132. package/publish/lib/cjs/Utils/getElementProperty.js +0 -189
  133. package/publish/lib/cjs/Utils/guid.d.ts +0 -7
  134. package/publish/lib/cjs/Utils/guid.js +0 -67
  135. package/publish/lib/cjs/Utils/initDefaultOptions.d.ts +0 -21
  136. package/publish/lib/cjs/Utils/initDefaultOptions.js +0 -131
  137. package/publish/lib/cjs/Utils/inputsCalculation.d.ts +0 -28
  138. package/publish/lib/cjs/Utils/inputsCalculation.js +0 -188
  139. package/publish/lib/cjs/Utils/math.d.ts +0 -77
  140. package/publish/lib/cjs/Utils/math.js +0 -305
  141. package/publish/lib/cjs/Utils/object.d.ts +0 -18
  142. package/publish/lib/cjs/Utils/object.js +0 -120
  143. package/publish/lib/cjs/Utils/os.d.ts +0 -2
  144. package/publish/lib/cjs/Utils/os.js +0 -104
  145. package/publish/lib/cjs/Utils/performance.d.ts +0 -3
  146. package/publish/lib/cjs/Utils/performance.js +0 -94
  147. package/publish/lib/cjs/Utils/tree.d.ts +0 -40
  148. package/publish/lib/cjs/Utils/tree.js +0 -195
  149. package/publish/lib/cjs/Utils/useAutosizeTextArea.d.ts +0 -10
  150. package/publish/lib/cjs/Utils/useAutosizeTextArea.js +0 -227
  151. package/publish/lib/cjs/Utils/useBoundedDrag.d.ts +0 -125
  152. package/publish/lib/cjs/Utils/useBoundedDrag.js +0 -380
  153. package/publish/lib/cjs/Utils/useClickOutside.d.ts +0 -33
  154. package/publish/lib/cjs/Utils/useClickOutside.js +0 -166
  155. package/publish/lib/cjs/Utils/useComId.d.ts +0 -6
  156. package/publish/lib/cjs/Utils/useComId.js +0 -114
  157. package/publish/lib/cjs/Utils/useDebounce.d.ts +0 -20
  158. package/publish/lib/cjs/Utils/useDebounce.js +0 -138
  159. package/publish/lib/cjs/Utils/useDragDropPosition.d.ts +0 -169
  160. package/publish/lib/cjs/Utils/useDragDropPosition.js +0 -456
  161. package/publish/lib/cjs/Utils/useDraggable.d.ts +0 -62
  162. package/publish/lib/cjs/Utils/useDraggable.js +0 -348
  163. package/publish/lib/cjs/Utils/useInterval.d.ts +0 -5
  164. package/publish/lib/cjs/Utils/useInterval.js +0 -168
  165. package/publish/lib/cjs/Utils/useIsMobile.d.ts +0 -2
  166. package/publish/lib/cjs/Utils/useIsMobile.js +0 -168
  167. package/publish/lib/cjs/Utils/useKeyPress.d.ts +0 -44
  168. package/publish/lib/cjs/Utils/useKeyPress.js +0 -200
  169. package/publish/lib/cjs/Utils/useThrottle.d.ts +0 -2
  170. package/publish/lib/cjs/Utils/useThrottle.js +0 -136
  171. package/publish/lib/cjs/Utils/useWindowScroll.d.ts +0 -12
  172. package/publish/lib/cjs/Utils/useWindowScroll.js +0 -217
  173. package/publish/lib/cjs/Utils/viewport.d.ts +0 -7
  174. package/publish/lib/cjs/Utils/viewport.js +0 -64
  175. package/publish/lib/cjs/index.d.ts +0 -45
  176. package/publish/lib/cjs/index.js +0 -46
  177. package/publish/lib/css/BackToTop/index.css +0 -34
  178. package/publish/lib/css/CascadingSelect/index.css +0 -216
  179. package/publish/lib/css/CascadingSelectE2E/index.css +0 -216
  180. package/publish/lib/css/ColorPicker/index.css +0 -58
  181. package/publish/lib/css/Date/index.css +0 -434
  182. package/publish/lib/css/DragDropList/index.css +0 -188
  183. package/publish/lib/css/DropdownMenu/index.css +0 -151
  184. package/publish/lib/css/EventCalendar/index.css +0 -300
  185. package/publish/lib/css/EventCalendarTimeline/index.css +0 -694
  186. package/publish/lib/css/HorizontalScrollContent/index.css +0 -70
  187. package/publish/lib/css/LiveSearch/index.css +0 -55
  188. package/publish/lib/css/MultilevelDropdownMenu/index.css +0 -38
  189. package/publish/lib/css/MultipleSelect/index.css +0 -313
  190. package/publish/lib/css/RangeSlider/index.css +0 -150
  191. package/publish/lib/css/Scrollbar/index.css +0 -176
  192. package/publish/lib/css/Select/index.css +0 -368
  193. package/publish/lib/css/ShowMoreLess/index.css +0 -23
  194. package/publish/lib/css/Table/index.css +0 -584
  195. package/publish/lib/css/TagInput/index.css +0 -91
  196. package/publish/lib/css/Toast/index.css +0 -201
  197. package/publish/lib/css/Tooltip/index.css +0 -197
  198. package/publish/lib/css/Tree/index.css +0 -232
  199. package/publish/lib/esm/Accordion/Accordion.tsx +0 -184
  200. package/publish/lib/esm/Accordion/AccordionItem.tsx +0 -143
  201. package/publish/lib/esm/Accordion/index.tsx +0 -2
  202. package/publish/lib/esm/BackToTop/index.scss +0 -47
  203. package/publish/lib/esm/BackToTop/index.tsx +0 -177
  204. package/publish/lib/esm/CascadingSelect/Group.tsx +0 -82
  205. package/publish/lib/esm/CascadingSelect/index.scss +0 -291
  206. package/publish/lib/esm/CascadingSelect/index.tsx +0 -1203
  207. package/publish/lib/esm/CascadingSelectE2E/Group.tsx +0 -83
  208. package/publish/lib/esm/CascadingSelectE2E/index.scss +0 -293
  209. package/publish/lib/esm/CascadingSelectE2E/index.tsx +0 -1471
  210. package/publish/lib/esm/Checkbox/index.tsx +0 -193
  211. package/publish/lib/esm/ColorPicker/index.scss +0 -91
  212. package/publish/lib/esm/ColorPicker/index.tsx +0 -204
  213. package/publish/lib/esm/Date/Calendar.tsx +0 -723
  214. package/publish/lib/esm/Date/index.scss +0 -567
  215. package/publish/lib/esm/Date/index.tsx +0 -1683
  216. package/publish/lib/esm/Date/localization/en_US.js +0 -13
  217. package/publish/lib/esm/Date/localization/zh_CN.js +0 -12
  218. package/publish/lib/esm/DigitalClock/index.tsx +0 -74
  219. package/publish/lib/esm/DragDropList/index.scss +0 -245
  220. package/publish/lib/esm/DragDropList/index.tsx +0 -494
  221. package/publish/lib/esm/DropdownMenu/Option.tsx +0 -55
  222. package/publish/lib/esm/DropdownMenu/index.scss +0 -205
  223. package/publish/lib/esm/DropdownMenu/index.tsx +0 -377
  224. package/publish/lib/esm/DynamicFields/index.tsx +0 -404
  225. package/publish/lib/esm/EventCalendar/index.scss +0 -407
  226. package/publish/lib/esm/EventCalendar/index.tsx +0 -1004
  227. package/publish/lib/esm/EventCalendarTimeline/index.scss +0 -926
  228. package/publish/lib/esm/EventCalendarTimeline/index.tsx +0 -2683
  229. package/publish/lib/esm/File/index.tsx +0 -477
  230. package/publish/lib/esm/HorizontalScrollContent/index.scss +0 -87
  231. package/publish/lib/esm/HorizontalScrollContent/index.tsx +0 -171
  232. package/publish/lib/esm/Input/index.tsx +0 -614
  233. package/publish/lib/esm/LiveSearch/index.scss +0 -82
  234. package/publish/lib/esm/LiveSearch/index.tsx +0 -960
  235. package/publish/lib/esm/MasonryLayout/index.tsx +0 -326
  236. package/publish/lib/esm/ModalDialog/index.tsx +0 -552
  237. package/publish/lib/esm/ModeSwitch/index.tsx +0 -82
  238. package/publish/lib/esm/MultilevelDropdownMenu/ItemList.tsx +0 -265
  239. package/publish/lib/esm/MultilevelDropdownMenu/index.scss +0 -79
  240. package/publish/lib/esm/MultilevelDropdownMenu/index.tsx +0 -77
  241. package/publish/lib/esm/MultipleCheckboxes/index.tsx +0 -669
  242. package/publish/lib/esm/MultipleSelect/index.scss +0 -398
  243. package/publish/lib/esm/MultipleSelect/index.tsx +0 -766
  244. package/publish/lib/esm/MultipleSelect/utils/func.ts +0 -61
  245. package/publish/lib/esm/NativeSelect/index.tsx +0 -396
  246. package/publish/lib/esm/NativeSelect/utils/func.ts +0 -49
  247. package/publish/lib/esm/NumberInput/index.tsx +0 -385
  248. package/publish/lib/esm/Pagination/index.tsx +0 -286
  249. package/publish/lib/esm/Pagination/pagination-navigators.tsx +0 -60
  250. package/publish/lib/esm/Radio/index.tsx +0 -670
  251. package/publish/lib/esm/RangeSlider/index.scss +0 -186
  252. package/publish/lib/esm/RangeSlider/index.tsx +0 -241
  253. package/publish/lib/esm/RootPortal/index.tsx +0 -53
  254. package/publish/lib/esm/ScrollReveal/index.tsx +0 -148
  255. package/publish/lib/esm/Scrollbar/index.scss +0 -221
  256. package/publish/lib/esm/Scrollbar/index.tsx +0 -561
  257. package/publish/lib/esm/SearchBar/index.tsx +0 -253
  258. package/publish/lib/esm/Select/index.scss +0 -553
  259. package/publish/lib/esm/Select/index.tsx +0 -2816
  260. package/publish/lib/esm/Select/utils/func.ts +0 -106
  261. package/publish/lib/esm/ShowMoreLess/index.scss +0 -27
  262. package/publish/lib/esm/ShowMoreLess/index.tsx +0 -145
  263. package/publish/lib/esm/Switch/index.tsx +0 -147
  264. package/publish/lib/esm/Table/Table.tsx +0 -257
  265. package/publish/lib/esm/Table/TableBody.tsx +0 -41
  266. package/publish/lib/esm/Table/TableCaption.tsx +0 -34
  267. package/publish/lib/esm/Table/TableCell.tsx +0 -123
  268. package/publish/lib/esm/Table/TableColgroup.tsx +0 -38
  269. package/publish/lib/esm/Table/TableContext.tsx +0 -26
  270. package/publish/lib/esm/Table/TableFoot.tsx +0 -28
  271. package/publish/lib/esm/Table/TableHead.tsx +0 -28
  272. package/publish/lib/esm/Table/TableRow.tsx +0 -76
  273. package/publish/lib/esm/Table/index.scss +0 -418
  274. package/publish/lib/esm/Table/index.tsx +0 -14
  275. package/publish/lib/esm/Table/utils/DragHandleSprite.tsx +0 -46
  276. package/publish/lib/esm/Table/utils/SortSprite.tsx +0 -57
  277. package/publish/lib/esm/Table/utils/TableFilter.tsx +0 -56
  278. package/publish/lib/esm/Table/utils/ToggleSelection.tsx +0 -225
  279. package/publish/lib/esm/Table/utils/func.ts +0 -171
  280. package/publish/lib/esm/Table/utils/hooks/useTableDraggable.tsx +0 -342
  281. package/publish/lib/esm/Table/utils/hooks/useTableKeyPress.tsx +0 -154
  282. package/publish/lib/esm/Table/utils/hooks/useTableResponsive.tsx +0 -92
  283. package/publish/lib/esm/Table/utils/hooks/useTableSort.tsx +0 -143
  284. package/publish/lib/esm/Tabs/TabList.tsx +0 -50
  285. package/publish/lib/esm/Tabs/TabPanel.tsx +0 -44
  286. package/publish/lib/esm/Tabs/Tabs.tsx +0 -282
  287. package/publish/lib/esm/Tabs/index.tsx +0 -3
  288. package/publish/lib/esm/TagInput/index.scss +0 -126
  289. package/publish/lib/esm/TagInput/index.tsx +0 -352
  290. package/publish/lib/esm/Textarea/index.tsx +0 -608
  291. package/publish/lib/esm/Toast/Item.tsx +0 -124
  292. package/publish/lib/esm/Toast/index.scss +0 -269
  293. package/publish/lib/esm/Toast/index.tsx +0 -374
  294. package/publish/lib/esm/Tooltip/index.scss +0 -269
  295. package/publish/lib/esm/Tooltip/index.tsx +0 -312
  296. package/publish/lib/esm/Tree/TreeList.tsx +0 -616
  297. package/publish/lib/esm/Tree/index.scss +0 -386
  298. package/publish/lib/esm/Tree/index.tsx +0 -396
  299. package/publish/lib/esm/Tree/init-height.tsx +0 -27
  300. package/publish/lib/esm/Tree/utils/func.ts +0 -15
  301. package/publish/lib/esm/Utils/hooks/useAutosizeTextArea.tsx +0 -125
  302. package/publish/lib/esm/Utils/hooks/useBoundedDrag.tsx +0 -301
  303. package/publish/lib/esm/Utils/hooks/useClickOutside.tsx +0 -69
  304. package/publish/lib/esm/Utils/hooks/useComId.tsx +0 -13
  305. package/publish/lib/esm/Utils/hooks/useDebounce.tsx +0 -40
  306. package/publish/lib/esm/Utils/hooks/useDragDropPosition.tsx +0 -420
  307. package/publish/lib/esm/Utils/hooks/useDraggable.tsx +0 -265
  308. package/publish/lib/esm/Utils/hooks/useInterval.tsx +0 -74
  309. package/publish/lib/esm/Utils/hooks/useIsMobile.tsx +0 -56
  310. package/publish/lib/esm/Utils/hooks/useKeyPress.tsx +0 -104
  311. package/publish/lib/esm/Utils/hooks/useThrottle.tsx +0 -39
  312. package/publish/lib/esm/Utils/hooks/useWindowScroll.tsx +0 -83
  313. package/publish/lib/esm/Utils/libs/anim.ts +0 -96
  314. package/publish/lib/esm/Utils/libs/buffer.ts +0 -262
  315. package/publish/lib/esm/Utils/libs/cls.ts +0 -64
  316. package/publish/lib/esm/Utils/libs/convert.ts +0 -59
  317. package/publish/lib/esm/Utils/libs/date.ts +0 -578
  318. package/publish/lib/esm/Utils/libs/dom.ts +0 -150
  319. package/publish/lib/esm/Utils/libs/easing.ts +0 -201
  320. package/publish/lib/esm/Utils/libs/extract.ts +0 -86
  321. package/publish/lib/esm/Utils/libs/getElementProperty.ts +0 -150
  322. package/publish/lib/esm/Utils/libs/guid.ts +0 -16
  323. package/publish/lib/esm/Utils/libs/initDefaultOptions.ts +0 -104
  324. package/publish/lib/esm/Utils/libs/inputsCalculation.ts +0 -160
  325. package/publish/lib/esm/Utils/libs/math.ts +0 -276
  326. package/publish/lib/esm/Utils/libs/object.ts +0 -68
  327. package/publish/lib/esm/Utils/libs/os.ts +0 -63
  328. package/publish/lib/esm/Utils/libs/performance.ts +0 -47
  329. package/publish/lib/esm/Utils/libs/tree.ts +0 -119
  330. package/publish/lib/esm/Utils/libs/viewport.ts +0 -20
  331. package/publish/lib/esm/Utils/plugins/bodyScrollLock.ts +0 -286
  332. package/publish/lib/esm/index.js +0 -43
  333. package/publish/package.json +0 -1
  334. /package/{publish/Accordion → Accordion}/index.d.ts +0 -0
  335. /package/{publish/Accordion → Accordion}/index.js +0 -0
  336. /package/{publish/BackToTop → BackToTop}/index.css +0 -0
  337. /package/{publish/BackToTop → BackToTop}/index.d.ts +0 -0
  338. /package/{publish/BackToTop → BackToTop}/index.js +0 -0
  339. /package/{publish/CascadingSelect → CascadingSelect}/index.css +0 -0
  340. /package/{publish/CascadingSelect → CascadingSelect}/index.d.ts +0 -0
  341. /package/{publish/CascadingSelect → CascadingSelect}/index.js +0 -0
  342. /package/{publish/CascadingSelectE2E → CascadingSelectE2E}/index.css +0 -0
  343. /package/{publish/CascadingSelectE2E → CascadingSelectE2E}/index.d.ts +0 -0
  344. /package/{publish/CascadingSelectE2E → CascadingSelectE2E}/index.js +0 -0
  345. /package/{publish/Checkbox → Checkbox}/index.d.ts +0 -0
  346. /package/{publish/Checkbox → Checkbox}/index.js +0 -0
  347. /package/{publish/ColorPicker → ColorPicker}/index.css +0 -0
  348. /package/{publish/ColorPicker → ColorPicker}/index.d.ts +0 -0
  349. /package/{publish/ColorPicker → ColorPicker}/index.js +0 -0
  350. /package/{publish/Date → Date}/index.css +0 -0
  351. /package/{publish/Date → Date}/index.d.ts +0 -0
  352. /package/{publish/Date → Date}/index.js +0 -0
  353. /package/{publish/DigitalClock → DigitalClock}/index.d.ts +0 -0
  354. /package/{publish/DigitalClock → DigitalClock}/index.js +0 -0
  355. /package/{publish/DragDropList → DragDropList}/index.css +0 -0
  356. /package/{publish/DragDropList → DragDropList}/index.d.ts +0 -0
  357. /package/{publish/DragDropList → DragDropList}/index.js +0 -0
  358. /package/{publish/DropdownMenu → DropdownMenu}/index.css +0 -0
  359. /package/{publish/DropdownMenu → DropdownMenu}/index.d.ts +0 -0
  360. /package/{publish/DropdownMenu → DropdownMenu}/index.js +0 -0
  361. /package/{publish/DynamicFields → DynamicFields}/index.d.ts +0 -0
  362. /package/{publish/DynamicFields → DynamicFields}/index.js +0 -0
  363. /package/{publish/EventCalendar → EventCalendar}/index.css +0 -0
  364. /package/{publish/EventCalendar → EventCalendar}/index.d.ts +0 -0
  365. /package/{publish/EventCalendar → EventCalendar}/index.js +0 -0
  366. /package/{publish/EventCalendarTimeline → EventCalendarTimeline}/index.css +0 -0
  367. /package/{publish/EventCalendarTimeline → EventCalendarTimeline}/index.d.ts +0 -0
  368. /package/{publish/EventCalendarTimeline → EventCalendarTimeline}/index.js +0 -0
  369. /package/{publish/File → File}/index.d.ts +0 -0
  370. /package/{publish/File → File}/index.js +0 -0
  371. /package/{publish/HorizontalScrollContent → HorizontalScrollContent}/index.css +0 -0
  372. /package/{publish/HorizontalScrollContent → HorizontalScrollContent}/index.d.ts +0 -0
  373. /package/{publish/HorizontalScrollContent → HorizontalScrollContent}/index.js +0 -0
  374. /package/{publish/Input → Input}/index.d.ts +0 -0
  375. /package/{publish/Input → Input}/index.js +0 -0
  376. /package/{publish/LiveSearch → LiveSearch}/index.css +0 -0
  377. /package/{publish/LiveSearch → LiveSearch}/index.d.ts +0 -0
  378. /package/{publish/LiveSearch → LiveSearch}/index.js +0 -0
  379. /package/{publish/MasonryLayout → MasonryLayout}/index.d.ts +0 -0
  380. /package/{publish/MasonryLayout → MasonryLayout}/index.js +0 -0
  381. /package/{publish/ModalDialog → ModalDialog}/index.d.ts +0 -0
  382. /package/{publish/ModalDialog → ModalDialog}/index.js +0 -0
  383. /package/{publish/ModeSwitch → ModeSwitch}/index.d.ts +0 -0
  384. /package/{publish/ModeSwitch → ModeSwitch}/index.js +0 -0
  385. /package/{publish/MultilevelDropdownMenu → MultilevelDropdownMenu}/index.css +0 -0
  386. /package/{publish/MultilevelDropdownMenu → MultilevelDropdownMenu}/index.d.ts +0 -0
  387. /package/{publish/MultilevelDropdownMenu → MultilevelDropdownMenu}/index.js +0 -0
  388. /package/{publish/MultipleCheckboxes → MultipleCheckboxes}/index.d.ts +0 -0
  389. /package/{publish/MultipleCheckboxes → MultipleCheckboxes}/index.js +0 -0
  390. /package/{publish/MultipleSelect → MultipleSelect}/index.css +0 -0
  391. /package/{publish/MultipleSelect → MultipleSelect}/index.d.ts +0 -0
  392. /package/{publish/MultipleSelect → MultipleSelect}/index.js +0 -0
  393. /package/{publish/NativeSelect → NativeSelect}/index.d.ts +0 -0
  394. /package/{publish/NativeSelect → NativeSelect}/index.js +0 -0
  395. /package/{publish/NumberInput → NumberInput}/index.d.ts +0 -0
  396. /package/{publish/NumberInput → NumberInput}/index.js +0 -0
  397. /package/{publish/Pagination → Pagination}/index.d.ts +0 -0
  398. /package/{publish/Pagination → Pagination}/index.js +0 -0
  399. /package/{publish/Radio → Radio}/index.d.ts +0 -0
  400. /package/{publish/Radio → Radio}/index.js +0 -0
  401. /package/{publish/RangeSlider → RangeSlider}/index.css +0 -0
  402. /package/{publish/RangeSlider → RangeSlider}/index.d.ts +0 -0
  403. /package/{publish/RangeSlider → RangeSlider}/index.js +0 -0
  404. /package/{publish/RootPortal → RootPortal}/index.d.ts +0 -0
  405. /package/{publish/RootPortal → RootPortal}/index.js +0 -0
  406. /package/{publish/ScrollReveal → ScrollReveal}/index.d.ts +0 -0
  407. /package/{publish/ScrollReveal → ScrollReveal}/index.js +0 -0
  408. /package/{publish/Scrollbar → Scrollbar}/index.css +0 -0
  409. /package/{publish/Scrollbar → Scrollbar}/index.d.ts +0 -0
  410. /package/{publish/Scrollbar → Scrollbar}/index.js +0 -0
  411. /package/{publish/SearchBar → SearchBar}/index.d.ts +0 -0
  412. /package/{publish/SearchBar → SearchBar}/index.js +0 -0
  413. /package/{publish/Select → Select}/index.css +0 -0
  414. /package/{publish/Select → Select}/index.d.ts +0 -0
  415. /package/{publish/Select → Select}/index.js +0 -0
  416. /package/{publish/ShowMoreLess → ShowMoreLess}/index.css +0 -0
  417. /package/{publish/ShowMoreLess → ShowMoreLess}/index.d.ts +0 -0
  418. /package/{publish/ShowMoreLess → ShowMoreLess}/index.js +0 -0
  419. /package/{publish/Switch → Switch}/index.d.ts +0 -0
  420. /package/{publish/Switch → Switch}/index.js +0 -0
  421. /package/{publish/Table → Table}/index.css +0 -0
  422. /package/{publish/Table → Table}/index.d.ts +0 -0
  423. /package/{publish/Table → Table}/index.js +0 -0
  424. /package/{publish/Tabs → Tabs}/index.d.ts +0 -0
  425. /package/{publish/Tabs → Tabs}/index.js +0 -0
  426. /package/{publish/TagInput → TagInput}/index.css +0 -0
  427. /package/{publish/TagInput → TagInput}/index.d.ts +0 -0
  428. /package/{publish/TagInput → TagInput}/index.js +0 -0
  429. /package/{publish/Textarea → Textarea}/index.d.ts +0 -0
  430. /package/{publish/Textarea → Textarea}/index.js +0 -0
  431. /package/{publish/Toast → Toast}/index.css +0 -0
  432. /package/{publish/Toast → Toast}/index.d.ts +0 -0
  433. /package/{publish/Toast → Toast}/index.js +0 -0
  434. /package/{publish/Tooltip → Tooltip}/index.css +0 -0
  435. /package/{publish/Tooltip → Tooltip}/index.d.ts +0 -0
  436. /package/{publish/Tooltip → Tooltip}/index.js +0 -0
  437. /package/{publish/Tree → Tree}/index.css +0 -0
  438. /package/{publish/Tree → Tree}/index.d.ts +0 -0
  439. /package/{publish/Tree → Tree}/index.js +0 -0
  440. /package/{publish/Utils → Utils}/anim.d.ts +0 -0
  441. /package/{publish/Utils → Utils}/anim.js +0 -0
  442. /package/{publish/Utils → Utils}/bodyScrollLock.d.ts +0 -0
  443. /package/{publish/Utils → Utils}/bodyScrollLock.js +0 -0
  444. /package/{publish/Utils → Utils}/buffer.d.ts +0 -0
  445. /package/{publish/Utils → Utils}/buffer.js +0 -0
  446. /package/{publish/Utils → Utils}/cls.d.ts +0 -0
  447. /package/{publish/Utils → Utils}/cls.js +0 -0
  448. /package/{publish/Utils → Utils}/convert.d.ts +0 -0
  449. /package/{publish/Utils → Utils}/convert.js +0 -0
  450. /package/{publish/Utils → Utils}/date.d.ts +0 -0
  451. /package/{publish/Utils → Utils}/date.js +0 -0
  452. /package/{publish/Utils → Utils}/dom.d.ts +0 -0
  453. /package/{publish/Utils → Utils}/dom.js +0 -0
  454. /package/{publish/Utils → Utils}/easing.d.ts +0 -0
  455. /package/{publish/Utils → Utils}/easing.js +0 -0
  456. /package/{publish/Utils → Utils}/extract.d.ts +0 -0
  457. /package/{publish/Utils → Utils}/extract.js +0 -0
  458. /package/{publish/Utils → Utils}/getElementProperty.d.ts +0 -0
  459. /package/{publish/Utils → Utils}/getElementProperty.js +0 -0
  460. /package/{publish/Utils → Utils}/guid.d.ts +0 -0
  461. /package/{publish/Utils → Utils}/guid.js +0 -0
  462. /package/{publish/Utils → Utils}/initDefaultOptions.d.ts +0 -0
  463. /package/{publish/Utils → Utils}/initDefaultOptions.js +0 -0
  464. /package/{publish/Utils → Utils}/inputsCalculation.d.ts +0 -0
  465. /package/{publish/Utils → Utils}/inputsCalculation.js +0 -0
  466. /package/{publish/Utils → Utils}/math.d.ts +0 -0
  467. /package/{publish/Utils → Utils}/math.js +0 -0
  468. /package/{publish/Utils → Utils}/object.d.ts +0 -0
  469. /package/{publish/Utils → Utils}/object.js +0 -0
  470. /package/{publish/Utils → Utils}/os.d.ts +0 -0
  471. /package/{publish/Utils → Utils}/os.js +0 -0
  472. /package/{publish/Utils → Utils}/performance.d.ts +0 -0
  473. /package/{publish/Utils → Utils}/performance.js +0 -0
  474. /package/{publish/Utils → Utils}/tree.d.ts +0 -0
  475. /package/{publish/Utils → Utils}/tree.js +0 -0
  476. /package/{publish/Utils → Utils}/useAutosizeTextArea.d.ts +0 -0
  477. /package/{publish/Utils → Utils}/useAutosizeTextArea.js +0 -0
  478. /package/{publish/Utils → Utils}/useBoundedDrag.d.ts +0 -0
  479. /package/{publish/Utils → Utils}/useBoundedDrag.js +0 -0
  480. /package/{publish/Utils → Utils}/useClickOutside.d.ts +0 -0
  481. /package/{publish/Utils → Utils}/useClickOutside.js +0 -0
  482. /package/{publish/Utils → Utils}/useComId.d.ts +0 -0
  483. /package/{publish/Utils → Utils}/useComId.js +0 -0
  484. /package/{publish/Utils → Utils}/useDebounce.d.ts +0 -0
  485. /package/{publish/Utils → Utils}/useDebounce.js +0 -0
  486. /package/{publish/Utils → Utils}/useDragDropPosition.d.ts +0 -0
  487. /package/{publish/Utils → Utils}/useDragDropPosition.js +0 -0
  488. /package/{publish/Utils → Utils}/useDraggable.d.ts +0 -0
  489. /package/{publish/Utils → Utils}/useDraggable.js +0 -0
  490. /package/{publish/Utils → Utils}/useInterval.d.ts +0 -0
  491. /package/{publish/Utils → Utils}/useInterval.js +0 -0
  492. /package/{publish/Utils → Utils}/useIsMobile.d.ts +0 -0
  493. /package/{publish/Utils → Utils}/useIsMobile.js +0 -0
  494. /package/{publish/Utils → Utils}/useKeyPress.d.ts +0 -0
  495. /package/{publish/Utils → Utils}/useKeyPress.js +0 -0
  496. /package/{publish/Utils → Utils}/useThrottle.d.ts +0 -0
  497. /package/{publish/Utils → Utils}/useThrottle.js +0 -0
  498. /package/{publish/Utils → Utils}/useWindowScroll.d.ts +0 -0
  499. /package/{publish/Utils → Utils}/useWindowScroll.js +0 -0
  500. /package/{publish/Utils → Utils}/viewport.d.ts +0 -0
  501. /package/{publish/Utils → Utils}/viewport.js +0 -0
@@ -0,0 +1,1171 @@
1
+
2
+ import React, { useEffect, useState, useRef, useImperativeHandle } from "react";
3
+
4
+
5
+ import Textarea from 'funda-textarea';
6
+ import RootPortal from 'funda-root-portal';
7
+
8
+ import useComId from 'funda-utils/dist/cjs/useComId';
9
+ import useDebounce from 'funda-utils/dist/cjs/useDebounce';
10
+ import useThrottle from 'funda-utils/dist/cjs/useThrottle';
11
+
12
+
13
+
14
+ // loader
15
+ import PureLoader from './PureLoader';
16
+ import TypingEffect from "./TypingEffect";
17
+
18
+ import {
19
+ isValidJSON,
20
+ formatLatestDisplayContent,
21
+ formatName,
22
+ fixHtmlTags
23
+ } from './utils/func';
24
+
25
+ import useStreamController from './useStreamController';
26
+
27
+ export type MessageDetail = {
28
+ sender: string; // Sender's name
29
+ timestamp: string; // Time when the message was sent
30
+ content: string; // The message content
31
+ tag: string; // such as '[reply]'
32
+ };
33
+
34
+ export interface FloatingButton {
35
+ label: string; // HTML string
36
+ value: string;
37
+ onClick: string;
38
+ }
39
+
40
+ export interface RequestConfig {
41
+ apiUrl: string;
42
+ requestBody: string; // JSON string for request body template
43
+ responseExtractor: string; // JSON path to extract response
44
+ }
45
+
46
+ export type ChatboxProps = {
47
+ debug?: boolean;
48
+ prefix?: string;
49
+ contentRef?: React.RefObject<any>;
50
+ model?: string;
51
+ baseUrl?: string;
52
+ apiKey?: string;
53
+ defaultMessages?: MessageDetail[];
54
+ verbose?: boolean;
55
+ reasoningSwitchLabel?: string;
56
+ stopLabel?: React.ReactNode;
57
+ questionName?: React.ReactNode;
58
+ answerName?: React.ReactNode;
59
+ questionNameIcon?: string;
60
+ answerNameIcon?: string;
61
+ bubble?: boolean;
62
+ bubbleLabel?: string;
63
+ sendLabel?: string;
64
+ sendLoading?: boolean;
65
+ sendLoadingLabel?: string;
66
+ placeholder?: string;
67
+ noDataPlaceholder?: string;
68
+ requestConfig: RequestConfig;
69
+ headerConfig?: any;
70
+ maxHistoryLength?: number;
71
+ contextData?: Record<string, any>; // Dynamic JSON data
72
+ toolkitButtons?: FloatingButton[];
73
+ newChatButton?: FloatingButton;
74
+ renderParser?: (input: string) => Promise<string>;
75
+ requestBodyFormatter?: (body: any, contextData: Record<string, any>, conversationHistory: MessageDetail[]) => any;
76
+ nameFormatter?: (input: string) => string;
77
+ onInputChange?: (controlRef: React.RefObject<any>, val: string) => any;
78
+ onChunk?: (controlRef: React.RefObject<any>, lastContent: string, conversationHistory: MessageDetail[]) => any;
79
+ onComplete?: (controlRef: React.RefObject<any>, lastContent: string, conversationHistory: MessageDetail[]) => any;
80
+ };
81
+
82
+
83
+ const Chatbox = (props: ChatboxProps) => {
84
+
85
+ const chatId = useComId().replace(/\-/g, '_');
86
+
87
+ // Store latest props in refs
88
+ const propsRef = useRef<any>(props);
89
+
90
+ // Store context data in ref to get latest values
91
+ const contextDataRef = useRef<Record<string, any> | undefined>(props.contextData);
92
+
93
+ // Store config in ref to get latest values
94
+ const configRef = useRef<RequestConfig>({
95
+ apiUrl: "{baseUrl}/v1/chat/completions",
96
+ requestBody: `{
97
+ "model": "{model}",
98
+ "messages": [{
99
+ "role": "user",
100
+ "content": "{message}"
101
+ }],
102
+ "stream": true
103
+ }`,
104
+ responseExtractor: "data.choices.0.delta.content"
105
+ });
106
+
107
+
108
+ //
109
+ const rootRef = useRef<HTMLDivElement>(null);
110
+ const msgContainerRef = useRef<HTMLDivElement>(null);
111
+ const msInput = useRef<HTMLTextAreaElement>(null);
112
+ const inputContentRef = useRef<any>(null);
113
+
114
+ const [loaderDisplay, setLoaderDisplay] = useState<boolean>(false);
115
+ const [loading, setLoading] = useState<boolean>(false);
116
+ const [thinking, setThinking] = useState<boolean>(false);
117
+ const [show, setShow] = useState<boolean>(false);
118
+ const [msgList, setMsgList] = useState<MessageDetail[]>([]);
119
+ const [elapsedTime, setElapsedTime] = useState<number>(0);
120
+ const [tempAnimText, setTempAnimText] = useState<string>('');
121
+
122
+ //
123
+ const timer = useRef<any>(null);
124
+
125
+
126
+ //================================================================
127
+ // helper
128
+ //================================================================
129
+ const exposedMethods = () => {
130
+ return {
131
+ chatOpen: () => {
132
+ setShow(true);
133
+ setTimeout(() => {
134
+ if (msInput.current) msInput.current.focus();
135
+ }, 0);
136
+ },
137
+ chatClose: () => {
138
+ setShow(false);
139
+ },
140
+ clearData: () => {
141
+ setMsgList([]);
142
+ conversationHistory.current = [];
143
+ },
144
+ sendMsg: () => {
145
+ handleClickSafe();
146
+ },
147
+ getHistory: () => conversationHistory.current,
148
+ trimHistory: (length?: number) => {
149
+ const maxLength = length || args().maxHistoryLength || 20;
150
+ if (conversationHistory.current.length > maxLength) {
151
+ conversationHistory.current = conversationHistory.current.slice(-maxLength);
152
+ }
153
+ },
154
+ setVal: (v: string) => {
155
+ if (inputContentRef.current) inputContentRef.current.set(v);
156
+ },
157
+ setContextData: (v: Record<string, any>) => {
158
+ contextDataRef.current = v;
159
+ },
160
+
161
+ };
162
+ };
163
+
164
+ const scrollToBottom = useThrottle(() => {
165
+ if (msgContainerRef.current) {
166
+ msgContainerRef.current.scrollTop = msgContainerRef.current.scrollHeight;
167
+ }
168
+ }, 300, []);
169
+
170
+ const args = () => {
171
+ const currentProps = propsRef.current;
172
+ if (typeof currentProps.headerConfig === 'undefined' || typeof configRef.current.apiUrl === 'undefined') {
173
+ return {};
174
+ }
175
+
176
+ const {
177
+ debug,
178
+ prefix,
179
+ contentRef,
180
+ model,
181
+ baseUrl,
182
+ apiKey,
183
+ verbose,
184
+ reasoningSwitchLabel,
185
+ stopLabel,
186
+ questionName,
187
+ answerName,
188
+ bubble,
189
+ bubbleLabel,
190
+ sendLabel,
191
+ sendLoading,
192
+ sendLoadingLabel,
193
+ placeholder,
194
+ noDataPlaceholder,
195
+ requestConfig,
196
+ headerConfig,
197
+ toolkitButtons,
198
+ newChatButton,
199
+ maxHistoryLength,
200
+ renderParser,
201
+ requestBodyFormatter,
202
+ nameFormatter,
203
+ onInputChange,
204
+ onChunk,
205
+ onComplete,
206
+ } = currentProps;
207
+
208
+
209
+ const {
210
+ apiUrl,
211
+ requestBody,
212
+ responseExtractor
213
+ } = configRef.current;
214
+
215
+ const latestContextData = contextDataRef.current ? contextDataRef.current : undefined;
216
+
217
+ let _requestBodyTmpl = requestBody.replace(/\'/g, '"'); // !!! REQUIRED !!!
218
+ let _isStream: boolean = true;
219
+
220
+ // request API
221
+ const requestApiUrl = apiUrl.replace(/\{baseUrl\}/g, baseUrl);
222
+
223
+
224
+ // header config
225
+ const _headerConfig = headerConfig.replace(/\{apiKey\}/g, apiKey)
226
+ .replace(/\'/g, '"'); // !!! REQUIRED !!!
227
+ const headerConfigRes = typeof _headerConfig !== 'undefined' ? (isValidJSON(_headerConfig) ? JSON.parse(_headerConfig) : undefined) : {'Content-Type':'application/json'};
228
+
229
+
230
+ // Determine whether it is in JSON format
231
+ if (!isValidJSON(_requestBodyTmpl)) {
232
+ console.log('--> [ERROR] Wrong JSON format');
233
+ _requestBodyTmpl = '{}';
234
+ return {};
235
+ } else {
236
+ _isStream = JSON.parse(_requestBodyTmpl).hasOwnProperty('stream') && JSON.parse(_requestBodyTmpl).stream === true;
237
+ }
238
+
239
+ // Whether or not to show reasoning
240
+ const withReasoning = typeof verbose === 'undefined' ? true : verbose;
241
+
242
+ // Get latest name values
243
+ const _answerName: string = formatName(answerName, true, currentProps);
244
+ const _questionName: string = formatName(questionName, false, currentProps);
245
+
246
+ // Responder deconstruction
247
+ const responseExtractPath = responseExtractor.split('.');
248
+
249
+ return {
250
+ debug,
251
+ prefix,
252
+ contentRef,
253
+ model,
254
+ baseUrl,
255
+ apiKey,
256
+ verbose,
257
+ reasoningSwitchLabel,
258
+ stopLabel,
259
+ bubble,
260
+ bubbleLabel,
261
+ sendLabel,
262
+ sendLoading,
263
+ sendLoadingLabel,
264
+ placeholder,
265
+ noDataPlaceholder,
266
+ requestConfig,
267
+ maxHistoryLength,
268
+ toolkitButtons,
269
+ newChatButton,
270
+ renderParser,
271
+ requestBodyFormatter,
272
+ nameFormatter,
273
+ onInputChange,
274
+ onChunk,
275
+ onComplete,
276
+
277
+ //
278
+ latestContextData,
279
+ questionNameRes: _questionName,
280
+ answerNameRes: _answerName,
281
+ isStream: _isStream,
282
+ headerConfigRes,
283
+ requestApiUrl,
284
+ requestBodyTmpl: _requestBodyTmpl,
285
+ responseExtractPath,
286
+ withReasoning,
287
+ }
288
+
289
+ }
290
+
291
+
292
+ //================================================================
293
+ // Custom buttons
294
+ //================================================================
295
+ const [activeButtons, setActiveButtons] = useState<Record<string, boolean>>({});
296
+ const executeButtonAction = (actionStr: string, buttonId: string, buttonElement: HTMLButtonElement) => {
297
+ try {
298
+ // Create a new function to execute
299
+ const actionFn = new Function('method', 'isActive', 'button', actionStr);
300
+ /*
301
+ function (method, isActive, button) {
302
+ console.log('Clearing chat');
303
+ method.clearData();
304
+ }
305
+ */
306
+
307
+ // Update the button status
308
+ const newState = !activeButtons[buttonId];
309
+ setActiveButtons(prev => ({
310
+ ...prev,
311
+ [buttonId]: newState
312
+ }));
313
+
314
+ return actionFn(exposedMethods(), newState, buttonElement);
315
+
316
+
317
+ } catch (error) {
318
+ console.error('Error executing button action:', error);
319
+ }
320
+ };
321
+
322
+ //================================================================
323
+ // Conversation History
324
+ //================================================================
325
+ const conversationHistory = useRef<Array<MessageDetail>>([]);
326
+ const updateConversationHistory = (newMessage: MessageDetail) => {
327
+ const maxLength = args().maxHistoryLength || 20;
328
+
329
+ // Add new messages to your history
330
+ conversationHistory.current.push(newMessage);
331
+
332
+ // If the maximum length is exceeded, the oldest record is deleted
333
+ if (conversationHistory.current.length > maxLength) {
334
+ const removeCount = conversationHistory.current.length - maxLength;
335
+ conversationHistory.current = conversationHistory.current.slice(removeCount);
336
+ }
337
+
338
+ };
339
+
340
+
341
+ //================================================================
342
+ // normal request
343
+ //================================================================
344
+ const abortController = useRef<any>(new AbortController()); // DO NOT USE "useState()"
345
+
346
+ const abortNormalRequest = () => {
347
+ console.log('--> Abort stream');
348
+ abortController.current.abort();
349
+ };
350
+
351
+ const reconnectNormalRequest = () => {
352
+ console.log('--> Reconnect stream');
353
+ abortController.current = new AbortController();
354
+ };
355
+
356
+
357
+ //================================================================
358
+ // stream controller
359
+ //================================================================
360
+ const abortStream = () => {
361
+ console.log('--> Abort stream');
362
+ streamController.abort();
363
+ };
364
+
365
+ // parse chunk data
366
+ const parseChunkData = async (chunk: string, index: number, complete: boolean) => {
367
+
368
+ // Store the final content and bind it to loading
369
+ let lastContent: string = '';
370
+
371
+ try {
372
+
373
+
374
+ // Extract response using the path
375
+ const extractPath = args().responseExtractPath?.slice(1);
376
+
377
+ // Streaming data is JSON split by rows
378
+ const lines = chunk.split("\n").filter(line => line.trim() !== "");
379
+
380
+ for (const line of lines) {
381
+
382
+ // debug
383
+ if (args().debug && index < 10 && !complete) {
384
+ console.log(`--> (${index}) ${line}`);
385
+ }
386
+
387
+ // Send the streamed data to the front end
388
+ if (line.indexOf('[DONE]') < 0) {
389
+
390
+ // STEP 1:
391
+ // ------
392
+ // Create a JSON string
393
+ const _content = `${line.replace(/^data:\s*/, '')}`;
394
+
395
+ // Determine whether it is in JSON format
396
+ if (!isValidJSON(_content)) {
397
+ console.log('--> [ERROR] Wrong JSON format');
398
+
399
+ //reset SSE
400
+ closeSSE();
401
+ break; // Exit the loop
402
+ }
403
+
404
+ // STEP 2:
405
+ // ------
406
+ // Response body
407
+ let result = JSON.parse(_content);
408
+
409
+ //*******
410
+ // for Ollama API (STREAM END)
411
+ //*******
412
+ if (typeof result.done !== 'undefined') {
413
+ if (result.done === true) {
414
+ console.log('--> [DONE]');
415
+
416
+ //reset SSE
417
+ closeSSE();
418
+ break; // Exit the loop
419
+ }
420
+ }
421
+
422
+ //*******
423
+ // for OpenAI API
424
+ //*******
425
+ if (extractPath) {
426
+ for (const path of extractPath) {
427
+ result = result[path];
428
+ }
429
+ }
430
+
431
+ let content = result;
432
+
433
+ // STEP 3:
434
+ // ------
435
+ // 🚀 !! IMPORTANT: Skip the error content
436
+ if (typeof content === 'undefined') {
437
+ continue;
438
+ }
439
+
440
+
441
+ // STEP 4:
442
+ // ------
443
+ // Update thinking state
444
+ if (content.includes('<think>')) {
445
+ setThinking(true);
446
+ }
447
+ if (content.includes('</think>')) {
448
+ setThinking(false);
449
+ }
450
+
451
+
452
+ // STEP 5:
453
+ // ------
454
+ // Replace with a valid label
455
+ content = fixHtmlTags(content, args().withReasoning, args().reasoningSwitchLabel);
456
+
457
+
458
+
459
+ // STEP 6:
460
+ // ------
461
+ // By updating the stream text, you can update the UI
462
+ tempLastContent.current += content;
463
+ lastContent += content;
464
+
465
+
466
+ // STEP 7:
467
+ // ------
468
+ let parsedContent = tempLastContent.current;
469
+
470
+ // If a render parser exists, it is used to process the string
471
+ if (typeof args().renderParser === 'function') {
472
+ parsedContent = await args().renderParser(parsedContent);
473
+ }
474
+
475
+
476
+ // STEP 8:
477
+ // ------
478
+ // Real-time output
479
+ if (args().withReasoning) {
480
+ setTempAnimText(formatLatestDisplayContent(parsedContent));
481
+ } else {
482
+ if (!thinking) {
483
+ setTempAnimText(formatLatestDisplayContent(parsedContent));
484
+ }
485
+ }
486
+
487
+ // STEP 9:
488
+ // ------
489
+ // Scroll to the bottom
490
+ scrollToBottom();
491
+
492
+
493
+ } else {
494
+ console.log('--> [DONE]');
495
+
496
+ //reset SSE
497
+ closeSSE();
498
+
499
+ break; // Exit the loop
500
+ }
501
+
502
+ }
503
+ } catch (error) {
504
+ console.error('--> Error processing chunk:', error);
505
+ }
506
+
507
+
508
+
509
+ let latestRes = complete ? lastContent : tempLastContent.current;
510
+
511
+ // If a render parser exists, it is used to process the string
512
+ if (typeof args().renderParser === 'function') {
513
+ latestRes = await args().renderParser(latestRes);
514
+ }
515
+
516
+ return formatLatestDisplayContent(latestRes);
517
+
518
+ };
519
+
520
+ // Store the final content and bind it to loading
521
+ const tempLastContent = useRef<string>('');
522
+ const streamController = useStreamController({
523
+ onChunk: async (chunk: string, index: number) => {
524
+
525
+ // start (Execute it only once)
526
+ if (index === 0) {
527
+ // hide loader
528
+ setLoaderDisplay(false);
529
+ }
530
+
531
+ //
532
+ const res = await parseChunkData(chunk, index, false);
533
+
534
+ //
535
+ args().onChunk?.(inputContentRef.current, res, conversationHistory.current);
536
+ },
537
+ onComplete: async (lastContent: string) => {
538
+ console.log('--> Stream complete');
539
+
540
+ const res = await parseChunkData(lastContent, 0 , true);
541
+
542
+
543
+ // Display AI reply
544
+ displayMessage(args().answerNameRes, res);
545
+
546
+ //
547
+ args().onComplete?.(inputContentRef.current, res, conversationHistory.current);
548
+
549
+ //
550
+ closeSSE();
551
+ },
552
+ onError: (error) => {
553
+ console.error('--> Stream error:', error);
554
+ closeSSE();
555
+ },
556
+ onAbort: () => {
557
+ console.log('--> Stream aborted');
558
+ closeSSE();
559
+ }
560
+ });
561
+
562
+
563
+ //================================================================
564
+ // Core
565
+ //================================================================
566
+ const closeSSE = () => {
567
+
568
+ // reset
569
+ setTempAnimText('');
570
+ tempLastContent.current = '';
571
+
572
+
573
+ // Stop the timer
574
+ clearInterval(timer.current);
575
+ timer.current = null;
576
+
577
+ // loading
578
+ setLoading(false);
579
+
580
+
581
+ }
582
+ const displayMessage = (sender: string | undefined, content: string) => {
583
+ const timestamp = new Date().toLocaleTimeString(); // Get the current time
584
+ const tag = sender === args().answerNameRes ? '[reply]' : '';
585
+
586
+ const newMessage: MessageDetail = {
587
+ sender: sender || '',
588
+ timestamp,
589
+ content,
590
+ tag
591
+ };
592
+
593
+ // update messages history
594
+ updateConversationHistory(newMessage);
595
+
596
+ // Update the message list state
597
+ setMsgList((prevMessages) => [...prevMessages, newMessage]);
598
+
599
+ };
600
+
601
+ const sendMessage = async () => {
602
+ if (rootRef.current === null || msgContainerRef.current === null || msInput.current === null) return;
603
+
604
+ const messageInput: any = msInput.current;
605
+ const message = messageInput.value;
606
+
607
+ if (message.trim() === '') {
608
+ return;
609
+ }
610
+
611
+
612
+ // Start the timer
613
+ setElapsedTime(0); // Reset elapsed time
614
+ timer.current = setInterval(() => {
615
+ setElapsedTime((prev) => prev + 1); // Increment elapsed time every second
616
+ }, 1000);
617
+
618
+ // user message
619
+
620
+ let inputMsg = `${message}`;
621
+ // If a render parser exists, it is used to process the string
622
+ if (typeof args().renderParser === 'function') {
623
+ inputMsg = await args().renderParser(inputMsg);
624
+ }
625
+
626
+ displayMessage(args().questionNameRes, inputMsg); // Display user message
627
+
628
+ // loading
629
+ setLoading(true);
630
+
631
+ // show loader
632
+ setLoaderDisplay(true);
633
+
634
+
635
+ // clear
636
+ if (inputContentRef.current) inputContentRef.current.clear();
637
+
638
+ try {
639
+ const res: any = await mainRequest(message);
640
+
641
+ // reply (normal)
642
+ //======================
643
+ if (!args().isStream) {
644
+ const reply = res.reply;
645
+ let replyRes = `${reply}`;
646
+
647
+ // If a render parser exists, it is used to process the string
648
+ if (typeof args().renderParser === 'function') {
649
+ replyRes = await args().renderParser(replyRes);
650
+ }
651
+
652
+ displayMessage(args().answerNameRes, replyRes); // Display AI reply
653
+
654
+
655
+ //
656
+ args().onChunk?.(inputContentRef.current, replyRes, conversationHistory.current);
657
+ args().onComplete?.(inputContentRef.current, replyRes, conversationHistory.current);
658
+
659
+ //reset SSE
660
+ closeSSE();
661
+
662
+ }
663
+
664
+
665
+ } catch (error) {
666
+
667
+ // loading
668
+ setLoading(false);
669
+
670
+ // Stop the timer
671
+ clearInterval(timer.current);
672
+ timer.current = null;
673
+
674
+ console.error('--> Error sending message:', error);
675
+ displayMessage(args().answerNameRes, `Error: Unable to send message: ${String(error)}`); // Display AI reply
676
+
677
+ }
678
+
679
+ // clear
680
+ messageInput.value = '';
681
+
682
+ // reset textarea height
683
+ if (inputContentRef.current) inputContentRef.current.resetHeight();
684
+
685
+
686
+ // Scroll to the bottom
687
+ scrollToBottom();
688
+ };
689
+
690
+ const handleClickSafe = useDebounce(() => {
691
+ sendMessage();
692
+ }, 300, []);
693
+
694
+ const handleClose = (e: React.MouseEvent) => {
695
+ e.preventDefault();
696
+ e.stopPropagation();
697
+ setShow(false);
698
+
699
+ };
700
+
701
+
702
+ const mainRequest = async (msg: string) => {
703
+
704
+ // Use vLLM's API
705
+ //======================
706
+ try {
707
+ // Parse and interpolate request body template
708
+ let requestBodyRes = JSON.parse(
709
+ (args().requestBodyTmpl || '{}')
710
+ .replace(/\{model\}/g, args().model)
711
+ .replace(/\{message\}/g, msg)
712
+ .replace(/\{token\}/g, chatId)
713
+ );
714
+
715
+ //
716
+ // If a formatter function exists, it is used to process the request body
717
+ if (typeof args().requestBodyFormatter === 'function') {
718
+ requestBodyRes = args().requestBodyFormatter(requestBodyRes, args().latestContextData, conversationHistory.current);
719
+ }
720
+
721
+ // Scroll to the bottom
722
+ setTimeout(() => {
723
+ // Scroll to the bottom
724
+ scrollToBottom();
725
+ }, 500);
726
+
727
+
728
+ if (args().isStream) {
729
+ {/* ======================================================== */}
730
+ {/* ======================== STREAM ====================== */}
731
+ {/* ======================================================== */}
732
+
733
+ const response: any = await fetch((args().requestApiUrl || ''), {
734
+ method: "POST",
735
+ body: JSON.stringify(requestBodyRes),
736
+ headers: args().headerConfigRes
737
+ });
738
+
739
+ if (!response.ok) {
740
+ const _errInfo = `[ERROR] HTTP Error ${response.status}: ${response.statusText}`;
741
+
742
+ setTempAnimText(_errInfo);
743
+
744
+ // hide loader
745
+ setLoaderDisplay(false);
746
+
747
+
748
+ return {
749
+ reply: _errInfo
750
+ };
751
+ }
752
+
753
+ // Start streaming
754
+ await streamController.start(response);
755
+
756
+ return {
757
+ reply: tempAnimText // The final content will be in tempAnimText
758
+ };
759
+
760
+
761
+ } else {
762
+ {/* ======================================================== */}
763
+ {/* ======================== NORMAL ====================== */}
764
+ {/* ======================================================== */}
765
+
766
+ // Extract response using the path
767
+ const extractPath = args().responseExtractPath?.slice(1);
768
+
769
+ const response = await fetch((args().requestApiUrl || ''), {
770
+ method: "POST",
771
+ headers: args().headerConfigRes,
772
+ body: JSON.stringify(requestBodyRes),
773
+ signal: abortController.current.signal
774
+ });
775
+
776
+ if (!response.ok) {
777
+ const _errInfo = `[ERROR] HTTP Error ${response.status}: ${response.statusText}`;
778
+
779
+ // hide loader
780
+ setLoaderDisplay(false);
781
+
782
+ return {
783
+ reply: _errInfo
784
+ };
785
+ }
786
+
787
+ const jsonResponse = await response.json();
788
+
789
+
790
+ // hide loader
791
+ setLoaderDisplay(false);
792
+
793
+ let result: any = jsonResponse;
794
+ if (extractPath) {
795
+ for (const path of extractPath) {
796
+ result = result[path];
797
+ }
798
+ }
799
+
800
+ let content = result;
801
+
802
+ // Replace with a valid label
803
+ content = fixHtmlTags(content, args().withReasoning, args().reasoningSwitchLabel);
804
+
805
+ return {
806
+ reply: formatLatestDisplayContent(content)
807
+ };
808
+
809
+ }
810
+
811
+
812
+
813
+
814
+
815
+
816
+ } catch (error) {
817
+ const _err = `--> Error in mainRequest: ${error}`;
818
+ console.error(_err);
819
+
820
+ //reset SSE
821
+ closeSSE();
822
+
823
+ return {
824
+ reply: _err
825
+ };
826
+ }
827
+
828
+ };
829
+
830
+
831
+ // exposes the following methods
832
+ useImperativeHandle(
833
+ propsRef.current.contentRef,
834
+ () => exposedMethods(),
835
+ [propsRef.current.contentRef, inputContentRef, msInput],
836
+ );
837
+
838
+
839
+
840
+ // Update ref when props change
841
+ useEffect(() => {
842
+ propsRef.current = props;
843
+ }, [props]);
844
+
845
+ useEffect(() => {
846
+ if (props.requestConfig) {
847
+ configRef.current = props.requestConfig;
848
+ }
849
+ }, [props.requestConfig]);
850
+
851
+ useEffect(() => {
852
+ contextDataRef.current = props.contextData;
853
+ }, [props.contextData]);
854
+
855
+ useEffect(() => {
856
+ if (Array.isArray(props.defaultMessages) && props.defaultMessages.length > 0) {
857
+ // Update the default messages
858
+ setMsgList(props.defaultMessages);
859
+ }
860
+ }, [props.defaultMessages]);
861
+
862
+
863
+
864
+ return (
865
+ <>
866
+
867
+ <RootPortal show={true} containerClassName="Chatbox">
868
+
869
+ {/**------------- BUBBLE -------------*/}
870
+ {args().bubble ? <>
871
+ <div className={`${args().prefix || 'custom-'}chatbox-circle`} onClick={(e: React.MouseEvent) => {
872
+ e.preventDefault();
873
+ e.stopPropagation();
874
+ setShow(true);
875
+ }}
876
+ >
877
+ <span dangerouslySetInnerHTML={{ __html: `${args().bubbleLabel}` }}></span>
878
+ </div>
879
+ </> : null}
880
+ {/**------------- BUBBLE -------------*/}
881
+
882
+ {/**------------- CLOSE BUTTON -------------*/}
883
+ <button style={{ display: show ? 'block' : 'none' }} className={`${args().prefix || 'custom-'}chatbox-close`} tabIndex={-1} onClick={handleClose}>
884
+ <svg width="30px" height="30px" viewBox="0 0 1024 1024" fill="#000000"><path d="M707.872 329.392L348.096 689.16l-31.68-31.68 359.776-359.768z" fill="#000" /><path d="M328 340.8l32-31.2 348 348-32 32z" fill="#000" /></svg>
885
+
886
+ </button>
887
+ {/**------------- CLOSE BUTTON------------- */}
888
+
889
+
890
+ <div style={{ display: show ? 'block' : 'none' }} className={`${args().prefix || 'custom-'}chatbox-container`} ref={rootRef}>
891
+
892
+ {/**------------- NO DATA -------------*/}
893
+ {msgList.length === 0 ? <>
894
+
895
+ <div className="d-flex flex-column align-items-center justify-content-center h-50">
896
+ <p>
897
+ <svg width="70px" height="70px" viewBox="0 0 24 24" fill="none">
898
+ <path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 13.5997 2.37562 15.1116 3.04346 16.4525C3.22094 16.8088 3.28001 17.2161 3.17712 17.6006L2.58151 19.8267C2.32295 20.793 3.20701 21.677 4.17335 21.4185L6.39939 20.8229C6.78393 20.72 7.19121 20.7791 7.54753 20.9565C8.88837 21.6244 10.4003 22 12 22Z" stroke="#858297" strokeWidth="1.5" />
899
+ <path opacity="0.5" d="M8 10.5H16" stroke="#333" strokeWidth="1.5" strokeLinecap="round" />
900
+ <path opacity="0.5" d="M8 14H13.5" stroke="#333" strokeWidth="1.5" strokeLinecap="round" />
901
+ </svg>
902
+
903
+ </p>
904
+ <p className="text-primary" dangerouslySetInnerHTML={{ __html: `${args().noDataPlaceholder}` }}></p>
905
+ </div>
906
+ </> : null}
907
+ {/**------------- /NO DATA -------------*/}
908
+
909
+
910
+
911
+ {/**------------- MESSAGES LIST -------------*/}
912
+ <div className="messages" ref={msgContainerRef}>
913
+
914
+ {msgList.map((msg, index) => {
915
+
916
+ const isAnimProgress = tempAnimText !== '' && msg.sender !== args().questionNameRes && index === msgList.length - 1 && loading;
917
+
918
+
919
+ return <div key={index} className={msg.tag?.indexOf('[reply]') < 0 ? 'request' : 'reply'} style={{ display: isAnimProgress ? 'none' : '' }}>
920
+ <div className="qa-name" dangerouslySetInnerHTML={{ __html: `${msg.sender}` }}></div>
921
+
922
+ {msg.sender === args().questionNameRes ? <>
923
+ <div className="qa-content" dangerouslySetInnerHTML={{ __html: `${msg.content} <span class="qa-timestamp">${msg.timestamp}</span>` }}></div>
924
+ </> : <>
925
+
926
+ {args().isStream ? <>
927
+ <div className="qa-content" dangerouslySetInnerHTML={{ __html: `${msg.content} <span class="qa-timestamp">${msg.timestamp}</span>` }}></div>
928
+ </> : <>
929
+ <div className="qa-content">
930
+ <TypingEffect
931
+ messagesDiv={msgContainerRef.current}
932
+ content={`${msg.content} <span class="qa-timestamp">${msg.timestamp}</span>`}
933
+ speed={10}
934
+ />
935
+ </div>
936
+ </>}
937
+ </>}
938
+
939
+ </div>
940
+ }
941
+ )}
942
+
943
+
944
+
945
+ {/* ======================================================== */}
946
+ {/* ====================== STREAM begin ==================== */}
947
+ {/* ======================================================== */}
948
+ {args().isStream ? <>
949
+ {args().verbose ? <>
950
+ {/* +++++++++++++++ With reasoning ++++++++++++++++++++ */}
951
+
952
+ {/** ANIM TEXT (has thinking) */}
953
+ {tempAnimText !== '' && loading ? <>
954
+ <div className="reply reply-waiting">
955
+ <div className="qa-name">
956
+ <span dangerouslySetInnerHTML={{ __html: `${args().answerNameRes}` }} />
957
+ {loaderDisplay ? <>
958
+ <div className="msg-dotted-loader-container">
959
+ <span className="msg-dotted-loader"></span>
960
+ <span className="msg-dotted-loader-text">{args().sendLoadingLabel} ({elapsedTime}s)</span>
961
+ </div>
962
+ </> : null}
963
+
964
+ </div>
965
+
966
+ <div className="qa-content">
967
+ <div className="qa-content" dangerouslySetInnerHTML={{ __html: `${tempAnimText}` }}></div>
968
+ </div>
969
+ </div>
970
+ </> : null}
971
+ {/** /ANIM TEXT (has thinking) */}
972
+
973
+
974
+ </> : <>
975
+ {/* +++++++++++++++ Without reasoning ++++++++++++++++++++ */}
976
+ {/** ANIM TEXT (has loading) */}
977
+ {loading ? <>
978
+ <div className="reply reply-waiting">
979
+ <div className="qa-name">
980
+ <span dangerouslySetInnerHTML={{ __html: `${args().answerNameRes}` }} />
981
+ {thinking ? <>
982
+ <div className="msg-dotted-loader-container">
983
+ <span className="msg-dotted-loader"></span>
984
+ <span className="msg-dotted-loader-text">{args().sendLoadingLabel} ({elapsedTime}s)</span>
985
+ </div>
986
+ </> : null}
987
+
988
+ </div>
989
+
990
+ {tempAnimText !== '' ? <>
991
+ <div className="qa-content">
992
+ <div className="qa-content" dangerouslySetInnerHTML={{ __html: `${tempAnimText}` }}></div>
993
+ </div>
994
+ </> : null}
995
+
996
+ </div>
997
+ </> : null}
998
+ {/** /ANIM TEXT (has loading) */}
999
+
1000
+ </>}
1001
+
1002
+ </> : null}
1003
+ {/* ======================================================== */}
1004
+ {/* ====================== STREAM end ===================== */}
1005
+ {/* ======================================================== */}
1006
+
1007
+
1008
+
1009
+
1010
+ {/* ======================================================== */}
1011
+ {/* ====================== NORMAL begin ==================== */}
1012
+ {/* ======================================================== */}
1013
+ {!args().isStream ? <>
1014
+ {/** ANIM TEXT (has loading) */}
1015
+ {loading ? <>
1016
+ <div className="reply reply-waiting">
1017
+ <div className="qa-name">
1018
+ <span dangerouslySetInnerHTML={{ __html: `${args().answerNameRes}` }} />
1019
+ <div className="msg-dotted-loader-container">
1020
+ <span className="msg-dotted-loader"></span>
1021
+ <span className="msg-dotted-loader-text">{args().sendLoadingLabel} ({elapsedTime}s)</span>
1022
+ </div>
1023
+
1024
+ </div>
1025
+
1026
+ {tempAnimText !== '' ? <>
1027
+ <div className="qa-content">
1028
+ <div className="qa-content" dangerouslySetInnerHTML={{ __html: `${tempAnimText}` }}></div>
1029
+ </div>
1030
+ </> : null}
1031
+
1032
+ </div>
1033
+ </> : null}
1034
+ {/** /ANIM TEXT (has loading) */}
1035
+ </> : null}
1036
+ {/* ======================================================== */}
1037
+ {/* ====================== NORMAL end ===================== */}
1038
+ {/* ======================================================== */}
1039
+
1040
+
1041
+ {/**------------- NEW CHAT BUTTON -------------*/}
1042
+ {args().newChatButton && msgList.length > 0 && (
1043
+ <div className="newchat-btn">
1044
+ <button
1045
+ onClick={(e: React.MouseEvent<HTMLButtonElement>) => executeButtonAction(args().newChatButton.onClick, `${args().prefix || 'custom-'}chatbox-btn-new-${chatId}`, e.currentTarget)}
1046
+ >
1047
+ <span dangerouslySetInnerHTML={{ __html: args().newChatButton?.label || '' }}></span>
1048
+ </button>
1049
+ </div>
1050
+ )}
1051
+ {/**------------- /NEW CHAT BUTTON -------------*/}
1052
+
1053
+
1054
+
1055
+ </div>
1056
+ {/**------------- /MESSAGES LIST -------------*/}
1057
+
1058
+
1059
+
1060
+
1061
+ {/**------------- CONTROL AREA -------------*/}
1062
+ <div className="msgcontrol">
1063
+
1064
+
1065
+ <Textarea
1066
+ ref={msInput}
1067
+ contentRef={inputContentRef}
1068
+ controlClassName="messageInput-control"
1069
+ wrapperClassName="messageInput"
1070
+ placeholder={args().placeholder}
1071
+ disabled={loading ? true : false}
1072
+ onKeyDown={(event: React.KeyboardEvent) => {
1073
+ if (event.key === 'Enter') {
1074
+ event.preventDefault();
1075
+ handleClickSafe();
1076
+ }
1077
+ }}
1078
+ onChange={(e) => {
1079
+ args().onInputChange?.(inputContentRef.current, e.target.value);
1080
+ }}
1081
+ rows={3}
1082
+ autoSize
1083
+ autoSizeMaxHeight={200}
1084
+ />
1085
+
1086
+
1087
+ {loading ? <>
1088
+ <button
1089
+ onClick={(e: React.MouseEvent) => {
1090
+ e.preventDefault();
1091
+ e.stopPropagation();
1092
+
1093
+ if (!args().isStream) {
1094
+ // normal request
1095
+ abortNormalRequest();
1096
+ } else {
1097
+ // stop stream
1098
+ abortStream();
1099
+ }
1100
+
1101
+ //reset SSE
1102
+ closeSSE();
1103
+ }}
1104
+ className="is-suspended"
1105
+ dangerouslySetInnerHTML={{ __html: `${args().stopLabel || '<svg width="15px" height="15px" viewBox="0 0 24 24" fill="none"><path d="M2 12C2 7.28595 2 4.92893 3.46447 3.46447C4.92893 2 7.28595 2 12 2C16.714 2 19.0711 2 20.5355 3.46447C22 4.92893 22 7.28595 22 12C22 16.714 22 19.0711 20.5355 20.5355C19.0711 22 16.714 22 12 22C7.28595 22 4.92893 22 3.46447 20.5355C2 19.0711 2 16.714 2 12Z" fill="#1C274C"/></svg>'}` }}
1106
+ ></button>
1107
+ </> : <>
1108
+ <button
1109
+ onClick={(e: React.MouseEvent) => {
1110
+ e.preventDefault();
1111
+ e.stopPropagation();
1112
+
1113
+ // normal request
1114
+ if (!args().isStream) {
1115
+ if (abortController.current.signal.aborted) {
1116
+ reconnectNormalRequest();
1117
+ }
1118
+ }
1119
+
1120
+ handleClickSafe();
1121
+ }}
1122
+ dangerouslySetInnerHTML={{ __html: `${args().sendLabel}` }}
1123
+ ></button>
1124
+ </>}
1125
+
1126
+
1127
+ </div>
1128
+ {/**------------- /CONTROL AREA -------------*/}
1129
+
1130
+
1131
+
1132
+ {/**------------- SEND LOADING -------------*/}
1133
+ {args().sendLoading ? <div className="loading"><div style={{ display: loading ? 'block' : 'none' }}><PureLoader customClassName="w-100" txt="" /></div></div> : null}
1134
+ {/**------------- /SEND LOADING -------------*/}
1135
+
1136
+
1137
+ {/**------------- TOOLKIT BUTTONS -------------*/}
1138
+ {args().toolkitButtons && args().toolkitButtons.length > 0 && (
1139
+ <div className="toolkit-btns">
1140
+ {args().toolkitButtons.map((btn: FloatingButton, index: number) => {
1141
+ const _id = `${args().prefix || 'custom-'}chatbox-btn-tools-${chatId}${index}`;
1142
+ const isActive = activeButtons[_id];
1143
+ return <button
1144
+ key={index}
1145
+ className={`${btn.value || ''} ${isActive ? 'active' : ''}`}
1146
+ onClick={(e: React.MouseEvent<HTMLButtonElement>) => executeButtonAction(btn.onClick, _id, e.currentTarget)}
1147
+ >
1148
+ <span dangerouslySetInnerHTML={{ __html: btn.label }}></span>
1149
+ </button>
1150
+ })}
1151
+ </div>
1152
+ )}
1153
+ {/**------------- /TOOLKIT BUTTONS -------------*/}
1154
+
1155
+
1156
+
1157
+ </div>
1158
+
1159
+ </RootPortal>
1160
+
1161
+ </>
1162
+ );
1163
+
1164
+
1165
+ }
1166
+
1167
+
1168
+
1169
+ export default Chatbox;
1170
+
1171
+