@envive-ai/react-toolkit-v3 0.3.22 → 0.3.24

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 (366) hide show
  1. package/dist/AnimatedText/AnimatedText.d.cts +3 -3
  2. package/dist/AnimatedText/AnimatedText.d.ts +3 -3
  3. package/dist/CSSVariablesEditor/CssVariablesEditorComponent.d.cts +2 -2
  4. package/dist/CSSVariablesEditor/CssVariablesEditorComponent.d.ts +2 -2
  5. package/dist/CSSVariablesEditor/hooks/useGetCssVariablesOptions.cjs +1 -1
  6. package/dist/CSSVariablesEditor/hooks/useGetCssVariablesOptions.js +1 -1
  7. package/dist/CSSVariablesEditor/hooks/useGetCurrentMerchantColors.cjs +1 -1
  8. package/dist/CSSVariablesEditor/hooks/useGetCurrentMerchantColors.js +1 -1
  9. package/dist/CSSVariablesEditor/hooks/useGetDefaultCssVariables.cjs +4 -4
  10. package/dist/CSSVariablesEditor/hooks/useGetDefaultCssVariables.js +4 -4
  11. package/dist/CSSVariablesEditor/hooks/useHandleUpdateCssVars.cjs +3 -3
  12. package/dist/CSSVariablesEditor/hooks/useHandleUpdateCssVars.js +3 -3
  13. package/dist/Carousel/Carousel.d.cts +2 -2
  14. package/dist/Carousel/components/Badge.cjs +1 -1
  15. package/dist/Carousel/components/Badge.js +1 -1
  16. package/dist/Carousel/components/Container.cjs +1 -1
  17. package/dist/Carousel/components/Container.js +1 -1
  18. package/dist/ChatFooter/ChatFooter.cjs +7 -3
  19. package/dist/ChatFooter/ChatFooter.d.cts +7 -3
  20. package/dist/ChatFooter/ChatFooter.d.ts +7 -3
  21. package/dist/ChatFooter/ChatFooter.js +7 -3
  22. package/dist/ChatFooter/components/Layout.cjs +1 -1
  23. package/dist/ChatFooter/components/Layout.js +1 -1
  24. package/dist/ChatFooter/components/index.d.cts +10 -6
  25. package/dist/ChatFooter/components/index.d.ts +10 -6
  26. package/dist/ChatFooter/types/types.d.cts +16 -0
  27. package/dist/ChatFooter/types/types.d.ts +16 -0
  28. package/dist/ChatHeader/ChatHeader.cjs +2 -1
  29. package/dist/ChatHeader/ChatHeader.d.cts +2 -2
  30. package/dist/ChatHeader/ChatHeader.d.ts +2 -2
  31. package/dist/ChatHeader/ChatHeader.js +2 -1
  32. package/dist/ChatHeader/components/Handle.cjs +2 -2
  33. package/dist/ChatHeader/components/Handle.js +2 -2
  34. package/dist/ChatHeader/hooks/useGetHandleProperties.cjs +4 -2
  35. package/dist/ChatHeader/hooks/useGetHandleProperties.js +4 -2
  36. package/dist/ChatHeader/hooks/useGetLayoutProperties.cjs +1 -1
  37. package/dist/ChatHeader/hooks/useGetLayoutProperties.js +1 -1
  38. package/dist/ChatHeader/hooks/useGetToggleOptionProperties.cjs +1 -1
  39. package/dist/ChatHeader/hooks/useGetToggleOptionProperties.js +1 -1
  40. package/dist/ChatPreview/ChatPreview.cjs +6 -3
  41. package/dist/ChatPreview/ChatPreview.d.cts +2 -2
  42. package/dist/ChatPreview/ChatPreview.d.ts +2 -2
  43. package/dist/ChatPreview/ChatPreview.js +6 -3
  44. package/dist/ChatPreview/index.d.cts +2 -2
  45. package/dist/ChatPreview/index.d.ts +2 -2
  46. package/dist/ChatPreview/types/types.d.cts +13 -1
  47. package/dist/ChatPreview/types/types.d.ts +13 -1
  48. package/dist/ChatPreviewComparison/ChatPreviewComparison.cjs +6 -3
  49. package/dist/ChatPreviewComparison/ChatPreviewComparison.d.cts +2 -2
  50. package/dist/ChatPreviewComparison/ChatPreviewComparison.d.ts +2 -2
  51. package/dist/ChatPreviewComparison/ChatPreviewComparison.js +6 -3
  52. package/dist/ChatPreviewComparison/components/Layout.cjs +2 -2
  53. package/dist/ChatPreviewComparison/components/Layout.js +2 -2
  54. package/dist/ChatPreviewComparison/index.d.cts +2 -2
  55. package/dist/ChatPreviewComparison/index.d.ts +2 -2
  56. package/dist/ChatPreviewComparison/types/types.d.cts +13 -1
  57. package/dist/ChatPreviewComparison/types/types.d.ts +13 -1
  58. package/dist/ChatPreviewLoading/ChatPreviewLoading.cjs +7 -2
  59. package/dist/ChatPreviewLoading/ChatPreviewLoading.d.cts +4 -3
  60. package/dist/ChatPreviewLoading/ChatPreviewLoading.d.ts +2 -1
  61. package/dist/ChatPreviewLoading/ChatPreviewLoading.js +7 -2
  62. package/dist/ChatPreviewLoading/types/types.d.cts +4 -0
  63. package/dist/ChatPreviewLoading/types/types.d.ts +4 -0
  64. package/dist/Container/Container.d.cts +172 -172
  65. package/dist/Container/Container.d.ts +172 -172
  66. package/dist/DesignTokens/DesignTokensComponent.d.cts +2 -2
  67. package/dist/DesignTokens/DesignTokensComponent.d.ts +2 -2
  68. package/dist/DesignTokens/components/FontFamily.cjs +1 -1
  69. package/dist/DesignTokens/components/FontFamily.js +1 -1
  70. package/dist/DesignTokens/components/FontSize.cjs +1 -1
  71. package/dist/DesignTokens/components/FontSize.js +1 -1
  72. package/dist/DesignTokens/components/FontWeight.cjs +1 -1
  73. package/dist/DesignTokens/components/FontWeight.js +1 -1
  74. package/dist/DesignTokens/components/LetterSpacing.cjs +1 -1
  75. package/dist/DesignTokens/components/LetterSpacing.js +1 -1
  76. package/dist/DesignTokens/components/LineHeight.cjs +1 -1
  77. package/dist/DesignTokens/components/LineHeight.js +1 -1
  78. package/dist/DesignTokens/components/Typography.cjs +1 -1
  79. package/dist/DesignTokens/components/Typography.js +1 -1
  80. package/dist/Disclaimer/components/Container.cjs +2 -2
  81. package/dist/Disclaimer/components/Container.js +2 -2
  82. package/dist/DocumentRetrievalCard/DocumentRetrievalCard.d.ts +2 -2
  83. package/dist/DocumentRetrievalCard/components/Image.cjs +1 -1
  84. package/dist/DocumentRetrievalCard/components/Image.js +1 -1
  85. package/dist/DocumentRetrievalCard/components/Layout.cjs +1 -1
  86. package/dist/DocumentRetrievalCard/components/Layout.js +1 -1
  87. package/dist/DocumentRetrievalCard/components/ViewArticleButton/components/Icon.cjs +1 -1
  88. package/dist/DocumentRetrievalCard/components/ViewArticleButton/components/Icon.js +1 -1
  89. package/dist/DocumentRetrievalCard/components/ViewArticleButton/components/Label.cjs +1 -1
  90. package/dist/DocumentRetrievalCard/components/ViewArticleButton/components/Label.js +1 -1
  91. package/dist/DocumentRetrievalCard/components/ViewArticleButton/components/Layout.cjs +1 -1
  92. package/dist/DocumentRetrievalCard/components/ViewArticleButton/components/Layout.js +1 -1
  93. package/dist/FloatingButton/FloatingButton.d.cts +2 -2
  94. package/dist/FloatingButton/components/Button.cjs +1 -1
  95. package/dist/FloatingButton/components/Button.js +1 -1
  96. package/dist/FloatingButton/components/Container.cjs +1 -1
  97. package/dist/FloatingButton/components/Container.js +1 -1
  98. package/dist/FloatingButton/components/Wrapper.cjs +1 -1
  99. package/dist/FloatingButton/components/Wrapper.js +1 -1
  100. package/dist/FloatingChat/FloatingChat.cjs +32 -4
  101. package/dist/FloatingChat/FloatingChat.d.cts +2 -2
  102. package/dist/FloatingChat/FloatingChat.d.ts +2 -2
  103. package/dist/FloatingChat/FloatingChat.js +33 -5
  104. package/dist/FloatingChat/components/AgentMessage.cjs +2 -2
  105. package/dist/FloatingChat/components/AgentMessage.js +2 -2
  106. package/dist/FloatingChat/components/ChatMessages.cjs +1 -1
  107. package/dist/FloatingChat/components/ChatMessages.js +1 -1
  108. package/dist/FloatingChat/components/Layout.cjs +1 -1
  109. package/dist/FloatingChat/components/Layout.js +1 -1
  110. package/dist/FloatingChat/components/ProductResultsModal.cjs +1 -1
  111. package/dist/FloatingChat/components/ProductResultsModal.js +1 -1
  112. package/dist/FloatingChat/components/ResultsGridView.cjs +1 -1
  113. package/dist/FloatingChat/components/ResultsGridView.js +1 -1
  114. package/dist/FloatingChat/components/SalesAgentBadgeContent.cjs +1 -1
  115. package/dist/FloatingChat/components/SalesAgentBadgeContent.js +1 -1
  116. package/dist/FloatingChat/components/SlideChatContent.cjs +1 -1
  117. package/dist/FloatingChat/components/SlideChatContent.js +1 -1
  118. package/dist/FloatingChat/hooks/useChatSuggestions.cjs +3 -5
  119. package/dist/FloatingChat/hooks/useChatSuggestions.js +4 -6
  120. package/dist/Form/Form.cjs +1 -1
  121. package/dist/Form/Form.js +1 -1
  122. package/dist/Form/components/Layout.cjs +1 -1
  123. package/dist/Form/components/Layout.js +1 -1
  124. package/dist/Form/components/SubmitButtonItem.cjs +1 -1
  125. package/dist/Form/components/SubmitButtonItem.js +1 -1
  126. package/dist/Form/components/TextFieldItem.cjs +1 -1
  127. package/dist/Form/components/TextFieldItem.js +1 -1
  128. package/dist/FullPageSalesAgent/FullPageSalesAgent.cjs +29 -2
  129. package/dist/FullPageSalesAgent/FullPageSalesAgent.d.cts +5 -3
  130. package/dist/FullPageSalesAgent/FullPageSalesAgent.d.ts +5 -3
  131. package/dist/FullPageSalesAgent/FullPageSalesAgent.js +30 -3
  132. package/dist/FullPageSalesAgent/components/Layout.cjs +1 -1
  133. package/dist/FullPageSalesAgent/components/Layout.js +1 -1
  134. package/dist/Image/Image.cjs +1 -1
  135. package/dist/Image/Image.d.cts +2 -2
  136. package/dist/Image/Image.d.ts +2 -2
  137. package/dist/Image/Image.js +1 -1
  138. package/dist/ImageGallery/ImageGallery.d.cts +2 -2
  139. package/dist/ImageGallery/ImageGallery.d.ts +2 -2
  140. package/dist/ImageGallery/components/Layout.cjs +1 -1
  141. package/dist/ImageGallery/components/Layout.js +1 -1
  142. package/dist/ImageGallery/utils/functions.cjs +1 -1
  143. package/dist/ImageGallery/utils/functions.js +1 -1
  144. package/dist/MarkdownProcessor/MarkdownProcessor.d.cts +2 -2
  145. package/dist/Message/components/Layout.cjs +1 -1
  146. package/dist/Message/components/Layout.js +1 -1
  147. package/dist/OrderLookupCard/OrderLookupCard.cjs +1 -1
  148. package/dist/OrderLookupCard/OrderLookupCard.js +1 -1
  149. package/dist/OrderLookupCard/components/Layout.cjs +1 -1
  150. package/dist/OrderLookupCard/components/Layout.js +1 -1
  151. package/dist/OrderLookupCard/components/MoreProductsOverlay.cjs +1 -1
  152. package/dist/OrderLookupCard/components/MoreProductsOverlay.js +1 -1
  153. package/dist/OrderLookupCard/components/ProductImageGridItem.cjs +1 -1
  154. package/dist/OrderLookupCard/components/ProductImageGridItem.js +1 -1
  155. package/dist/OrderLookupCard/components/ProductImageItem.cjs +1 -1
  156. package/dist/OrderLookupCard/components/ProductImageItem.js +1 -1
  157. package/dist/OrderLookupCard/components/ProductImagesGrid.cjs +1 -1
  158. package/dist/OrderLookupCard/components/ProductImagesGrid.js +1 -1
  159. package/dist/OrderLookupCard/components/StatusLabel.cjs +1 -1
  160. package/dist/OrderLookupCard/components/StatusLabel.js +1 -1
  161. package/dist/OrderLookupCard/components/TrackOrderLink.cjs +1 -1
  162. package/dist/OrderLookupCard/components/TrackOrderLink.js +1 -1
  163. package/dist/ProductCard/ProductCard.cjs +6 -2
  164. package/dist/ProductCard/ProductCard.d.cts +6 -3
  165. package/dist/ProductCard/ProductCard.d.ts +6 -3
  166. package/dist/ProductCard/ProductCard.js +6 -2
  167. package/dist/ProductCard/index.d.cts +2 -2
  168. package/dist/ProductCard/index.d.ts +2 -2
  169. package/dist/ProductCard/types/index.d.cts +7 -1
  170. package/dist/ProductCard/types/index.d.ts +7 -1
  171. package/dist/PromptButton/PromptButton.cjs +1 -1
  172. package/dist/PromptButton/PromptButton.d.cts +2 -2
  173. package/dist/PromptButton/PromptButton.js +1 -1
  174. package/dist/PromptButton/components/Layout.cjs +1 -1
  175. package/dist/PromptButton/components/Layout.js +1 -1
  176. package/dist/PromptButton/components/Loading.cjs +1 -1
  177. package/dist/PromptButton/components/Loading.js +1 -1
  178. package/dist/PromptButtonCarouselWithImage/PromptButtonCarouselWithImage.cjs +5 -2
  179. package/dist/PromptButtonCarouselWithImage/PromptButtonCarouselWithImage.d.cts +6 -3
  180. package/dist/PromptButtonCarouselWithImage/PromptButtonCarouselWithImage.d.ts +6 -3
  181. package/dist/PromptButtonCarouselWithImage/PromptButtonCarouselWithImage.js +5 -2
  182. package/dist/PromptButtonCarouselWithImage/components/Layout.cjs +1 -1
  183. package/dist/PromptButtonCarouselWithImage/components/Layout.js +1 -1
  184. package/dist/PromptButtonCarouselWithImage/components/Skeleton.cjs +1 -1
  185. package/dist/PromptButtonCarouselWithImage/components/Skeleton.js +1 -1
  186. package/dist/PromptButtonCarouselWithImage/types/types.d.cts +12 -0
  187. package/dist/PromptButtonCarouselWithImage/types/types.d.ts +12 -0
  188. package/dist/PromptCarousel/PromptCarousel.cjs +1 -1
  189. package/dist/PromptCarousel/PromptCarousel.d.cts +2 -2
  190. package/dist/PromptCarousel/PromptCarousel.d.ts +2 -2
  191. package/dist/PromptCarousel/PromptCarousel.js +1 -1
  192. package/dist/PromptCarousel/hooks/useCarouselButtons.cjs +3 -2
  193. package/dist/PromptCarousel/hooks/useCarouselButtons.js +3 -2
  194. package/dist/ReviewCard/ReviewCard.d.cts +2 -2
  195. package/dist/ReviewCard/ReviewCard.d.ts +2 -2
  196. package/dist/ReviewCard/components/Container.cjs +1 -1
  197. package/dist/ReviewCard/components/Container.js +1 -1
  198. package/dist/ReviewCard/components/Rating.cjs +1 -2
  199. package/dist/ReviewCard/components/Rating.js +1 -2
  200. package/dist/ReviewCard/components/ReadMoreButton.cjs +1 -1
  201. package/dist/ReviewCard/components/ReadMoreButton.js +1 -1
  202. package/dist/ReviewCard/components/index.d.cts +6 -6
  203. package/dist/ReviewCard/components/index.d.ts +6 -6
  204. package/dist/SalesAgentProductCard/SalesAgentProductCard.d.cts +2 -2
  205. package/dist/SalesAgentProductCard/components/Container.cjs +1 -1
  206. package/dist/SalesAgentProductCard/components/Container.js +1 -1
  207. package/dist/SalesAgentProductCard/components/ProductImage.cjs +1 -1
  208. package/dist/SalesAgentProductCard/components/ProductImage.js +1 -1
  209. package/dist/SalesAgentProductCard/components/ProductName.cjs +1 -1
  210. package/dist/SalesAgentProductCard/components/ProductName.js +1 -1
  211. package/dist/SalesAgentProductCard/components/index.d.cts +8 -8
  212. package/dist/SocialProof/SocialProof.cjs +6 -3
  213. package/dist/SocialProof/SocialProof.d.cts +2 -2
  214. package/dist/SocialProof/SocialProof.d.ts +2 -2
  215. package/dist/SocialProof/SocialProof.js +6 -3
  216. package/dist/SocialProof/components/Headline.cjs +1 -1
  217. package/dist/SocialProof/components/Headline.js +1 -1
  218. package/dist/SocialProof/components/LayoutFourHorizontal.cjs +1 -1
  219. package/dist/SocialProof/components/LayoutFourHorizontal.js +1 -1
  220. package/dist/SocialProof/components/Textfield.cjs +5 -2
  221. package/dist/SocialProof/components/Textfield.js +5 -2
  222. package/dist/SocialProof/index.d.cts +2 -2
  223. package/dist/SocialProof/index.d.ts +2 -2
  224. package/dist/SocialProof/types/types.d.cts +13 -1
  225. package/dist/SocialProof/types/types.d.ts +13 -1
  226. package/dist/SparkleAnimation/SparkleAnimation.d.cts +2 -2
  227. package/dist/Stack/Stack.d.cts +2 -2
  228. package/dist/Stack/Stack.d.ts +2 -2
  229. package/dist/TextField/TextField.cjs +35 -3
  230. package/dist/TextField/TextField.d.cts +5 -1
  231. package/dist/TextField/TextField.d.ts +5 -1
  232. package/dist/TextField/TextField.js +35 -3
  233. package/dist/TextField/components/Input.cjs +1 -1
  234. package/dist/TextField/components/Input.js +1 -1
  235. package/dist/TextField/components/Layout.cjs +11 -8
  236. package/dist/TextField/components/Layout.js +11 -8
  237. package/dist/TextField/components/SendIcon.cjs +1 -1
  238. package/dist/TextField/components/SendIcon.js +1 -1
  239. package/dist/TextField/components/VoiceInputButton.cjs +45 -0
  240. package/dist/TextField/components/VoiceInputButton.js +39 -0
  241. package/dist/TextField/components/index.cjs +3 -1
  242. package/dist/TextField/components/index.js +3 -1
  243. package/dist/TextField/hooks/useGetMicButtonContainerProperties.cjs +20 -0
  244. package/dist/TextField/hooks/useGetMicButtonContainerProperties.js +19 -0
  245. package/dist/TextField/hooks/useGetSkeletonProperties.cjs +1 -1
  246. package/dist/TextField/hooks/useGetSkeletonProperties.js +1 -1
  247. package/dist/TextField/hooks/useVoiceInput.cjs +52 -0
  248. package/dist/TextField/hooks/useVoiceInput.js +50 -0
  249. package/dist/TextField/types/index.d.cts +11 -0
  250. package/dist/TextField/types/index.d.ts +11 -0
  251. package/dist/TextField/utils/getLayoutStateProperties.cjs +9 -1
  252. package/dist/TextField/utils/getLayoutStateProperties.js +8 -1
  253. package/dist/Title/Title.cjs +1 -1
  254. package/dist/Title/Title.js +1 -1
  255. package/dist/Title/components/Layout.cjs +1 -1
  256. package/dist/Title/components/Layout.js +1 -1
  257. package/dist/TitledPromptCarousel/TitledPromptCarousel.cjs +1 -1
  258. package/dist/TitledPromptCarousel/TitledPromptCarousel.d.cts +2 -2
  259. package/dist/TitledPromptCarousel/TitledPromptCarousel.js +1 -1
  260. package/dist/Tokens/index.cjs +6 -6
  261. package/dist/Tokens/index.js +6 -6
  262. package/dist/TypingAnimation/TypingAnimation.cjs +7 -3
  263. package/dist/TypingAnimation/TypingAnimation.d.cts +2 -2
  264. package/dist/TypingAnimation/TypingAnimation.d.ts +2 -2
  265. package/dist/TypingAnimation/TypingAnimation.js +7 -3
  266. package/dist/TypingAnimation/index.d.cts +2 -2
  267. package/dist/TypingAnimation/index.d.ts +2 -2
  268. package/dist/TypingAnimation/types/index.d.cts +13 -1
  269. package/dist/TypingAnimation/types/index.d.ts +13 -1
  270. package/dist/Typography/Typography.d.cts +4 -4
  271. package/dist/Typography/Typography.d.ts +4 -4
  272. package/dist/WelcomeMessage/components/Container.cjs +1 -1
  273. package/dist/WelcomeMessage/components/Container.js +1 -1
  274. package/dist/WidgetTextField/WidgetTextField.cjs +39 -7
  275. package/dist/WidgetTextField/WidgetTextField.d.cts +7 -3
  276. package/dist/WidgetTextField/WidgetTextField.d.ts +7 -3
  277. package/dist/WidgetTextField/WidgetTextField.js +33 -2
  278. package/dist/WidgetTextField/components/Container.cjs +32 -26
  279. package/dist/WidgetTextField/components/Container.js +32 -26
  280. package/dist/WidgetTextField/components/Skeleton.cjs +1 -1
  281. package/dist/WidgetTextField/components/Skeleton.js +1 -1
  282. package/dist/WidgetTextField/hooks/useGetContainerProperties.cjs +5 -3
  283. package/dist/WidgetTextField/hooks/useGetContainerProperties.js +5 -3
  284. package/dist/WidgetTextField/hooks/useGetMicWidgetButtonProperties.cjs +20 -0
  285. package/dist/WidgetTextField/hooks/useGetMicWidgetButtonProperties.js +19 -0
  286. package/dist/WidgetTextField/types/types.d.cts +21 -0
  287. package/dist/WidgetTextField/types/types.d.ts +21 -0
  288. package/dist/WidgetWrapper/WidgetWrapper.cjs +1 -1
  289. package/dist/WidgetWrapper/WidgetWrapper.d.cts +2 -2
  290. package/dist/WidgetWrapper/WidgetWrapper.js +1 -1
  291. package/dist/WidgetWrapper/hooks/useGetWrapperProperties.cjs +1 -1
  292. package/dist/WidgetWrapper/hooks/useGetWrapperProperties.js +1 -1
  293. package/dist/WidgetWrapperWithTitle/WidgetWrapperWithTitle.d.cts +2 -2
  294. package/dist/WidgetWrapperWithTitle/WidgetWrapperWithTitle.d.ts +2 -2
  295. package/dist/node_modules/jotai/esm/react.cjs +87 -0
  296. package/dist/node_modules/jotai/esm/react.js +88 -2
  297. package/dist/node_modules/jotai/esm/vanilla/internals.cjs +2 -1
  298. package/dist/node_modules/jotai/esm/vanilla/internals.js +1 -1
  299. package/dist/packages/components-v3/tokens/typography/typography.cjs +1 -1
  300. package/dist/packages/components-v3/tokens/typography/typography.js +1 -1
  301. package/dist/styles.css +1 -1
  302. package/dist/utils/resolveTheme.cjs +1 -1
  303. package/dist/utils/resolveTheme.js +1 -1
  304. package/package.json +2 -1
  305. package/src/components/ChatFooter/ChatFooter.tsx +8 -0
  306. package/src/components/ChatFooter/__tests__/ChatFooter.test.tsx +43 -0
  307. package/src/components/ChatFooter/components/TextField.tsx +12 -0
  308. package/src/components/ChatFooter/types/types.ts +17 -0
  309. package/src/components/ChatHeader/ChatHeader.tsx +1 -0
  310. package/src/components/ChatHeader/components/Handle.tsx +7 -2
  311. package/src/components/ChatHeader/hooks/useGetHandleProperties.ts +5 -1
  312. package/src/components/ChatHeader/hooks/useGetToggleOptionProperties.ts +1 -1
  313. package/src/components/ChatHeader/types/index.ts +1 -0
  314. package/src/components/ChatPreview/ChatPreview.tsx +13 -2
  315. package/src/components/ChatPreview/__tests__/ChatPreview.test.tsx +44 -0
  316. package/src/components/ChatPreview/index.ts +1 -1
  317. package/src/components/ChatPreview/types/types.ts +13 -0
  318. package/src/components/ChatPreviewComparison/ChatPreviewComparison.tsx +6 -0
  319. package/src/components/ChatPreviewComparison/__tests__/ChatPreviewComparison.test.tsx +44 -0
  320. package/src/components/ChatPreviewComparison/index.ts +1 -1
  321. package/src/components/ChatPreviewComparison/types/types.ts +13 -0
  322. package/src/components/ChatPreviewLoading/ChatPreviewLoading.tsx +5 -3
  323. package/src/components/ChatPreviewLoading/__tests__/ChatPreviewLoading.test.tsx +40 -0
  324. package/src/components/ChatPreviewLoading/types/types.ts +5 -0
  325. package/src/components/Disclaimer/components/Container.tsx +1 -1
  326. package/src/components/FloatingChat/FloatingChat.tsx +43 -7
  327. package/src/components/FloatingChat/components/SlideChatContent.tsx +1 -1
  328. package/src/components/FloatingChat/hooks/useChatSuggestions.ts +8 -12
  329. package/src/components/FullPageSalesAgent/FullPageSalesAgent.tsx +43 -7
  330. package/src/components/ProductCard/ProductCard.tsx +7 -0
  331. package/src/components/ProductCard/__tests__/ProductCard.test.tsx +33 -0
  332. package/src/components/ProductCard/index.ts +1 -1
  333. package/src/components/ProductCard/types/index.ts +6 -0
  334. package/src/components/PromptButtonCarouselWithImage/PromptButtonCarouselWithImage.tsx +6 -0
  335. package/src/components/PromptButtonCarouselWithImage/__tests__/PromptButtonCarouselWithImage.test.tsx +34 -0
  336. package/src/components/PromptButtonCarouselWithImage/types/types.ts +12 -0
  337. package/src/components/PromptCarousel/__tests__/PromptCarousel.test.tsx +19 -0
  338. package/src/components/PromptCarousel/hooks/useCarouselButtons.ts +4 -2
  339. package/src/components/ReviewCard/components/Rating.tsx +0 -1
  340. package/src/components/SocialProof/SocialProof.tsx +6 -0
  341. package/src/components/SocialProof/__tests__/SocialProof.test.tsx +58 -0
  342. package/src/components/SocialProof/components/Textfield.tsx +9 -0
  343. package/src/components/SocialProof/index.ts +1 -1
  344. package/src/components/SocialProof/types/types.ts +13 -0
  345. package/src/components/TextField/TextField.tsx +49 -0
  346. package/src/components/TextField/__tests__/TextField.test.tsx +3 -3
  347. package/src/components/TextField/__tests__/VoiceInputButton.test.tsx +175 -0
  348. package/src/components/TextField/components/Layout.tsx +24 -17
  349. package/src/components/TextField/components/VoiceInputButton.tsx +69 -0
  350. package/src/components/TextField/components/index.ts +2 -0
  351. package/src/components/TextField/hooks/useGetMicButtonContainerProperties.ts +38 -0
  352. package/src/components/TextField/hooks/useGetSkeletonProperties.ts +1 -1
  353. package/src/components/TextField/hooks/useVoiceInput.ts +75 -0
  354. package/src/components/TextField/types/index.ts +11 -0
  355. package/src/components/TextField/utils/getLayoutStateProperties.ts +8 -0
  356. package/src/components/TypingAnimation/TypingAnimation.tsx +7 -0
  357. package/src/components/TypingAnimation/__tests__/TypingAnimation.test.tsx +47 -0
  358. package/src/components/TypingAnimation/index.ts +1 -1
  359. package/src/components/TypingAnimation/types/index.ts +14 -1
  360. package/src/components/WidgetTextField/WidgetTextField.tsx +47 -0
  361. package/src/components/WidgetTextField/__tests__/WidgetTextField.test.tsx +119 -4
  362. package/src/components/WidgetTextField/components/Container.tsx +40 -27
  363. package/src/components/WidgetTextField/hooks/useGetContainerProperties.ts +16 -4
  364. package/src/components/WidgetTextField/hooks/useGetMicWidgetButtonProperties.ts +38 -0
  365. package/src/components/WidgetTextField/types/types.ts +21 -0
  366. package/src/components/WidgetWrapper/hooks/useGetWrapperProperties.ts +1 -1
@@ -34,6 +34,7 @@ export const ChatPreviewComparison = ({
34
34
  images,
35
35
  logoSrc,
36
36
  titleLabel,
37
+ voiceInputEnabled,
37
38
  } = widgetContentProps ?? {};
38
39
 
39
40
  const {
@@ -46,6 +47,8 @@ export const ChatPreviewComparison = ({
46
47
  handlePromptButtonTouchEnd,
47
48
  handleLinkClick,
48
49
  handleTextFieldClick,
50
+ onTranscriptionStarted,
51
+ onTranscriptionCompleted,
49
52
  } = widgetEventProps ?? {};
50
53
 
51
54
  const finalTheme = resolveTheme(theme);
@@ -101,6 +104,9 @@ export const ChatPreviewComparison = ({
101
104
  theme={finalTheme}
102
105
  placeholder={textFieldPlaceholderText ?? ''}
103
106
  onClick={() => handleTextFieldClick?.()}
107
+ enableVoiceInput={voiceInputEnabled}
108
+ onTranscriptionStarted={onTranscriptionStarted}
109
+ onTranscriptionCompleted={onTranscriptionCompleted}
104
110
  />
105
111
  );
106
112
 
@@ -418,4 +418,48 @@ describe('ChatPreviewComparison', () => {
418
418
  expect(screen.getByText('Button 1')).toBeInTheDocument();
419
419
  });
420
420
  });
421
+
422
+ describe('Voice input', () => {
423
+ it('should render with voiceInputEnabled set to true', () => {
424
+ render(
425
+ <ChatPreviewComparison
426
+ {...defaultProps}
427
+ widgetContentProps={{
428
+ ...defaultProps.widgetContentProps,
429
+ voiceInputEnabled: true,
430
+ }}
431
+ widgetStyleProps={{ hideTextField: false }}
432
+ />,
433
+ );
434
+ expect(screen.getByText('Compare these products')).toBeInTheDocument();
435
+ });
436
+
437
+ it('should render with voiceInputEnabled set to false', () => {
438
+ render(
439
+ <ChatPreviewComparison
440
+ {...defaultProps}
441
+ widgetContentProps={{
442
+ ...defaultProps.widgetContentProps,
443
+ voiceInputEnabled: false,
444
+ }}
445
+ widgetStyleProps={{ hideTextField: false }}
446
+ />,
447
+ );
448
+ expect(screen.getByText('Compare these products')).toBeInTheDocument();
449
+ });
450
+
451
+ it('should render with voiceInputEnabled undefined (default)', () => {
452
+ render(
453
+ <ChatPreviewComparison
454
+ {...defaultProps}
455
+ widgetContentProps={{
456
+ ...defaultProps.widgetContentProps,
457
+ voiceInputEnabled: undefined,
458
+ }}
459
+ widgetStyleProps={{ hideTextField: false }}
460
+ />,
461
+ );
462
+ expect(screen.getByText('Compare these products')).toBeInTheDocument();
463
+ });
464
+ });
421
465
  });
@@ -1,2 +1,2 @@
1
1
  export { ChatPreviewComparison } from './ChatPreviewComparison';
2
- export type { ChatPreviewComparisonProps } from './types/types';
2
+ export type { ChatPreviewComparisonProps, WidgetEventProps } from './types/types';
@@ -72,6 +72,11 @@ export type WidgetContentProps = {
72
72
  * Array of image objects for the images.
73
73
  */
74
74
  images?: ImageGalleryImage[];
75
+
76
+ /**
77
+ * Whether to enable voice input.
78
+ */
79
+ voiceInputEnabled?: boolean;
75
80
  };
76
81
 
77
82
  /**
@@ -176,6 +181,14 @@ export type WidgetEventProps = {
176
181
  * Callback function invoked when the text field is clicked.
177
182
  */
178
183
  handleTextFieldClick?: () => void;
184
+ /**
185
+ * Callback function invoked when voice transcription starts.
186
+ */
187
+ onTranscriptionStarted?: () => void;
188
+ /**
189
+ * Callback function invoked when voice transcription completes.
190
+ */
191
+ onTranscriptionCompleted?: (transcript: string) => void;
179
192
  };
180
193
 
181
194
  /**
@@ -1,8 +1,8 @@
1
1
  import { useMemo } from 'react';
2
- import { WidgetWrapperVariant } from '../WidgetWrapper';
3
2
  import { Stack } from '../Stack';
4
- import { ChatPreviewLoadingComponents } from './components';
5
3
  import { WidgetTextField } from '../WidgetTextField';
4
+ import { WidgetWrapperVariant } from '../WidgetWrapper';
5
+ import { ChatPreviewLoadingComponents } from './components';
6
6
  import { ChatPreviewLoadingProps } from './types/types';
7
7
 
8
8
  export const ChatPreviewLoading = ({
@@ -18,6 +18,7 @@ export const ChatPreviewLoading = ({
18
18
  hideLogo,
19
19
  logoSrc,
20
20
  titleLabel,
21
+ voiceInputEnabled,
21
22
  }: ChatPreviewLoadingProps) => {
22
23
  const textfield = useMemo(() => {
23
24
  if (fullIsLoading) {
@@ -29,10 +30,11 @@ export const ChatPreviewLoading = ({
29
30
  return (
30
31
  <WidgetTextField
31
32
  placeholder={textFieldPlaceholder ?? ''}
33
+ enableVoiceInput={voiceInputEnabled}
32
34
  disabled
33
35
  />
34
36
  );
35
- }, [fullIsLoading, textFieldPlaceholder]);
37
+ }, [fullIsLoading, textFieldPlaceholder, voiceInputEnabled]);
36
38
 
37
39
  const headline = useMemo(
38
40
  () => (
@@ -330,4 +330,44 @@ describe('ChatPreviewLoading', () => {
330
330
  expect(skeletons.length).toBeGreaterThanOrEqual(6);
331
331
  });
332
332
  });
333
+
334
+ describe('Voice input', () => {
335
+ it('should render with voiceInputEnabled set to true', async () => {
336
+ render(
337
+ <ChatPreviewLoading
338
+ {...defaultProps}
339
+ voiceInputEnabled
340
+ fullIsLoading={false}
341
+ hideTextField={false}
342
+ />,
343
+ );
344
+ await waitFor(() => {
345
+ expect(screen.getByText('What can I help you find?')).toBeInTheDocument();
346
+ });
347
+ });
348
+
349
+ it('should render with voiceInputEnabled set to false', () => {
350
+ render(
351
+ <ChatPreviewLoading
352
+ {...defaultProps}
353
+ voiceInputEnabled={false}
354
+ fullIsLoading={false}
355
+ hideTextField={false}
356
+ />,
357
+ );
358
+ expect(screen.getByText('Shopping Assistant')).toBeInTheDocument();
359
+ });
360
+
361
+ it('should render with voiceInputEnabled undefined (default)', () => {
362
+ render(
363
+ <ChatPreviewLoading
364
+ {...defaultProps}
365
+ voiceInputEnabled={undefined}
366
+ fullIsLoading={false}
367
+ hideTextField={false}
368
+ />,
369
+ );
370
+ expect(screen.getByText('Shopping Assistant')).toBeInTheDocument();
371
+ });
372
+ });
333
373
  });
@@ -50,6 +50,11 @@ export type ChatPreviewLoadingProps = {
50
50
  */
51
51
  hideTextField?: boolean;
52
52
 
53
+ /**
54
+ * Whether to enable voice input.
55
+ */
56
+ voiceInputEnabled?: boolean;
57
+
53
58
  /**
54
59
  * Placeholder text displayed in the text field.
55
60
  * Only used when `fullIsLoading` is `false` and `hideTextField` is `false`.
@@ -22,7 +22,7 @@ export const Container = ({
22
22
  id={id}
23
23
  testId={testId}
24
24
  style={style}
25
- className={classNames(className, 'envive-tw-px-4 envive-tw-py-6')}
25
+ className={classNames(className, 'envive-tw-px-4 envive-tw-pt-6')}
26
26
  >
27
27
  <Stack
28
28
  direction="column"
@@ -1,13 +1,15 @@
1
- import { useEffect, useMemo, useRef, useState } from 'react';
1
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
2
 
3
3
  import { ChatElementDisplayLocationV3 } from '@envive-ai/react-hooks/application/models';
4
- import { motion } from 'framer-motion';
4
+ import { EnviveMetricsEventName } from '@envive-ai/react-hooks/contexts/amplitudeContext';
5
+ import { listeningToSpeechAtom } from '@envive-ai/react-hooks/atoms/chat';
6
+ import { useWidgetInteraction } from '@envive-ai/react-hooks/hooks/WidgetInteraction';
5
7
  import {
6
8
  WidgetInteractionComponent,
7
9
  WidgetInteractionType,
8
10
  } from '@envive-ai/react-hooks/hooks/WidgetInteraction/types';
9
- import { useWidgetInteraction } from '@envive-ai/react-hooks/hooks/WidgetInteraction';
10
- import { EnviveMetricsEventName } from '@envive-ai/react-hooks/contexts/amplitudeContext';
11
+ import { motion } from 'framer-motion';
12
+ import { useSetAtom } from 'jotai';
11
13
  import { Theme } from '../../../tokens/theme/theme';
12
14
  import { ColorNames } from '../../models/colorsConfig';
13
15
 
@@ -24,12 +26,12 @@ import { useScrollToBottom } from './hooks/useScrollToBottom';
24
26
  import { useSnapSetup } from './hooks/useSnapSetup';
25
27
 
26
28
  import { Disclaimer } from '../Disclaimer';
29
+ import { SalesAgentProductCardProps } from '../SalesAgentProductCard/types/types';
27
30
  import { resolveTheme } from '../utils/resolveTheme';
31
+ import { FloatingChatComponents, ModalSheet } from './components';
28
32
  import { useFilteredChatMessages } from './hooks/useFilteredChatMessages';
29
33
  import { Unit } from './hooks/useSnapCalculator';
30
34
  import { FloatingChatProps } from './types/types';
31
- import { FloatingChatComponents, ModalSheet } from './components';
32
- import { SalesAgentProductCardProps } from '../SalesAgentProductCard/types/types';
33
35
  import { trackProductCardClicked } from './utils/trackProductCardInteraction';
34
36
 
35
37
  export const FloatingChat = ({
@@ -54,6 +56,7 @@ export const FloatingChat = ({
54
56
  const { trackWidgetInteraction } = useWidgetInteraction();
55
57
  const { onDrag, onHover, onMouseDown, onMouseUp, onTouchStart, onTouchEnd } =
56
58
  usePromptCarouselAnalytics(WidgetInteractionComponent.FLOATING_CHAT, text => text);
59
+ const setListeningToSpeech = useSetAtom(listeningToSpeechAtom);
57
60
 
58
61
  const [query, setQuery] = useState('');
59
62
 
@@ -93,7 +96,8 @@ export const FloatingChat = ({
93
96
  return undefined;
94
97
  }, [disclaimerText]);
95
98
 
96
- const { agentName, chatHeaderLogoDarkSrc, chatHeaderLogoLightSrc } = lookAndFeelConfig;
99
+ const { agentName, chatHeaderLogoDarkSrc, chatHeaderLogoLightSrc, voiceInputEnabled } =
100
+ lookAndFeelConfig;
97
101
 
98
102
  const {
99
103
  messages,
@@ -217,6 +221,32 @@ export const FloatingChat = ({
217
221
  );
218
222
  };
219
223
 
224
+ const handleTranscriptionStarted = useCallback(() => {
225
+ trackWidgetInteraction({
226
+ eventName: EnviveMetricsEventName.WidgetInteraction,
227
+ trigger: {
228
+ widget: WidgetInteractionComponent.FLOATING_CHAT,
229
+ widget_interaction: WidgetInteractionType.VOICE_TRANSCRIPTION_STARTED,
230
+ },
231
+ });
232
+ }, [trackWidgetInteraction]);
233
+
234
+ const handleTranscriptionCompleted = useCallback(
235
+ (transcript: string) => {
236
+ trackWidgetInteraction({
237
+ eventName: EnviveMetricsEventName.WidgetInteraction,
238
+ trigger: {
239
+ widget: WidgetInteractionComponent.FLOATING_CHAT,
240
+ widget_interaction: WidgetInteractionType.VOICE_TRANSCRIPTION_COMPLETED,
241
+ widget_interaction_data: {
242
+ transcription: transcript,
243
+ },
244
+ },
245
+ });
246
+ },
247
+ [trackWidgetInteraction],
248
+ );
249
+
220
250
  const header = (
221
251
  <ChatHeader
222
252
  logoDark={chatHeaderLogoDarkSrc}
@@ -281,6 +311,7 @@ export const FloatingChat = ({
281
311
  theme={finalTheme}
282
312
  isScrolled={isMobile ? isFloatingLayout : false}
283
313
  onChange={setQuery}
314
+ inputClassName="placeholder:envive-tw-text-text-secondary"
284
315
  onSubmit={() => {
285
316
  onTypedMessageSubmitted({
286
317
  query,
@@ -303,6 +334,7 @@ export const FloatingChat = ({
303
334
  onSuggestionClicked(suggestion, ChatElementDisplayLocationV3.FLOATING_CHAT_PROMPT_BUTTON);
304
335
  }
305
336
 
337
+ setListeningToSpeech('abort');
306
338
  setAnswerSuggestions([]);
307
339
  setGeneralSuggestions([]);
308
340
  handleBackToChat();
@@ -315,6 +347,9 @@ export const FloatingChat = ({
315
347
  hideEnviveWatermark={!showEnviveLogo}
316
348
  onFocus={handleInputQueryFocus}
317
349
  parentWidget={WidgetInteractionComponent.FLOATING_CHAT}
350
+ voiceInputEnabled={voiceInputEnabled}
351
+ onTranscriptionStarted={handleTranscriptionStarted}
352
+ onTranscriptionCompleted={handleTranscriptionCompleted}
318
353
  />
319
354
  );
320
355
 
@@ -373,6 +408,7 @@ export const FloatingChat = ({
373
408
  if (suggestion) {
374
409
  onSuggestionClicked(suggestion, ChatElementDisplayLocationV3.FLOATING_CHAT_PROMPT_BUTTON);
375
410
  }
411
+ setListeningToSpeech('abort');
376
412
  setAnswerSuggestions([]);
377
413
  setGeneralSuggestions([]);
378
414
  }}
@@ -52,7 +52,7 @@ export const SlideChatContent = ({
52
52
  );
53
53
 
54
54
  return (
55
- <div className="envive-tw-relative envive-tw-min-h-[200px] envive-tw-w-full envive-tw-overflow-hidden">
55
+ <div className="envive-tw-relative envive-tw-w-full envive-tw-overflow-hidden">
56
56
  <AnimatePresence
57
57
  initial={false}
58
58
  mode="wait"
@@ -1,4 +1,4 @@
1
- import { useEffect, useState } from 'react';
1
+ import { useLayoutEffect, useState } from 'react';
2
2
  import { Suggestion } from '@envive-ai/react-hooks/application/models';
3
3
 
4
4
  export interface UseChatSuggestionsProps {
@@ -26,17 +26,13 @@ export const useChatSuggestions = ({
26
26
  const showAnswerSuggestions =
27
27
  answerSuggestions.length > 0 && !isPendingResponse && !isResponseStreaming;
28
28
 
29
- useEffect(() => {
30
- if (suggestions.length > 0) {
31
- setAnswerSuggestions(
32
- suggestions.filter(suggestion => suggestion.isAnswer).map(suggestion => suggestion.content),
33
- );
34
- setGeneralSuggestions(
35
- suggestions
36
- .filter(suggestion => !suggestion.isAnswer)
37
- .map(suggestion => suggestion.content),
38
- );
39
- }
29
+ useLayoutEffect(() => {
30
+ setAnswerSuggestions(
31
+ suggestions.filter(suggestion => suggestion.isAnswer).map(suggestion => suggestion.content),
32
+ );
33
+ setGeneralSuggestions(
34
+ suggestions.filter(suggestion => !suggestion.isAnswer).map(suggestion => suggestion.content),
35
+ );
40
36
  }, [suggestions]);
41
37
 
42
38
  return {
@@ -1,4 +1,5 @@
1
1
  import { ChatElementDisplayLocationV3 } from '@envive-ai/react-hooks/application/models';
2
+ import { listeningToSpeechAtom } from '@envive-ai/react-hooks/atoms/chat';
2
3
  import { EnviveMetricsEventName } from '@envive-ai/react-hooks/contexts/amplitudeContext';
3
4
  import { HardcopyResponse } from '@envive-ai/react-hooks/contexts/hardcopyContext';
4
5
  import { useSalesAgent } from '@envive-ai/react-hooks/contexts/salesAgentContext';
@@ -8,17 +9,23 @@ import {
8
9
  WidgetInteractionComponent,
9
10
  WidgetInteractionType,
10
11
  } from '@envive-ai/react-hooks/hooks/WidgetInteraction/types';
11
- import { useRef, useState } from 'react';
12
+ import { useSetAtom } from 'jotai';
13
+ import { useCallback, useRef, useState } from 'react';
12
14
  import { ChatFooter } from '../ChatFooter';
13
15
  import { Disclaimer } from '../Disclaimer';
14
16
  import { FloatingChatComponents } from '../FloatingChat/components';
17
+ import {
18
+ NUM_COLUMNS_FPSA,
19
+ NUM_COLUMNS_MOBILE,
20
+ ResultsGridColumnCount,
21
+ } from '../FloatingChat/components/ResultsGridView';
15
22
  import { useChatSuggestions } from '../FloatingChat/hooks/useChatSuggestions';
16
23
  import { useProductResultsView } from '../FloatingChat/hooks/useProductResultsView';
17
24
  import { useScrollToBottom } from '../FloatingChat/hooks/useScrollToBottom';
18
25
  import { trackProductCardClicked } from '../FloatingChat/utils/trackProductCardInteraction';
19
- import { SalesAgentProductCardProps } from '../SalesAgentProductCard/types/types';
20
26
  import { PromptButtonVariant } from '../PromptButton';
21
27
  import { PromptCarousel, PromptCarouselRows, usePromptCarouselAnalytics } from '../PromptCarousel';
28
+ import { SalesAgentProductCardProps } from '../SalesAgentProductCard/types/types';
22
29
  import { Theme } from '../Tokens';
23
30
  import { resolveTheme } from '../utils/resolveTheme';
24
31
  import { SparkleIconColor, WelcomeMessage } from '../WelcomeMessage';
@@ -27,11 +34,6 @@ import { useGetFooterStyles } from './hooks/useGetFooterStyles';
27
34
  import { useGetMessagesStyles } from './hooks/useGetMessagesStyles';
28
35
  import { useGetScrollContentStyles } from './hooks/useGetScrollContentStyles';
29
36
  import { useIsMobile } from './hooks/useIsMobile';
30
- import {
31
- NUM_COLUMNS_FPSA,
32
- NUM_COLUMNS_MOBILE,
33
- ResultsGridColumnCount,
34
- } from '../FloatingChat/components/ResultsGridView';
35
37
 
36
38
  interface FullPageSalesAgentProps {
37
39
  theme?: Theme;
@@ -40,6 +42,7 @@ interface FullPageSalesAgentProps {
40
42
  hardcopyContent: HardcopyResponse;
41
43
  headerContainer?: string;
42
44
  autoHeight?: boolean;
45
+ voiceInputEnabled?: boolean;
43
46
  }
44
47
 
45
48
  export const FullPageSalesAgent = ({
@@ -49,6 +52,7 @@ export const FullPageSalesAgent = ({
49
52
  hardcopyContent,
50
53
  headerContainer,
51
54
  autoHeight,
55
+ voiceInputEnabled,
52
56
  }: FullPageSalesAgentProps) => {
53
57
  const resolvedTheme = resolveTheme(theme);
54
58
  const salesAgentData = useSalesAgent(WidgetInteractionComponent.FULL_PAGE_SALES_AGENT);
@@ -61,6 +65,7 @@ export const FullPageSalesAgent = ({
61
65
  const { trackWidgetInteraction } = useWidgetInteraction();
62
66
  const { onDrag, onHover, onMouseDown, onMouseUp, onTouchStart, onTouchEnd } =
63
67
  usePromptCarouselAnalytics(WidgetInteractionComponent.FULL_PAGE_SALES_AGENT, text => text);
68
+ const setListeningToSpeech = useSetAtom(listeningToSpeechAtom);
64
69
 
65
70
  const {
66
71
  welcomeMessageIconColor,
@@ -153,6 +158,32 @@ export const FullPageSalesAgent = ({
153
158
  );
154
159
  };
155
160
 
161
+ const handleTranscriptionStarted = useCallback(() => {
162
+ trackWidgetInteraction({
163
+ eventName: EnviveMetricsEventName.WidgetInteraction,
164
+ trigger: {
165
+ widget: WidgetInteractionComponent.FULL_PAGE_SALES_AGENT,
166
+ widget_interaction: WidgetInteractionType.VOICE_TRANSCRIPTION_STARTED,
167
+ },
168
+ });
169
+ }, [trackWidgetInteraction]);
170
+
171
+ const handleTranscriptionCompleted = useCallback(
172
+ (transcript: string) => {
173
+ trackWidgetInteraction({
174
+ eventName: EnviveMetricsEventName.WidgetInteraction,
175
+ trigger: {
176
+ widget: WidgetInteractionComponent.FULL_PAGE_SALES_AGENT,
177
+ widget_interaction: WidgetInteractionType.VOICE_TRANSCRIPTION_COMPLETED,
178
+ widget_interaction_data: {
179
+ transcription: transcript,
180
+ },
181
+ },
182
+ });
183
+ },
184
+ [trackWidgetInteraction],
185
+ );
186
+
156
187
  const welcomeMessage = (
157
188
  <div className={messageContainerClasses}>
158
189
  <WelcomeMessage
@@ -188,6 +219,7 @@ export const FullPageSalesAgent = ({
188
219
  onSuggestionClicked(suggestion, ChatElementDisplayLocationV3.FLOATING_CHAT_PROMPT_BUTTON);
189
220
  }
190
221
 
222
+ setListeningToSpeech('abort');
191
223
  setAnswerSuggestions([]);
192
224
  setGeneralSuggestions([]);
193
225
  handleBackToChat();
@@ -205,6 +237,9 @@ export const FullPageSalesAgent = ({
205
237
  }}
206
238
  onFocus={handleInputQueryFocus}
207
239
  parentWidget={WidgetInteractionComponent.FULL_PAGE_SALES_AGENT}
240
+ voiceInputEnabled={voiceInputEnabled}
241
+ onTranscriptionStarted={handleTranscriptionStarted}
242
+ onTranscriptionCompleted={handleTranscriptionCompleted}
208
243
  />
209
244
  );
210
245
 
@@ -258,6 +293,7 @@ export const FullPageSalesAgent = ({
258
293
  if (suggestion) {
259
294
  onSuggestionClicked(suggestion, ChatElementDisplayLocationV3.FLOATING_CHAT_PROMPT_BUTTON);
260
295
  }
296
+ setListeningToSpeech('abort');
261
297
  setAnswerSuggestions([]);
262
298
  setGeneralSuggestions([]);
263
299
  }}
@@ -20,6 +20,7 @@ export const ProductCard = ({
20
20
  textTypingDuration,
21
21
  textTransition,
22
22
  loop,
23
+ voiceInputEnabled,
23
24
  onSelect,
24
25
  onDrag,
25
26
  onHover,
@@ -28,6 +29,8 @@ export const ProductCard = ({
28
29
  onTouchStart,
29
30
  onTouchEnd,
30
31
  onInputClick,
32
+ onTranscriptionStarted,
33
+ onTranscriptionCompleted,
31
34
  }: ProductCardProps) => {
32
35
  const resolvedTheme = resolveTheme(theme);
33
36
 
@@ -59,8 +62,12 @@ export const ProductCard = ({
59
62
  />
60
63
  <WidgetTextField
61
64
  theme={resolvedTheme}
65
+ minimalFrame={resolvedTheme === Theme.MINIMAL ? 'bottom-only' : 'full'}
62
66
  placeholder={placeholder}
63
67
  onClick={onInputClick}
68
+ enableVoiceInput={voiceInputEnabled}
69
+ onTranscriptionStarted={onTranscriptionStarted}
70
+ onTranscriptionCompleted={onTranscriptionCompleted}
64
71
  textColor={
65
72
  resolvedTheme === Theme.MINIMAL
66
73
  ? TypographyColor.TEXT_LIGHT
@@ -259,5 +259,38 @@ describe('ProductCard', () => {
259
259
  expect(screen.getByText('Test Product')).toBeInTheDocument();
260
260
  expect(screen.getByText('Prompt 1')).toBeInTheDocument();
261
261
  });
262
+
263
+ it('should render with voiceInputEnabled set to true', () => {
264
+ render(
265
+ <ProductCard
266
+ {...defaultProps}
267
+ voiceInputEnabled
268
+ />,
269
+ );
270
+
271
+ expect(screen.getByText('Test Product')).toBeInTheDocument();
272
+ });
273
+
274
+ it('should render with voiceInputEnabled set to false', () => {
275
+ render(
276
+ <ProductCard
277
+ {...defaultProps}
278
+ voiceInputEnabled={false}
279
+ />,
280
+ );
281
+
282
+ expect(screen.getByText('Test Product')).toBeInTheDocument();
283
+ });
284
+
285
+ it('should render with voiceInputEnabled undefined (default)', () => {
286
+ render(
287
+ <ProductCard
288
+ {...defaultProps}
289
+ voiceInputEnabled={undefined}
290
+ />,
291
+ );
292
+
293
+ expect(screen.getByText('Test Product')).toBeInTheDocument();
294
+ });
262
295
  });
263
296
  });
@@ -1,2 +1,2 @@
1
1
  export { ProductCard } from './ProductCard';
2
- export type { ProductCardProps } from './types';
2
+ export type { ProductCardProps, InputProps } from './types';
@@ -94,6 +94,12 @@ export interface InputProps {
94
94
  onInputClick: () => void;
95
95
  /** Placeholder text displayed in the input field. */
96
96
  placeholder?: string;
97
+ /** Whether to enable voice input. */
98
+ voiceInputEnabled?: boolean;
99
+ /** Callback function invoked when voice transcription starts. */
100
+ onTranscriptionStarted?: () => void;
101
+ /** Callback function invoked when voice transcription completes. */
102
+ onTranscriptionCompleted?: (transcript: string) => void;
97
103
  }
98
104
 
99
105
  /**
@@ -13,6 +13,7 @@ export const PromptButtonCarouselWithImage = ({
13
13
  alt,
14
14
  isLoading,
15
15
  hideTextField,
16
+ voiceInputEnabled,
16
17
  title,
17
18
  promptButtonsTexts,
18
19
  promptButtonType,
@@ -25,6 +26,8 @@ export const PromptButtonCarouselWithImage = ({
25
26
  handlePromptButtonTouchEnd,
26
27
  textFieldPlaceholder,
27
28
  handleTextFieldClick,
29
+ onTranscriptionStarted,
30
+ onTranscriptionCompleted,
28
31
  }: PromptButtonCarouselWithImageProps) => {
29
32
  const finalTheme = resolveTheme(theme);
30
33
 
@@ -49,6 +52,9 @@ export const PromptButtonCarouselWithImage = ({
49
52
  className={finalTheme === Theme.MINIMAL ? '!envive-tw-border-border-medium' : undefined}
50
53
  onClick={() => handleTextFieldClick(textFieldPlaceholder)}
51
54
  theme={finalTheme}
55
+ enableVoiceInput={voiceInputEnabled}
56
+ onTranscriptionStarted={onTranscriptionStarted}
57
+ onTranscriptionCompleted={onTranscriptionCompleted}
52
58
  />
53
59
  }
54
60
  image={
@@ -513,4 +513,38 @@ describe('PromptButtonCarouselWithImage', () => {
513
513
  }).not.toThrow();
514
514
  });
515
515
  });
516
+
517
+ describe('Voice input', () => {
518
+ it('should render with voiceInputEnabled set to true', () => {
519
+ setMobile(true);
520
+ render(
521
+ <PromptButtonCarouselWithImage
522
+ {...defaultProps}
523
+ voiceInputEnabled
524
+ />,
525
+ );
526
+ expect(screen.getByText('Type something...')).toBeInTheDocument();
527
+ setMobile(false);
528
+ });
529
+
530
+ it('should render with voiceInputEnabled set to false', () => {
531
+ render(
532
+ <PromptButtonCarouselWithImage
533
+ {...defaultProps}
534
+ voiceInputEnabled={false}
535
+ />,
536
+ );
537
+ expect(screen.getByText('Type something...')).toBeInTheDocument();
538
+ });
539
+
540
+ it('should render with voiceInputEnabled undefined (default)', () => {
541
+ render(
542
+ <PromptButtonCarouselWithImage
543
+ {...defaultProps}
544
+ voiceInputEnabled={undefined}
545
+ />,
546
+ );
547
+ expect(screen.getByText('Type something...')).toBeInTheDocument();
548
+ });
549
+ });
516
550
  });
@@ -59,6 +59,10 @@ export type PromptButtonCarouselWithImageProps = {
59
59
  * Whether to hide the text field.
60
60
  */
61
61
  hideTextField?: boolean;
62
+ /**
63
+ * Whether to enable voice input.
64
+ */
65
+ voiceInputEnabled?: boolean;
62
66
  /**
63
67
  * Callback function invoked when a prompt button is clicked.
64
68
  * Receives the button's text as a parameter.
@@ -97,4 +101,12 @@ export type PromptButtonCarouselWithImageProps = {
97
101
  * Receives the placeholder text as a parameter.
98
102
  */
99
103
  handleTextFieldClick: (text: string) => void;
104
+ /**
105
+ * Callback function invoked when voice transcription starts.
106
+ */
107
+ onTranscriptionStarted?: () => void;
108
+ /**
109
+ * Callback function invoked when voice transcription completes.
110
+ */
111
+ onTranscriptionCompleted?: (transcript: string) => void;
100
112
  };