@stack-spot/ai-chat-widget 0.11.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (347) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/StackspotAIWidget.d.ts +20 -0
  3. package/dist/StackspotAIWidget.d.ts.map +1 -1
  4. package/dist/StackspotAIWidget.js +7 -3
  5. package/dist/StackspotAIWidget.js.map +1 -1
  6. package/dist/chat-interceptors/CustomInputs.d.ts +4 -1
  7. package/dist/chat-interceptors/CustomInputs.d.ts.map +1 -1
  8. package/dist/chat-interceptors/CustomInputs.js +10 -1
  9. package/dist/chat-interceptors/CustomInputs.js.map +1 -1
  10. package/dist/chat-interceptors/quick-command-questions.d.ts +10 -0
  11. package/dist/chat-interceptors/quick-command-questions.d.ts.map +1 -1
  12. package/dist/chat-interceptors/quick-command-questions.js +12 -2
  13. package/dist/chat-interceptors/quick-command-questions.js.map +1 -1
  14. package/dist/chat-interceptors/quick-commands.d.ts +11 -0
  15. package/dist/chat-interceptors/quick-commands.d.ts.map +1 -1
  16. package/dist/chat-interceptors/quick-commands.js +65 -25
  17. package/dist/chat-interceptors/quick-commands.js.map +1 -1
  18. package/dist/chat-interceptors/send-message.d.ts +10 -0
  19. package/dist/chat-interceptors/send-message.d.ts.map +1 -1
  20. package/dist/chat-interceptors/send-message.js +32 -10
  21. package/dist/chat-interceptors/send-message.js.map +1 -1
  22. package/dist/components/Accordion.d.ts +10 -0
  23. package/dist/components/Accordion.d.ts.map +1 -1
  24. package/dist/components/Accordion.js +3 -0
  25. package/dist/components/Accordion.js.map +1 -1
  26. package/dist/components/AdaptiveTextArea.d.ts +13 -1
  27. package/dist/components/AdaptiveTextArea.d.ts.map +1 -1
  28. package/dist/components/AdaptiveTextArea.js +9 -4
  29. package/dist/components/AdaptiveTextArea.js.map +1 -1
  30. package/dist/components/AutoFocus.d.ts +23 -0
  31. package/dist/components/AutoFocus.d.ts.map +1 -0
  32. package/dist/components/AutoFocus.js +16 -0
  33. package/dist/components/AutoFocus.js.map +1 -0
  34. package/dist/components/Fading.d.ts +32 -0
  35. package/dist/components/Fading.d.ts.map +1 -0
  36. package/dist/components/Fading.js +33 -0
  37. package/dist/components/Fading.js.map +1 -0
  38. package/dist/components/FadingOverflow.d.ts +25 -0
  39. package/dist/components/FadingOverflow.d.ts.map +1 -1
  40. package/dist/components/FadingOverflow.js +11 -2
  41. package/dist/components/FadingOverflow.js.map +1 -1
  42. package/dist/components/FallbackBoundary/ErrorBoundary.d.ts +3 -0
  43. package/dist/components/FallbackBoundary/ErrorBoundary.d.ts.map +1 -1
  44. package/dist/components/FallbackBoundary/ErrorBoundary.js +18 -4
  45. package/dist/components/FallbackBoundary/ErrorBoundary.js.map +1 -1
  46. package/dist/components/FallbackBoundary/Loading.js +1 -1
  47. package/dist/components/FallbackBoundary/Loading.js.map +1 -1
  48. package/dist/components/FallbackBoundary/index.d.ts +12 -1
  49. package/dist/components/FallbackBoundary/index.d.ts.map +1 -1
  50. package/dist/components/FallbackBoundary/index.js +1 -1
  51. package/dist/components/FallbackBoundary/index.js.map +1 -1
  52. package/dist/components/HistoryList.d.ts +15 -0
  53. package/dist/components/HistoryList.d.ts.map +1 -1
  54. package/dist/components/HistoryList.js +3 -1
  55. package/dist/components/HistoryList.js.map +1 -1
  56. package/dist/components/IconInput.d.ts +3 -0
  57. package/dist/components/IconInput.d.ts.map +1 -1
  58. package/dist/components/IconInput.js +3 -0
  59. package/dist/components/IconInput.js.map +1 -1
  60. package/dist/components/OverlayMenu.d.ts +12 -1
  61. package/dist/components/OverlayMenu.d.ts.map +1 -1
  62. package/dist/components/OverlayMenu.js +31 -10
  63. package/dist/components/OverlayMenu.js.map +1 -1
  64. package/dist/components/ProgressBar.d.ts +22 -0
  65. package/dist/components/ProgressBar.d.ts.map +1 -1
  66. package/dist/components/ProgressBar.js +5 -0
  67. package/dist/components/ProgressBar.js.map +1 -1
  68. package/dist/components/QuickStartButton.d.ts.map +1 -1
  69. package/dist/components/QuickStartButton.js +3 -0
  70. package/dist/components/QuickStartButton.js.map +1 -1
  71. package/dist/components/RightPanelForm.d.ts +3 -0
  72. package/dist/components/RightPanelForm.d.ts.map +1 -1
  73. package/dist/components/RightPanelForm.js +8 -4
  74. package/dist/components/RightPanelForm.js.map +1 -1
  75. package/dist/components/RightPanelTabs.d.ts +3 -0
  76. package/dist/components/RightPanelTabs.d.ts.map +1 -1
  77. package/dist/components/RightPanelTabs.js +3 -0
  78. package/dist/components/RightPanelTabs.js.map +1 -1
  79. package/dist/components/TabManager.d.ts +6 -0
  80. package/dist/components/TabManager.d.ts.map +1 -1
  81. package/dist/components/TabManager.js +8 -0
  82. package/dist/components/TabManager.js.map +1 -1
  83. package/dist/components/Tooltip/Tooltip.d.ts +26 -1
  84. package/dist/components/Tooltip/Tooltip.d.ts.map +1 -1
  85. package/dist/components/Tooltip/Tooltip.js +18 -5
  86. package/dist/components/Tooltip/Tooltip.js.map +1 -1
  87. package/dist/components/Tooltip/TooltipAPI.d.ts +18 -2
  88. package/dist/components/Tooltip/TooltipAPI.d.ts.map +1 -1
  89. package/dist/components/Tooltip/TooltipAPI.js +68 -51
  90. package/dist/components/Tooltip/TooltipAPI.js.map +1 -1
  91. package/dist/components/Tooltip/types.d.ts +13 -0
  92. package/dist/components/Tooltip/types.d.ts.map +1 -1
  93. package/dist/components/form/DescribedCheckboxGroup.d.ts +4 -0
  94. package/dist/components/form/DescribedCheckboxGroup.d.ts.map +1 -1
  95. package/dist/components/form/DescribedCheckboxGroup.js +4 -0
  96. package/dist/components/form/DescribedCheckboxGroup.js.map +1 -1
  97. package/dist/components/form/DescribedRadioGroup.d.ts +4 -0
  98. package/dist/components/form/DescribedRadioGroup.d.ts.map +1 -1
  99. package/dist/components/form/DescribedRadioGroup.js +4 -0
  100. package/dist/components/form/DescribedRadioGroup.js.map +1 -1
  101. package/dist/components/form/types.d.ts +34 -0
  102. package/dist/components/form/types.d.ts.map +1 -1
  103. package/dist/context/AIWidgetProvider.d.ts +19 -0
  104. package/dist/context/AIWidgetProvider.d.ts.map +1 -1
  105. package/dist/context/AIWidgetProvider.js +19 -0
  106. package/dist/context/AIWidgetProvider.js.map +1 -1
  107. package/dist/context/hooks.d.ts +56 -0
  108. package/dist/context/hooks.d.ts.map +1 -1
  109. package/dist/context/hooks.js +56 -1
  110. package/dist/context/hooks.js.map +1 -1
  111. package/dist/features.d.ts +28 -0
  112. package/dist/features.d.ts.map +1 -1
  113. package/dist/features.js +1 -0
  114. package/dist/features.js.map +1 -1
  115. package/dist/layout.css +5 -0
  116. package/dist/regex.d.ts +2 -0
  117. package/dist/regex.d.ts.map +1 -0
  118. package/dist/regex.js +2 -0
  119. package/dist/regex.js.map +1 -0
  120. package/dist/right-panel/DefaultPanel.d.ts +3 -0
  121. package/dist/right-panel/DefaultPanel.d.ts.map +1 -1
  122. package/dist/right-panel/DefaultPanel.js +3 -0
  123. package/dist/right-panel/DefaultPanel.js.map +1 -1
  124. package/dist/right-panel/RightPanel.d.ts +3 -0
  125. package/dist/right-panel/RightPanel.d.ts.map +1 -1
  126. package/dist/right-panel/RightPanel.js +3 -0
  127. package/dist/right-panel/RightPanel.js.map +1 -1
  128. package/dist/right-panel/RightPanelProvider.d.ts +15 -0
  129. package/dist/right-panel/RightPanelProvider.d.ts.map +1 -1
  130. package/dist/right-panel/RightPanelProvider.js.map +1 -1
  131. package/dist/right-panel/constants.d.ts +2 -0
  132. package/dist/right-panel/constants.d.ts.map +1 -0
  133. package/dist/right-panel/constants.js +2 -0
  134. package/dist/right-panel/constants.js.map +1 -0
  135. package/dist/right-panel/hooks.d.ts +6 -0
  136. package/dist/right-panel/hooks.d.ts.map +1 -1
  137. package/dist/right-panel/hooks.js +8 -1
  138. package/dist/right-panel/hooks.js.map +1 -1
  139. package/dist/state/ChatEntry.d.ts +58 -2
  140. package/dist/state/ChatEntry.d.ts.map +1 -1
  141. package/dist/state/ChatEntry.js +20 -1
  142. package/dist/state/ChatEntry.js.map +1 -1
  143. package/dist/state/ChatState.d.ts +73 -8
  144. package/dist/state/ChatState.d.ts.map +1 -1
  145. package/dist/state/ChatState.js +24 -7
  146. package/dist/state/ChatState.js.map +1 -1
  147. package/dist/state/ChatTabsController.d.ts +31 -0
  148. package/dist/state/ChatTabsController.d.ts.map +1 -1
  149. package/dist/state/ChatTabsController.js +31 -0
  150. package/dist/state/ChatTabsController.js.map +1 -1
  151. package/dist/state/ObservableState.d.ts +14 -0
  152. package/dist/state/ObservableState.d.ts.map +1 -1
  153. package/dist/state/ObservableState.js +14 -0
  154. package/dist/state/ObservableState.js.map +1 -1
  155. package/dist/state/WidgetState.d.ts +5 -0
  156. package/dist/state/WidgetState.d.ts.map +1 -1
  157. package/dist/state/WidgetState.js +5 -0
  158. package/dist/state/WidgetState.js.map +1 -1
  159. package/dist/types.d.ts +10 -0
  160. package/dist/types.d.ts.map +1 -1
  161. package/dist/utils/chat.d.ts +13 -0
  162. package/dist/utils/chat.d.ts.map +1 -1
  163. package/dist/utils/chat.js +15 -1
  164. package/dist/utils/chat.js.map +1 -1
  165. package/dist/utils/date.d.ts +25 -0
  166. package/dist/utils/date.d.ts.map +1 -1
  167. package/dist/utils/date.js +25 -0
  168. package/dist/utils/date.js.map +1 -1
  169. package/dist/utils/download.d.ts +5 -0
  170. package/dist/utils/download.d.ts.map +1 -1
  171. package/dist/utils/download.js +5 -0
  172. package/dist/utils/download.js.map +1 -1
  173. package/dist/utils/knowledge-source.d.ts +10 -0
  174. package/dist/utils/knowledge-source.d.ts.map +1 -1
  175. package/dist/utils/knowledge-source.js +16 -0
  176. package/dist/utils/knowledge-source.js.map +1 -1
  177. package/dist/utils/string.d.ts +5 -0
  178. package/dist/utils/string.d.ts.map +1 -1
  179. package/dist/utils/string.js +5 -1
  180. package/dist/utils/string.js.map +1 -1
  181. package/dist/utils/url.d.ts +2 -0
  182. package/dist/utils/url.d.ts.map +1 -0
  183. package/dist/utils/url.js +8 -0
  184. package/dist/utils/url.js.map +1 -0
  185. package/dist/views/Agents.js +3 -0
  186. package/dist/views/Agents.js.map +1 -1
  187. package/dist/views/Chat/AgentInfo.d.ts +3 -0
  188. package/dist/views/Chat/AgentInfo.d.ts.map +1 -1
  189. package/dist/views/Chat/AgentInfo.js +3 -0
  190. package/dist/views/Chat/AgentInfo.js.map +1 -1
  191. package/dist/views/Chat/ChatMessage.d.ts +17 -2
  192. package/dist/views/Chat/ChatMessage.d.ts.map +1 -1
  193. package/dist/views/Chat/ChatMessage.js +9 -13
  194. package/dist/views/Chat/ChatMessage.js.map +1 -1
  195. package/dist/views/Chat/ChatMessages.d.ts +3 -0
  196. package/dist/views/Chat/ChatMessages.d.ts.map +1 -1
  197. package/dist/views/Chat/ChatMessages.js +3 -0
  198. package/dist/views/Chat/ChatMessages.js.map +1 -1
  199. package/dist/views/Chat/chat-scroll.d.ts +1 -1
  200. package/dist/views/Chat/chat-scroll.js +1 -1
  201. package/dist/views/Chat/events.d.ts +22 -0
  202. package/dist/views/Chat/events.d.ts.map +1 -0
  203. package/dist/views/Chat/events.js +66 -0
  204. package/dist/views/Chat/events.js.map +1 -0
  205. package/dist/views/Chat/index.d.ts +6 -0
  206. package/dist/views/Chat/index.d.ts.map +1 -1
  207. package/dist/views/Chat/index.js +3 -0
  208. package/dist/views/Chat/index.js.map +1 -1
  209. package/dist/views/ChatHistory/ChatHistoryPanel.d.ts +3 -0
  210. package/dist/views/ChatHistory/ChatHistoryPanel.d.ts.map +1 -1
  211. package/dist/views/ChatHistory/ChatHistoryPanel.js +5 -1
  212. package/dist/views/ChatHistory/ChatHistoryPanel.js.map +1 -1
  213. package/dist/views/ChatHistory/HistoryItem.d.ts +3 -0
  214. package/dist/views/ChatHistory/HistoryItem.d.ts.map +1 -1
  215. package/dist/views/ChatHistory/HistoryItem.js +13 -1
  216. package/dist/views/ChatHistory/HistoryItem.js.map +1 -1
  217. package/dist/views/ChatHistory/index.d.ts +10 -2
  218. package/dist/views/ChatHistory/index.d.ts.map +1 -1
  219. package/dist/views/ChatHistory/index.js +3 -0
  220. package/dist/views/ChatHistory/index.js.map +1 -1
  221. package/dist/views/ChatHistory/utils.d.ts +14 -0
  222. package/dist/views/ChatHistory/utils.d.ts.map +1 -1
  223. package/dist/views/ChatHistory/utils.js +14 -0
  224. package/dist/views/ChatHistory/utils.js.map +1 -1
  225. package/dist/views/ChatTabSelection.d.ts +3 -0
  226. package/dist/views/ChatTabSelection.d.ts.map +1 -1
  227. package/dist/views/ChatTabSelection.js +3 -0
  228. package/dist/views/ChatTabSelection.js.map +1 -1
  229. package/dist/views/Editor.d.ts +3 -0
  230. package/dist/views/Editor.d.ts.map +1 -1
  231. package/dist/views/Editor.js +4 -0
  232. package/dist/views/Editor.js.map +1 -1
  233. package/dist/views/Home.d.ts +8 -0
  234. package/dist/views/Home.d.ts.map +1 -1
  235. package/dist/views/Home.js +5 -0
  236. package/dist/views/Home.js.map +1 -1
  237. package/dist/views/KSDocument.d.ts +3 -0
  238. package/dist/views/KSDocument.d.ts.map +1 -1
  239. package/dist/views/KSDocument.js +3 -0
  240. package/dist/views/KSDocument.js.map +1 -1
  241. package/dist/views/KnowledgeSources.js +3 -0
  242. package/dist/views/KnowledgeSources.js.map +1 -1
  243. package/dist/views/MessageInput/ButtonGroup.d.ts +22 -0
  244. package/dist/views/MessageInput/ButtonGroup.d.ts.map +1 -1
  245. package/dist/views/MessageInput/ButtonGroup.js +4 -0
  246. package/dist/views/MessageInput/ButtonGroup.js.map +1 -1
  247. package/dist/views/MessageInput/InfoBar.d.ts +7 -0
  248. package/dist/views/MessageInput/InfoBar.d.ts.map +1 -1
  249. package/dist/views/MessageInput/InfoBar.js +7 -0
  250. package/dist/views/MessageInput/InfoBar.js.map +1 -1
  251. package/dist/views/MessageInput/QuickCommandSelector.d.ts +13 -0
  252. package/dist/views/MessageInput/QuickCommandSelector.d.ts.map +1 -0
  253. package/dist/views/MessageInput/QuickCommandSelector.js +141 -0
  254. package/dist/views/MessageInput/QuickCommandSelector.js.map +1 -0
  255. package/dist/views/MessageInput/index.d.ts +8 -0
  256. package/dist/views/MessageInput/index.d.ts.map +1 -1
  257. package/dist/views/MessageInput/index.js +11 -4
  258. package/dist/views/MessageInput/index.js.map +1 -1
  259. package/dist/views/MessageInput/styled.d.ts.map +1 -1
  260. package/dist/views/MessageInput/styled.js +137 -0
  261. package/dist/views/MessageInput/styled.js.map +1 -1
  262. package/dist/views/MinimizedHeader.d.ts +4 -0
  263. package/dist/views/MinimizedHeader.d.ts.map +1 -1
  264. package/dist/views/MinimizedHeader.js +4 -0
  265. package/dist/views/MinimizedHeader.js.map +1 -1
  266. package/dist/views/Stacks.d.ts +3 -0
  267. package/dist/views/Stacks.d.ts.map +1 -1
  268. package/dist/views/Stacks.js +3 -0
  269. package/dist/views/Stacks.js.map +1 -1
  270. package/dist/views/Workspaces.d.ts +3 -0
  271. package/dist/views/Workspaces.d.ts.map +1 -1
  272. package/dist/views/Workspaces.js +3 -0
  273. package/dist/views/Workspaces.js.map +1 -1
  274. package/package.json +6 -6
  275. package/src/StackspotAIWidget.tsx +23 -2
  276. package/src/chat-interceptors/CustomInputs.ts +14 -1
  277. package/src/chat-interceptors/quick-command-questions.ts +12 -2
  278. package/src/chat-interceptors/quick-commands.ts +66 -26
  279. package/src/chat-interceptors/send-message.ts +41 -11
  280. package/src/components/Accordion.tsx +10 -0
  281. package/src/components/AdaptiveTextArea.tsx +21 -4
  282. package/src/components/AutoFocus.tsx +34 -0
  283. package/src/components/Fading.tsx +66 -0
  284. package/src/components/FadingOverflow.tsx +31 -3
  285. package/src/components/FallbackBoundary/ErrorBoundary.tsx +26 -3
  286. package/src/components/FallbackBoundary/Loading.tsx +1 -1
  287. package/src/components/FallbackBoundary/index.tsx +13 -2
  288. package/src/components/HistoryList.tsx +15 -1
  289. package/src/components/IconInput.tsx +3 -0
  290. package/src/components/OverlayMenu.tsx +76 -20
  291. package/src/components/ProgressBar.tsx +23 -0
  292. package/src/components/QuickStartButton.tsx +3 -0
  293. package/src/components/RightPanelForm.tsx +15 -9
  294. package/src/components/RightPanelTabs.tsx +3 -0
  295. package/src/components/TabManager.tsx +8 -0
  296. package/src/components/Tooltip/Tooltip.tsx +47 -5
  297. package/src/components/Tooltip/TooltipAPI.ts +59 -42
  298. package/src/components/Tooltip/types.ts +13 -0
  299. package/src/components/form/DescribedCheckboxGroup.tsx +4 -0
  300. package/src/components/form/DescribedRadioGroup.tsx +4 -0
  301. package/src/components/form/types.ts +34 -0
  302. package/src/context/AIWidgetProvider.tsx +19 -0
  303. package/src/context/hooks.ts +56 -1
  304. package/src/features.ts +29 -0
  305. package/src/layout.css +5 -0
  306. package/src/regex.ts +1 -0
  307. package/src/right-panel/DefaultPanel.tsx +4 -0
  308. package/src/right-panel/RightPanel.tsx +3 -0
  309. package/src/right-panel/RightPanelProvider.tsx +15 -0
  310. package/src/right-panel/constants.ts +1 -0
  311. package/src/right-panel/hooks.tsx +8 -1
  312. package/src/state/ChatEntry.ts +60 -2
  313. package/src/state/ChatState.ts +74 -9
  314. package/src/state/ChatTabsController.ts +31 -0
  315. package/src/state/ObservableState.ts +14 -0
  316. package/src/state/WidgetState.ts +5 -0
  317. package/src/types.ts +10 -0
  318. package/src/utils/chat.ts +15 -1
  319. package/src/utils/date.ts +25 -1
  320. package/src/utils/download.ts +5 -0
  321. package/src/utils/knowledge-source.ts +16 -0
  322. package/src/utils/string.ts +5 -1
  323. package/src/utils/url.ts +8 -0
  324. package/src/views/Agents.tsx +3 -0
  325. package/src/views/Chat/AgentInfo.tsx +3 -0
  326. package/src/views/Chat/ChatMessage.tsx +31 -18
  327. package/src/views/Chat/ChatMessages.tsx +3 -0
  328. package/src/views/Chat/chat-scroll.ts +1 -1
  329. package/src/views/Chat/events.ts +69 -0
  330. package/src/views/Chat/index.tsx +6 -0
  331. package/src/views/ChatHistory/ChatHistoryPanel.tsx +6 -2
  332. package/src/views/ChatHistory/HistoryItem.tsx +14 -2
  333. package/src/views/ChatHistory/index.tsx +11 -1
  334. package/src/views/ChatHistory/utils.ts +14 -0
  335. package/src/views/ChatTabSelection.tsx +3 -0
  336. package/src/views/Editor.tsx +4 -0
  337. package/src/views/Home.tsx +8 -0
  338. package/src/views/KSDocument.tsx +3 -0
  339. package/src/views/KnowledgeSources.tsx +3 -0
  340. package/src/views/MessageInput/ButtonGroup.tsx +22 -0
  341. package/src/views/MessageInput/InfoBar.tsx +7 -0
  342. package/src/views/MessageInput/QuickCommandSelector.tsx +217 -0
  343. package/src/views/MessageInput/index.tsx +16 -4
  344. package/src/views/MessageInput/styled.ts +137 -0
  345. package/src/views/MinimizedHeader.tsx +4 -0
  346. package/src/views/Stacks.tsx +3 -0
  347. package/src/views/Workspaces.tsx +3 -0
@@ -1,9 +1,46 @@
1
1
  import { aiClient, StackspotAPIError } from '@stack-spot/portal-network'
2
- import { ChatEntry, KnowledgeSource } from '../state/ChatEntry'
2
+ import { ChatResponse3 } from '@stack-spot/portal-network/api/ai'
3
+ import { ChatEntry, KnowledgeSource, TextChatEntry } from '../state/ChatEntry'
3
4
  import { ChatState } from '../state/ChatState'
5
+ import { LabeledWithImage } from '../state/types'
4
6
  import { buildConversationContext } from '../utils/chat'
5
7
  import { genericSourcesToKnowledgeSources } from '../utils/knowledge-source'
6
8
 
9
+ /**
10
+ * Transforms a chat response from the backend into a chat entry that can be added to the chat.
11
+ * @param response the original response.
12
+ * @param knowledgeSources the knowledge sources already in format used by the chat.
13
+ * @param agent the current chat agent.
14
+ * @param includeDate whether or not to include the date in the chat entry.
15
+ * @returns the TextChatEntry to build a ChatEntry.
16
+ */
17
+ function createEntryValueFromChatResponse(
18
+ response: Partial<ChatResponse3>,
19
+ knowledgeSources: KnowledgeSource[] | undefined,
20
+ agent: LabeledWithImage | undefined,
21
+ includeDate = false,
22
+ ): TextChatEntry {
23
+ return {
24
+ agentType: 'bot',
25
+ type: 'md',
26
+ content: response.answer ?? '',
27
+ messageId: response.message_id ?? undefined,
28
+ knowledgeSources,
29
+ agent: agent,
30
+ updated: includeDate ? new Date().toISOString() : undefined,
31
+ }
32
+ }
33
+
34
+ /**
35
+ * The chat interceptor that sends the message to the AI agent, interprets the response and adds it to the chat.
36
+ *
37
+ * The message added to the chat is streamed, i.e. it changes over time, until it's completed.
38
+ *
39
+ * @param entry the chat entry.
40
+ * @param chat the chat state.
41
+ * @param signal a signal that can be canceled by the user.
42
+ * @returns undefined
43
+ */
7
44
  export async function sendMessageInterceptor(entry: ChatEntry, chat: ChatState, signal: AbortSignal) {
8
45
  const { agentType, content } = entry.getValue()
9
46
  if (agentType !== 'user') return
@@ -20,18 +57,11 @@ export async function sendMessageInterceptor(entry: ChatEntry, chat: ChatState,
20
57
  if (value.sources?.length !== knowledgeSources?.length) {
21
58
  knowledgeSources = genericSourcesToKnowledgeSources(value.sources)
22
59
  }
23
- botEntry.setValue({
24
- agentType: 'bot',
25
- type: 'md',
26
- content: value.answer ?? '',
27
- messageId: value.message_id ?? undefined,
28
- knowledgeSources,
29
- updated: new Date().toISOString(),
30
- agent: chat.get('agent'),
31
- })
60
+ botEntry.setValue(createEntryValueFromChatResponse(value, knowledgeSources, chat.get('agent')))
32
61
  })
33
62
  try {
34
- await stream.getValue()
63
+ const finalValue = await stream.getValue()
64
+ botEntry.setValue(createEntryValueFromChatResponse(finalValue, knowledgeSources, chat.get('agent'), true))
35
65
  aiClient.chat.invalidate({ conversationId: chat.id })
36
66
  if (isFirstMessage) aiClient.chats.invalidate()
37
67
  } catch (error: any) {
@@ -9,7 +9,14 @@ import { styled } from 'styled-components'
9
9
  import { WithChildren } from '../types'
10
10
 
11
11
  interface Props extends WithStyle, Required<WithChildren> {
12
+ /**
13
+ * The header of the accordion (always rendered). The body (hidden part) must be passed as the children.
14
+ */
12
15
  header: React.ReactNode,
16
+ /**
17
+ * Whether or not to start expanded.
18
+ * @default false
19
+ */
13
20
  startExpanded?: boolean,
14
21
  }
15
22
 
@@ -48,6 +55,9 @@ const StyledAccordion = styled.div`
48
55
  }
49
56
  `
50
57
 
58
+ /**
59
+ * A component that can have it's content shown or hidden (animated).
60
+ */
51
61
  export const Accordion = ({ children, header, className, startExpanded, style }: Props) => {
52
62
  const [expanded, setExpanded] = useState(startExpanded)
53
63
  return (
@@ -1,15 +1,32 @@
1
+ /* eslint-disable react/display-name */
1
2
  import { Textarea } from '@citric/core'
2
- import { useEffect, useRef } from 'react'
3
+ import { forwardRef, useEffect, useRef } from 'react'
3
4
  import { PropsOf } from '../types'
4
5
 
5
6
  interface Props extends PropsOf<typeof Textarea> {
7
+ /**
8
+ * A function to run whenever the height of the text area increases.
9
+ */
6
10
  onIncreaseSize?: () => void,
11
+ /**
12
+ * A function to run whenever the text area value becomes empty.
13
+ */
7
14
  onResetSize?: () => void,
15
+ /**
16
+ * The maximum height this textarea can get to.
17
+ */
8
18
  maxHeight?: number,
9
19
  }
10
20
 
11
- export const AdaptiveTextArea = ({ value, onIncreaseSize, onResetSize, maxHeight, style, ...props }: Props) => {
12
- const ref = useRef<HTMLTextAreaElement>(null)
21
+ /**
22
+ * The adaptive textarea grows in height whenever needed until the maximum height is reached.
23
+ */
24
+ export const AdaptiveTextArea = forwardRef<HTMLTextAreaElement, Props>((
25
+ { value, onIncreaseSize, onResetSize, maxHeight, style, ...props },
26
+ externalRef,
27
+ ) => {
28
+ const localRef = useRef<HTMLTextAreaElement>(null)
29
+ const ref = externalRef as React.RefObject<HTMLTextAreaElement> ?? localRef
13
30
 
14
31
  useEffect(() => {
15
32
  if (!ref.current) return
@@ -31,4 +48,4 @@ export const AdaptiveTextArea = ({ value, onIncreaseSize, onResetSize, maxHeight
31
48
  }, [value, maxHeight])
32
49
 
33
50
  return <Textarea {...props} ref={ref} value={value} style={{ ...style, maxHeight }} />
34
- }
51
+ })
@@ -0,0 +1,34 @@
1
+ /* eslint-disable react/display-name */
2
+ import { focusFirstChild, TagPriorityElement } from '@stack-spot/portal-components'
3
+ import { forwardRef, RefObject, useEffect, useRef } from 'react'
4
+
5
+ interface Props extends React.HTMLAttributes<HTMLDivElement> {
6
+ /**
7
+ * A delay in ms to focus the first focusable element.
8
+ */
9
+ delay?: number,
10
+ /**
11
+ * Instead of focusing the first element overall, focus the first according to this list of priorities.
12
+ *
13
+ * 'other' means elements that are normally not focusable, but have positive tabIndex values.
14
+ */
15
+ priority?: TagPriorityElement[],
16
+ /**
17
+ * Ignores any element that matches this query selector.
18
+ */
19
+ ignore?: string,
20
+ }
21
+
22
+ /**
23
+ * Focus the first focusable child as soon as the component mounts.
24
+ */
25
+ export const AutoFocus = forwardRef<HTMLDivElement, Props>(({ children, delay = 0, priority, ignore, ...props }, externalRef) => {
26
+ const localRef = useRef<HTMLDivElement>(null)
27
+ const ref = externalRef as RefObject<HTMLDivElement> ?? localRef
28
+
29
+ useEffect(() => {
30
+ setTimeout(() => focusFirstChild(ref.current, { priority, ignore }), delay)
31
+ }, [])
32
+
33
+ return <div ref={ref} {...props}>{children}</div>
34
+ })
@@ -0,0 +1,66 @@
1
+ /* eslint-disable react/display-name */
2
+ import { WithStyle } from '@stack-spot/portal-theme'
3
+ import { forwardRef, useEffect, useRef, useState } from 'react'
4
+ import { WithChildren } from '../types'
5
+
6
+ interface Props extends WithChildren, WithStyle {
7
+ /**
8
+ * Whether or not the content is visible.
9
+ */
10
+ visible: boolean,
11
+ /**
12
+ * Duration of the animation in ms.
13
+ * @default 300
14
+ */
15
+ duration?: number,
16
+ /**
17
+ * Function to run right before animation to show the content starts.
18
+ */
19
+ beforeFadeIn?: () => void,
20
+ /**
21
+ * Function to run right before animation to hide the content starts.
22
+ */
23
+ beforeFadeOut?: () => void,
24
+ /**
25
+ * Function to run right after the animation to show the content ends.
26
+ */
27
+ afterFadeIn?: () => void,
28
+ /**
29
+ * Function to run right after the animation to hide the content ends.
30
+ */
31
+ afterFadeOut?: () => void,
32
+ }
33
+
34
+ export const Fading = forwardRef<HTMLDivElement, Props>((
35
+ { visible, children, duration = 300, afterFadeIn, afterFadeOut, beforeFadeIn, beforeFadeOut, className, style },
36
+ ref,
37
+ ) => {
38
+ const [isOpaque, setOpaque] = useState(visible)
39
+ const [isRendered, setRendered] = useState(visible)
40
+ const previous = useRef(visible)
41
+ const timeout = useRef<number[]>([])
42
+ const opacity: React.CSSProperties = { transition: `opacity ${duration / 1000}s`, opacity: isOpaque ? 1 : 0 }
43
+
44
+ useEffect(() => {
45
+ if (previous.current === visible) return
46
+ timeout.current.forEach(window.clearTimeout)
47
+ timeout.current = []
48
+ if (visible) {
49
+ setRendered(true)
50
+ if (afterFadeIn) timeout.current.push(window.setTimeout(afterFadeIn, duration))
51
+ beforeFadeIn?.()
52
+ timeout.current.push(window.setTimeout(() => setOpaque(true), 0))
53
+
54
+ } else {
55
+ setOpaque(false)
56
+ beforeFadeOut?.()
57
+ timeout.current.push(window.setTimeout(() => {
58
+ setRendered(false)
59
+ afterFadeOut?.()
60
+ }, duration))
61
+ }
62
+ previous.current = visible
63
+ }, [visible])
64
+
65
+ return isRendered ? <div ref={ref} className={className} style={{ ...style, ...opacity }}>{children}</div> : null
66
+ })
@@ -10,12 +10,38 @@ type Side = 'top' | 'right' | 'left' | 'bottom'
10
10
  type ScrollType = 'none' | 'wheel' | 'bar' | 'arrows'
11
11
 
12
12
  interface Props extends WithChildren, WithStyle {
13
+ /**
14
+ * How to scroll the content.
15
+ * - none: overflow is hidden. No scrolling.
16
+ * - wheel: the content is solely scrollable through the mouse wheel and keyboard arrows, no scroll bars are rendered.
17
+ * - bar: this is the normal browser scroll. The content will be scrollable through the mouse wheel, keyboard and scrollbar.
18
+ * - arrows: arrows will be placed in the far edges of the sides that must be scrolled. The content is scrolled through the mouse wheel,
19
+ * keyboard and these arrows. Hovering an arrow slowly scrolls the content, clicking the arrow fully scrolls the content in its direction.
20
+ * There are no scrollbars in this scenario.
21
+ * @default 'none'
22
+ */
13
23
  scroll?: ScrollType,
24
+ /**
25
+ * If true, a horizontal scroll can be performed by using the vertical mouse wheel.
26
+ * @default false
27
+ */
14
28
  enableHorizontalScrollWithVerticalWheel?: boolean,
29
+ /**
30
+ * Which sides to fade when the content overflows.
31
+ *
32
+ * Important: it seems the current solution doesn't support mixing vertical and horizontal scrolls. I'm not sure if this is possible, I
33
+ * believed combining linear gradients would work, but it doesn't.
34
+ */
15
35
  sides?: Side[],
16
36
  }
17
37
 
38
+ // Scrolling can be very fast, this sets a lower limit for us to run listeners without impacting performance.
18
39
  const MIN_CHECK_INTERVAL_MS = 20
40
+ // The interval which to scroll the content when a scroll arrow is hovered.
41
+ const SCROLL_INTERVAL_MS = 20
42
+ // This sets the speed of the scroll when the user hovers a scroll arrow.
43
+ const SCROLL_PX = 4
44
+ // Fade masks
19
45
  const masks = {
20
46
  right: 'linear-gradient(to left, rgb(0, 0, 0, 0) 0%, rgb(0, 0, 0) min(30%, 100px), rgba(0, 0, 0) 100%)',
21
47
  left: 'linear-gradient(to right, rgb(0, 0, 0, 0) 0%, rgb(0, 0, 0) min(30%, 100px), rgba(0, 0, 0) 100%)',
@@ -95,9 +121,11 @@ const OverflowBox = styled.div`
95
121
  }
96
122
  `
97
123
 
98
- const SCROLL_INTERVAL_MS = 20
99
- const SCROLL_PX = 4
100
-
124
+ /**
125
+ * This component applies a fading graphical effect to its content if it overflows in any of the sides specified by the props.
126
+ *
127
+ * This also controls how this overflow is scrolled, introducing a new scrolling technique, which applies arrows to the overflowing side.
128
+ */
101
129
  export const FadingOverflow = (
102
130
  { children, scroll = 'none', sides, enableHorizontalScrollWithVerticalWheel, className, ...props }: Props,
103
131
  ) => {
@@ -1,15 +1,29 @@
1
+ import { IconBox, Text } from '@citric/core'
2
+ import { TimesCircle } from '@citric/icons'
1
3
  import { ErrorDescription, ErrorFeedback } from '@stack-spot/portal-components/error'
2
4
  import { StackspotAPIError } from '@stack-spot/portal-network'
3
5
  import { Component } from 'react'
6
+ import { styled } from 'styled-components'
4
7
 
5
8
  interface State extends ErrorDescription {
6
9
  hasError: boolean,
7
10
  }
8
11
 
9
12
  interface Props {
13
+ mini?: boolean,
14
+ message?: string,
10
15
  children: React.ReactNode,
11
16
  }
12
17
 
18
+ const ErrorBox = styled.div`
19
+ width: 100%;
20
+ height: 100%;
21
+ display: flex;
22
+ flex-direction: column;
23
+ align-items: center;
24
+ justify-content: center;
25
+ `
26
+
13
27
  /**
14
28
  * An Error Boundary that renders an ErrorFeedback instead of its content if any of its children throws.
15
29
  *
@@ -40,9 +54,18 @@ export class ErrorBoundary extends Component<Props, State> {
40
54
  if (this.props.children !== prevProps.children) this.setState({ hasError: false })
41
55
  }
42
56
 
57
+ private renderError() {
58
+ return this.props.mini
59
+ ? (
60
+ <ErrorBox className="error">
61
+ <IconBox size="lg" colorIcon="danger.500"><TimesCircle /></IconBox>
62
+ <Text colorScheme="light.700">{this.props.message || this.state.message}</Text>
63
+ </ErrorBox>
64
+ )
65
+ : <ErrorFeedback className="error" code={this.state.code} message={this.props.message || this.state.message} />
66
+ }
67
+
43
68
  render() {
44
- return this.state.hasError
45
- ? <ErrorFeedback code={this.state.code} message={this.state.message} />
46
- : this.props.children
69
+ return this.state.hasError ? this.renderError() : this.props.children
47
70
  }
48
71
  }
@@ -10,5 +10,5 @@ const LoadingBox = styled.div`
10
10
  `
11
11
 
12
12
  export const Loading = () => (
13
- <LoadingBox><LoadingCircular /></LoadingBox>
13
+ <LoadingBox className="loading"><LoadingCircular /></LoadingBox>
14
14
  )
@@ -3,11 +3,22 @@ import { WithChildren } from '../../types'
3
3
  import { ErrorBoundary } from './ErrorBoundary'
4
4
  import { Loading } from './Loading'
5
5
 
6
+ interface Props extends WithChildren {
7
+ /**
8
+ * Use this to show errors in small spaces.
9
+ */
10
+ mini?: boolean,
11
+ /**
12
+ * Replaces the error message with this text.
13
+ */
14
+ message?: string,
15
+ }
16
+
6
17
  /**
7
18
  * Fallbacks for errors and loadings (suspense).
8
19
  */
9
- export const FallbackBoundary = ({ children }: WithChildren) => (
10
- <ErrorBoundary>
20
+ export const FallbackBoundary = ({ children, mini, message }: Props) => (
21
+ <ErrorBoundary mini={mini} message={message}>
11
22
  <Suspense fallback={<Loading />}>
12
23
  {children}
13
24
  </Suspense>
@@ -1,4 +1,3 @@
1
- /* eslint-disable no-empty-pattern */
2
1
  import { Text } from '@citric/core'
3
2
  import { theme, WithStyle } from '@stack-spot/portal-theme'
4
3
  import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
@@ -10,9 +9,21 @@ import { subtractDays } from '../utils/date'
10
9
  type HistorySectionName = 'today' | 'yesterday' | 'last7' | 'last30' | 'older'
11
10
 
12
11
  interface Props<T> extends WithStyle {
12
+ /**
13
+ * The items in the history.
14
+ */
13
15
  items: T[],
16
+ /**
17
+ * A function to render an item.
18
+ */
14
19
  renderItem: (item: T) => React.ReactNode,
20
+ /**
21
+ * A function that returns the date of the item.
22
+ */
15
23
  getDate: (item: T) => Date,
24
+ /**
25
+ * A function that returns a unique id for the item.
26
+ */
16
27
  keygen: (item: T) => React.Key,
17
28
  }
18
29
 
@@ -53,6 +64,9 @@ function dateToSectionName(date: Date): HistorySectionName {
53
64
  return date.getTime() >= last30Days.getTime() ? 'last30' : 'older'
54
65
  }
55
66
 
67
+ /**
68
+ * Renders a history list, where the items are combined into sections according to their dates.
69
+ */
56
70
  export function HistoryList<T>({ getDate, items, keygen, className, style, renderItem }: Props<T>) {
57
71
  const t = useTranslate(dictionary)
58
72
  const sections = useMemo(() => {
@@ -47,6 +47,9 @@ const InputBox = styled.div`
47
47
  }
48
48
  `
49
49
 
50
+ /**
51
+ * A text input with an icon at the left side.
52
+ */
50
53
  export const IconInput = ({ icon, onChange, style, className, disabled, onFocus, onBlur, ...props }: Props) => {
51
54
  const [focused, setFocused] = useState(false)
52
55
 
@@ -1,7 +1,8 @@
1
- /* eslint-disable no-empty-pattern */
1
+ /* eslint-disable react/display-name */
2
2
  import { IconBox, Text } from '@citric/core'
3
+ import { useKeyboardControls } from '@stack-spot/portal-components'
3
4
  import { theme, WithStyle } from '@stack-spot/portal-theme'
4
- import { useMemo } from 'react'
5
+ import { forwardRef, RefObject, useCallback, useRef } from 'react'
5
6
  import { styled } from 'styled-components'
6
7
  import { ButtonAction, WithChildren } from '../types'
7
8
  import { Tooltip } from './Tooltip'
@@ -9,10 +10,27 @@ import { useTooltip } from './Tooltip/context'
9
10
  import { TooltipPosition } from './Tooltip/types'
10
11
 
11
12
  interface Props extends WithStyle, WithChildren {
13
+ /**
14
+ * The position of the menu relative to its children.
15
+ */
12
16
  position?: TooltipPosition,
17
+ /**
18
+ * The actions of the menu.
19
+ */
13
20
  actions: ButtonAction[],
14
21
  }
15
22
 
23
+ interface MenuProps {
24
+ /**
25
+ * The actions of the menu.
26
+ */
27
+ actions: ButtonAction[],
28
+ /**
29
+ * A reference to the HTML element that triggered the menu.
30
+ */
31
+ trigger: RefObject<HTMLDivElement>,
32
+ }
33
+
16
34
  const MenuList = styled.ul`
17
35
  margin: 0;
18
36
  padding: 0;
@@ -37,8 +55,9 @@ const MenuList = styled.ul`
37
55
  gap: 8px;
38
56
  background-color: transparent;
39
57
  border: none;
58
+ outline: none;
40
59
 
41
- &:hover {
60
+ &:hover, &:focus {
42
61
  background-color: ${theme.color.light[500]};
43
62
  }
44
63
  }
@@ -53,25 +72,62 @@ const StyledButton = styled.button<{ $color: string | undefined }>`
53
72
  }
54
73
  `
55
74
 
56
- export const OverlayMenu = ({ actions, children, className, position, style }: Props) => {
75
+ const Menu = ({ actions, trigger }: MenuProps) => {
57
76
  const tooltip = useTooltip()
58
- const menu = useMemo(() => {
59
- const items = actions.map(({ label, onClick, className, color, icon, style }) => (
60
- <li key={label} className={className} style={style}>
61
- <StyledButton $color={color} onClick={() => {
62
- onClick()
63
- tooltip.hide()
64
- }}>
65
- <IconBox>{icon}</IconBox>
66
- <Text>{label}</Text>
67
- </StyledButton>
68
- </li>
69
- ))
70
- return <MenuList>{items}</MenuList>
71
- }, [actions])
77
+ const ref = useRef<HTMLUListElement>(null)
78
+
79
+ useKeyboardControls({
80
+ querySelectors: 'button',
81
+ onPressEscape: () => {
82
+ tooltip.hide()
83
+ trigger.current?.focus()
84
+ },
85
+ ref,
86
+ }, [])
87
+
72
88
  return (
73
- <Tooltip content={menu} custom position={position} className={className} style={style} triggeredBy="click">
89
+ <MenuList ref={ref}>
90
+ {actions.map(({ label, onClick, className, color, icon, style }) => (
91
+ <li key={label} className={className} style={style}>
92
+ <StyledButton $color={color} onClick={() => {
93
+ onClick()
94
+ tooltip.hide()
95
+ }}>
96
+ <IconBox>{icon}</IconBox>
97
+ <Text>{label}</Text>
98
+ </StyledButton>
99
+ </li>
100
+ ))}
101
+ </MenuList>
102
+ )
103
+ }
104
+
105
+ /**
106
+ * A floating menu that shows up when the user clicks the children.
107
+ *
108
+ * This uses the tooltip component to build the menu.
109
+ */
110
+ export const OverlayMenu = forwardRef<HTMLDivElement, Props>(({ actions, children, className, position, style }, externalRef) => {
111
+ const localRef = useRef<HTMLDivElement>(null)
112
+ const ref = externalRef as RefObject<HTMLDivElement> ?? localRef
113
+ const tooltip = useTooltip()
114
+
115
+ const onShow = useCallback(() => {
116
+ tooltip.tooltipRef.current?.querySelector('button')?.focus()
117
+ }, [])
118
+
119
+ return (
120
+ <Tooltip
121
+ content={<Menu actions={actions} trigger={ref} />}
122
+ custom
123
+ position={position}
124
+ className={className}
125
+ style={style}
126
+ triggeredBy="click"
127
+ onShow={onShow}
128
+ ref={ref}
129
+ >
74
130
  {children}
75
131
  </Tooltip>
76
132
  )
77
- }
133
+ })
@@ -2,10 +2,28 @@ import { listToClass, theme, WithStyle } from '@stack-spot/portal-theme'
2
2
  import { styled } from 'styled-components'
3
3
 
4
4
  interface Props extends WithStyle {
5
+ /**
6
+ * Whether or not the progress bar is visible.
7
+ */
5
8
  visible?: boolean,
9
+ /**
10
+ * When true, the progress bar becomes very colorful and bright.
11
+ */
6
12
  shimmer?: boolean,
13
+ /**
14
+ * Color to use in the progress bar that appears in the foreground. Arrays create linear gradients.
15
+ * @default primary.500 if shimmer is false, white otherwise.
16
+ */
7
17
  foregroundColor?: string | string[],
18
+ /**
19
+ * Color to use in the progress bar that appears in the background. Arrays create linear gradients.
20
+ * @default light.500 if shimmer is false, a transparent white otherwise.
21
+ */
8
22
  backgroundColor?: string | string[],
23
+ /**
24
+ * Only useful if `shimmer` is true. This allows to customize the colors in the shimmering effect. Arrays create linear gradients.
25
+ * @default ['#ff6633', '#d668cd', '#ff6633', '#FFF8', '#299cf4']
26
+ */
9
27
  shimmerColor?: string | string[],
10
28
  }
11
29
 
@@ -21,6 +39,7 @@ function gradientFromColorArray(colors: string[]) {
21
39
  return `linear-gradient(to right, ${partials.join(', ')})`
22
40
  }
23
41
 
42
+ // the shimmering effect requires more space
24
43
  const SHIMMER_PADDING = '10px'
25
44
 
26
45
  const Styled = styled.div<{ $bg: string[], $fg: string[], $shimmer: string[] }>`
@@ -123,6 +142,10 @@ const Styled = styled.div<{ $bg: string[], $fg: string[], $shimmer: string[] }>`
123
142
  }
124
143
  `
125
144
 
145
+ /**
146
+ * A progress bar with indefinite progress report. This renders a narrower bar on top of larger one that animates from the left to the
147
+ * right.
148
+ */
126
149
  export const ProgressBar = ({
127
150
  visible = true,
128
151
  shimmer,
@@ -7,6 +7,9 @@ interface Props extends ButtonAction, WithStyle {
7
7
  background?: string,
8
8
  }
9
9
 
10
+ /**
11
+ * A button for quick starting a conversation.
12
+ */
10
13
  const QuickButton = styled.button<{ $color?: string, $bg?: string }>`
11
14
  display: flex;
12
15
  flex-direction: column;
@@ -1,6 +1,7 @@
1
1
  import { Card } from '@citric/ui'
2
2
  import { styled } from 'styled-components'
3
3
  import { PropsOf } from '../types'
4
+ import { AutoFocus } from './AutoFocus'
4
5
  import { FallbackBoundary } from './FallbackBoundary'
5
6
 
6
7
  const Form = styled.form`
@@ -40,16 +41,21 @@ const Form = styled.form`
40
41
  }
41
42
  `
42
43
 
44
+ /**
45
+ * A form that goes into a right panel. This controls style, errors, loading focus and form submission.
46
+ */
43
47
  export const RightPanelForm = ({ children, onSubmit, ...props }: PropsOf<typeof Form>) => (
44
48
  <FallbackBoundary>
45
- <Form
46
- {...props}
47
- onSubmit={(e) => {
48
- e.preventDefault()
49
- onSubmit?.(e)
50
- }}
51
- >
52
- {children}
53
- </Form>
49
+ <AutoFocus>
50
+ <Form
51
+ {...props}
52
+ onSubmit={(e) => {
53
+ e.preventDefault()
54
+ onSubmit?.(e)
55
+ }}
56
+ >
57
+ {children}
58
+ </Form>
59
+ </AutoFocus>
54
60
  </FallbackBoundary>
55
61
  )
@@ -24,6 +24,9 @@ const StyledTabsItem = styled(TabsItem)`
24
24
  overflow: hidden;
25
25
  `
26
26
 
27
+ /**
28
+ * Tabs for the right panel content.
29
+ */
27
30
  export const RightPanelTabs = ({ tabs }: Props) => {
28
31
  const [currentTab, setCurrentTab] = useState(0)
29
32
  const tabItems = useMemo(() => tabs.map(({ content, title }) => (