@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
@@ -0,0 +1,38 @@
1
+ import { useMemo } from 'react';
2
+ import { Theme } from '../../../../tokens/theme/theme';
3
+
4
+ export type UseGetMicButtonContainerPropertiesProps = {
5
+ theme: Theme;
6
+ isListening?: boolean;
7
+ };
8
+
9
+ export type MicButtonContainerProperties = {
10
+ micButtonContainerClasses: string;
11
+ };
12
+
13
+ export const useGetMicButtonContainerProperties = ({
14
+ theme,
15
+ isListening = false,
16
+ }: UseGetMicButtonContainerPropertiesProps): MicButtonContainerProperties => {
17
+ const micButtonContainerClasses = useMemo(() => {
18
+ const micButtonContainerClassesMap: Record<Theme, string> = {
19
+ [Theme.STANDARD]:
20
+ 'envive-tw-flex envive-tw-h-[40px] envive-tw-w-[40px] envive-tw-py-2 envive-tw-px-2 envive-tw-justify-center envive-tw-items-center envive-tw-flex-shrink-0 envive-tw-border envive-tw-border-solid envive-tw-rounded-global-custom envive-tw-border-border-light hover:envive-tw-border-border-dark',
21
+ [Theme.MODERN]:
22
+ 'envive-tw-flex envive-tw-h-[40px] envive-tw-w-[40px] envive-tw-py-2 envive-tw-px-2 envive-tw-justify-center envive-tw-items-center envive-tw-flex-shrink-0 envive-tw-border envive-tw-border-solid envive-tw-rounded-[4px] envive-tw-border-border-light hover:envive-tw-border-border-dark',
23
+ [Theme.MINIMAL]:
24
+ 'envive-tw-flex envive-tw-h-[40px] envive-tw-w-[40px] envive-tw-justify-center envive-tw-items-center envive-tw-flex-shrink-0 envive-tw-border-b envive-tw-border-solid envive-tw-border-b-border-medium hover:envive-tw-border-b-border-dark',
25
+ [Theme.GLOBAL_CUSTOM]:
26
+ 'envive-tw-flex envive-tw-h-[40px] envive-tw-w-[40px] envive-tw-py-2 envive-tw-px-2 envive-tw-justify-center envive-tw-items-center envive-tw-flex-shrink-0 envive-tw-border envive-tw-border-solid envive-tw-rounded-global-custom envive-tw-border-border-light hover:envive-tw-border-border-dark',
27
+ };
28
+
29
+ const baseClasses =
30
+ micButtonContainerClassesMap[theme] ?? micButtonContainerClassesMap[Theme.STANDARD];
31
+
32
+ return isListening
33
+ ? `${baseClasses} envive-tw-bg-[--envive-colors-text-accent]`
34
+ : `${baseClasses} envive-tw-bg-background-light`;
35
+ }, [theme, isListening]);
36
+
37
+ return { micButtonContainerClasses };
38
+ };
@@ -4,7 +4,7 @@ export const useGetSkeletonProperties = (isLoading?: boolean) => {
4
4
  const skeletonClass = useMemo(() => {
5
5
  if (!isLoading) return undefined;
6
6
 
7
- return 'envive-tw-animate-pulse';
7
+ return 'envive-tw-animate-pulse envive-tw-h-[40px]';
8
8
  }, [isLoading]);
9
9
 
10
10
  return { skeletonClass };
@@ -0,0 +1,75 @@
1
+ import { listeningToSpeechAtom } from '@envive-ai/react-hooks/atoms/chat';
2
+ import { useAtom } from 'jotai';
3
+ import { useEffect } from 'react';
4
+ import SpeechRecognition, { useSpeechRecognition } from 'react-speech-recognition';
5
+
6
+ export type UseVoiceInputProps = {
7
+ onTranscriptionStarted?: () => void;
8
+ onTranscriptionCompleted?: (transcript: string) => void;
9
+ disabled?: boolean;
10
+ };
11
+
12
+ export type UseVoiceInputReturn = {
13
+ isListening: boolean;
14
+ handleToggleListening: () => void;
15
+ handleAbortListening: () => void;
16
+ browserSupportsSpeechRecognition: boolean;
17
+ };
18
+
19
+ export const useVoiceInput = ({
20
+ onTranscriptionCompleted,
21
+ onTranscriptionStarted,
22
+ disabled = false,
23
+ }: UseVoiceInputProps): UseVoiceInputReturn => {
24
+ const [listeningToSpeech, setListeningToSpeech] = useAtom(listeningToSpeechAtom);
25
+ const { transcript, browserSupportsSpeechRecognition, resetTranscript, isMicrophoneAvailable } =
26
+ useSpeechRecognition();
27
+
28
+ const handleStartListening = async () => {
29
+ try {
30
+ resetTranscript();
31
+ await SpeechRecognition.startListening({ continuous: true, language: 'en-US' });
32
+ onTranscriptionStarted?.();
33
+ } catch (error) {
34
+ console.log('Microphone permission denied or error:', error);
35
+ setListeningToSpeech('abort');
36
+ }
37
+ };
38
+
39
+ const handleStopListening = async () => {
40
+ await SpeechRecognition.stopListening();
41
+ onTranscriptionCompleted?.(transcript);
42
+ };
43
+
44
+ const handleAbortListening = async () => {
45
+ await SpeechRecognition.abortListening();
46
+ resetTranscript();
47
+ };
48
+
49
+ const handleToggleListening = () => {
50
+ if (disabled || !isMicrophoneAvailable || !browserSupportsSpeechRecognition) return;
51
+
52
+ if (listeningToSpeech !== 'start') {
53
+ setListeningToSpeech('start');
54
+ } else {
55
+ setListeningToSpeech('stop');
56
+ }
57
+ };
58
+
59
+ useEffect(() => {
60
+ if (listeningToSpeech === 'start') {
61
+ handleStartListening();
62
+ } else if (listeningToSpeech === 'stop') {
63
+ handleStopListening();
64
+ } else if (listeningToSpeech === 'abort') {
65
+ handleAbortListening();
66
+ }
67
+ }, [listeningToSpeech]);
68
+
69
+ return {
70
+ isListening: listeningToSpeech === 'start',
71
+ handleToggleListening,
72
+ handleAbortListening,
73
+ browserSupportsSpeechRecognition,
74
+ };
75
+ };
@@ -34,6 +34,10 @@ export type TextFieldProps = {
34
34
  * Additional class names appended to the computed classes.
35
35
  */
36
36
  className?: string;
37
+ /**
38
+ * Additional class names applied directly to the input element (e.g. placeholder styling).
39
+ */
40
+ inputClassName?: string;
37
41
  /**
38
42
  * Inline styles forwarded to the rendered element.
39
43
  */
@@ -43,4 +47,11 @@ export type TextFieldProps = {
43
47
  * @default false
44
48
  */
45
49
  isLoading?: boolean;
50
+ /**
51
+ * Enable voice input button
52
+ * @default false
53
+ */
54
+ enableVoiceInput?: boolean;
55
+ onTranscriptionStarted?: () => void;
56
+ onTranscriptionCompleted?: (transcript: string) => void;
46
57
  };
@@ -1,12 +1,20 @@
1
+ import classNames from 'classnames';
2
+ import { Theme } from 'tokens/theme/theme';
3
+
1
4
  /**
2
5
  * Calculates state properties based on the layout state.
3
6
  */
4
7
  export const getLayoutStateProperties = (
8
+ theme: Theme,
5
9
  hasValue: boolean,
6
10
  isFocused: boolean,
7
11
  disabled: boolean,
8
12
  ) => {
9
13
  return {
14
+ containerClasses: classNames({
15
+ 'envive-tw-gap-4': theme !== Theme.MINIMAL,
16
+ 'envive-tw-flex': true,
17
+ }),
10
18
  isActive: (hasValue || isFocused) && !disabled,
11
19
  shouldShowFocus: isFocused && !disabled,
12
20
  shouldShowHover: !disabled,
@@ -29,6 +29,7 @@ export const TypingAnimation = ({
29
29
  textFieldAriaLabel,
30
30
  logoSrc,
31
31
  hideLogo,
32
+ voiceInputEnabled,
32
33
  } = widgetContentProps || {};
33
34
 
34
35
  const {
@@ -50,6 +51,8 @@ export const TypingAnimation = ({
50
51
  handleButtonTouchStart,
51
52
  handleButtonTouchEnd,
52
53
  handleTextFieldClick,
54
+ onTranscriptionStarted,
55
+ onTranscriptionCompleted,
53
56
  } = widgetEventProps || {};
54
57
  const typographyVariant = useGetTypographyVariant(theme);
55
58
  const { measuringRef, minHeight } = useAnimatedTextMinHeight(animatedTextSequence ?? []);
@@ -179,6 +182,10 @@ export const TypingAnimation = ({
179
182
  theme={theme}
180
183
  isLoading={isLoading}
181
184
  className="envive-tw-mt-2 envive-tw-overflow-hidden envive-tw-text-ellipsis envive-tw-whitespace-nowrap"
185
+ voiceInputClassName="envive-tw-mt-2"
186
+ enableVoiceInput={voiceInputEnabled}
187
+ onTranscriptionStarted={onTranscriptionStarted}
188
+ onTranscriptionCompleted={onTranscriptionCompleted}
182
189
  />
183
190
  )}
184
191
  </Stack>
@@ -326,4 +326,51 @@ describe('TypingAnimation', () => {
326
326
  expect(handleButtonClick).toHaveBeenNthCalledWith(3, mockPromptButtonTexts[2]);
327
327
  });
328
328
  });
329
+
330
+ describe('Voice input', () => {
331
+ it('should render with voiceInputEnabled set to true', () => {
332
+ render(
333
+ <TypingAnimation
334
+ {...defaultProps}
335
+ widgetContentProps={{
336
+ ...defaultProps.widgetContentProps,
337
+ voiceInputEnabled: true,
338
+ hintText: 'Type something...',
339
+ }}
340
+ widgetStyleProps={{ showTextField: true }}
341
+ />,
342
+ );
343
+ expect(screen.getByText('Type something...')).toBeInTheDocument();
344
+ });
345
+
346
+ it('should render with voiceInputEnabled set to false', () => {
347
+ render(
348
+ <TypingAnimation
349
+ {...defaultProps}
350
+ widgetContentProps={{
351
+ ...defaultProps.widgetContentProps,
352
+ voiceInputEnabled: false,
353
+ hintText: 'Type something...',
354
+ }}
355
+ widgetStyleProps={{ showTextField: true }}
356
+ />,
357
+ );
358
+ expect(screen.getByText('Type something...')).toBeInTheDocument();
359
+ });
360
+
361
+ it('should render with voiceInputEnabled undefined (default)', () => {
362
+ render(
363
+ <TypingAnimation
364
+ {...defaultProps}
365
+ widgetContentProps={{
366
+ ...defaultProps.widgetContentProps,
367
+ voiceInputEnabled: undefined,
368
+ hintText: 'Type something...',
369
+ }}
370
+ widgetStyleProps={{ showTextField: true }}
371
+ />,
372
+ );
373
+ expect(screen.getByText('Type something...')).toBeInTheDocument();
374
+ });
375
+ });
329
376
  });
@@ -1,2 +1,2 @@
1
1
  export { TypingAnimation } from './TypingAnimation';
2
- export type { TypingAnimationProps } from './types';
2
+ export type { TypingAnimationProps, WidgetEventProps } from './types';
@@ -1,7 +1,7 @@
1
- import { WidgetWrapperVariant } from '../../WidgetWrapper';
2
1
  import { PromptButtonVariant } from '../../PromptButton/types';
3
2
  import { PromptCarouselRows } from '../../PromptCarousel/types/types';
4
3
  import { Theme } from '../../Tokens';
4
+ import { WidgetWrapperVariant } from '../../WidgetWrapper';
5
5
 
6
6
  /**
7
7
  * Base props for the TypingAnimation component container.
@@ -73,6 +73,11 @@ export type WidgetContentProps = {
73
73
  * When `true`, hides the logo in the title even if logoSrc is provided.
74
74
  */
75
75
  hideLogo?: boolean;
76
+
77
+ /**
78
+ * Whether to enable voice input.
79
+ */
80
+ voiceInputEnabled?: boolean;
76
81
  };
77
82
 
78
83
  /**
@@ -166,6 +171,14 @@ export type WidgetEventProps = {
166
171
  * Callback function invoked when the TextField is clicked.
167
172
  */
168
173
  handleTextFieldClick?: () => void;
174
+ /**
175
+ * Callback function invoked when voice transcription starts.
176
+ */
177
+ onTranscriptionStarted?: () => void;
178
+ /**
179
+ * Callback function invoked when voice transcription completes.
180
+ */
181
+ onTranscriptionCompleted?: (transcript: string) => void;
169
182
  };
170
183
 
171
184
  /**
@@ -1,7 +1,14 @@
1
+ import { listeningToSpeechAtom } from '@envive-ai/react-hooks/atoms/chat';
2
+ import classNames from 'classnames';
3
+ import { useSetAtom } from 'jotai';
1
4
  import { Theme } from '../../../tokens/theme/theme';
5
+ import { TextFieldComponents } from '../TextField/components';
6
+ import { useGetSkeletonProperties } from '../TextField/hooks/useGetSkeletonProperties';
7
+ import { useVoiceInput } from '../TextField/hooks/useVoiceInput';
2
8
  import { TypographyColor } from '../Typography/types';
3
9
  import { resolveTheme } from '../utils/resolveTheme';
4
10
  import { WidgetTextFieldComponents } from './components';
11
+ import { useGetMicWidgetButtonProperties } from './hooks/useGetMicWidgetButtonProperties';
5
12
  import { IconVariant, type WidgetTextFieldProps } from './types/types';
6
13
 
7
14
  export const WidgetTextField = ({
@@ -9,7 +16,9 @@ export const WidgetTextField = ({
9
16
  testId,
10
17
  style,
11
18
  className,
19
+ voiceInputClassName,
12
20
  theme = Theme.GLOBAL_CUSTOM,
21
+ minimalFrame = 'full',
13
22
  iconVariant = IconVariant.DEFAULT,
14
23
  textColor = TypographyColor.TEXT_SECONDARY,
15
24
  placeholder,
@@ -17,13 +26,49 @@ export const WidgetTextField = ({
17
26
  disabled,
18
27
  isLoading,
19
28
  onClick,
29
+ enableVoiceInput = false,
30
+ onTranscriptionStarted,
20
31
  }: WidgetTextFieldProps) => {
21
32
  const resolvedTheme = resolveTheme(theme);
33
+ const setListeningToSpeech = useSetAtom(listeningToSpeechAtom);
34
+ const { skeletonClass } = useGetSkeletonProperties(isLoading);
35
+
36
+ const { browserSupportsSpeechRecognition } = useVoiceInput({});
37
+
38
+ const { micWidgetButtonClasses } = useGetMicWidgetButtonProperties({
39
+ theme: resolvedTheme,
40
+ isListening: false,
41
+ });
42
+
43
+ const voiceInputButtonClassName = classNames(
44
+ micWidgetButtonClasses,
45
+ skeletonClass,
46
+ voiceInputClassName,
47
+ );
22
48
 
23
49
  if (isLoading) {
24
50
  return <WidgetTextFieldComponents.Skeleton theme={resolvedTheme} />;
25
51
  }
26
52
 
53
+ const handleToggleListening = () => {
54
+ setListeningToSpeech('start');
55
+ onTranscriptionStarted?.();
56
+ onClick();
57
+ };
58
+
59
+ const voiceInputButton =
60
+ enableVoiceInput && browserSupportsSpeechRecognition ? (
61
+ <TextFieldComponents.VoiceInputButton
62
+ theme={resolvedTheme}
63
+ isListening={false}
64
+ onToggleListening={disabled ? undefined : handleToggleListening}
65
+ ariaLabel={ariaLabel}
66
+ isLoading={isLoading}
67
+ disabled={disabled}
68
+ className={voiceInputButtonClassName}
69
+ />
70
+ ) : null;
71
+
27
72
  return (
28
73
  <WidgetTextFieldComponents.Container
29
74
  onClick={disabled ? undefined : onClick}
@@ -32,6 +77,7 @@ export const WidgetTextField = ({
32
77
  style={style}
33
78
  className={className}
34
79
  theme={resolvedTheme}
80
+ minimalFrame={minimalFrame}
35
81
  disabled={disabled}
36
82
  ariaLabel={ariaLabel}
37
83
  icon={
@@ -47,6 +93,7 @@ export const WidgetTextField = ({
47
93
  textColor={textColor}
48
94
  />
49
95
  }
96
+ voiceInputButton={voiceInputButton}
50
97
  />
51
98
  );
52
99
  };
@@ -1,11 +1,37 @@
1
1
  import '@testing-library/jest-dom';
2
- import { describe, expect, it, vi } from 'vitest';
3
2
  import { fireEvent, render, screen } from '@testing-library/react';
4
- import { WidgetTextField } from '../WidgetTextField';
3
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
5
4
  import { Theme } from '../../../../tokens/theme/theme';
6
5
  import { IconVariant } from '../types/types';
6
+ import { WidgetTextField } from '../WidgetTextField';
7
+
8
+ const { mockStartListening, mockStopListening, mockAbortListening, mockResetTranscript } =
9
+ vi.hoisted(() => ({
10
+ mockStartListening: vi.fn(() => Promise.resolve()),
11
+ mockStopListening: vi.fn(() => Promise.resolve()),
12
+ mockAbortListening: vi.fn(() => Promise.resolve()),
13
+ mockResetTranscript: vi.fn(),
14
+ }));
15
+
16
+ vi.mock('react-speech-recognition', () => ({
17
+ default: {
18
+ startListening: mockStartListening,
19
+ stopListening: mockStopListening,
20
+ abortListening: mockAbortListening,
21
+ },
22
+ useSpeechRecognition: vi.fn(() => ({
23
+ transcript: '',
24
+ browserSupportsSpeechRecognition: true,
25
+ resetTranscript: mockResetTranscript,
26
+ })),
27
+ }));
7
28
 
8
29
  describe('WidgetTextField', () => {
30
+ beforeEach(() => {
31
+ vi.clearAllMocks();
32
+ mockStartListening.mockImplementation(() => Promise.resolve());
33
+ });
34
+
9
35
  describe('Basic rendering', () => {
10
36
  it('should render with placeholder text', () => {
11
37
  render(
@@ -59,7 +85,7 @@ describe('WidgetTextField', () => {
59
85
  className="custom-class"
60
86
  />,
61
87
  );
62
- const element = container.firstChild as HTMLElement;
88
+ const element = container.querySelector('.envive-tw-w-full') as HTMLElement;
63
89
  expect(element).toHaveClass('custom-class');
64
90
  });
65
91
 
@@ -71,7 +97,7 @@ describe('WidgetTextField', () => {
71
97
  style={{ marginTop: '20px' }}
72
98
  />,
73
99
  );
74
- const element = container.firstChild as HTMLElement;
100
+ const element = container.querySelector('.envive-tw-w-full') as HTMLElement;
75
101
  expect(element).toHaveStyle({ marginTop: '20px' });
76
102
  });
77
103
  });
@@ -382,4 +408,93 @@ describe('WidgetTextField', () => {
382
408
  expect(svg).toBeInTheDocument();
383
409
  });
384
410
  });
411
+
412
+ describe('Voice input button', () => {
413
+ it('should render voice input button when enableVoiceInput is true', () => {
414
+ const { container } = render(
415
+ <WidgetTextField
416
+ placeholder="Test"
417
+ theme={Theme.STANDARD}
418
+ enableVoiceInput
419
+ />,
420
+ );
421
+ const voiceButton = container.querySelector('button');
422
+ expect(voiceButton).toBeInTheDocument();
423
+ });
424
+
425
+ it('should not render voice input button when enableVoiceInput is false', () => {
426
+ const { container } = render(
427
+ <WidgetTextField
428
+ placeholder="Test"
429
+ theme={Theme.STANDARD}
430
+ enableVoiceInput={false}
431
+ />,
432
+ );
433
+ const voiceButton = container.querySelector('button');
434
+ expect(voiceButton).not.toBeInTheDocument();
435
+ });
436
+
437
+ it('should not render voice input button when isLoading is true', () => {
438
+ const { container } = render(
439
+ <WidgetTextField
440
+ placeholder="Test"
441
+ theme={Theme.STANDARD}
442
+ enableVoiceInput
443
+ isLoading
444
+ />,
445
+ );
446
+ const voiceButton = container.querySelector('button');
447
+ expect(voiceButton).not.toBeInTheDocument();
448
+ });
449
+
450
+ it('should disable voice input button when disabled', () => {
451
+ const { container } = render(
452
+ <WidgetTextField
453
+ placeholder="Test"
454
+ theme={Theme.STANDARD}
455
+ enableVoiceInput
456
+ disabled
457
+ />,
458
+ );
459
+ const voiceButton = container.querySelector('button') as HTMLButtonElement;
460
+ expect(voiceButton).toBeDisabled();
461
+ });
462
+
463
+ it('should apply skeleton class when isLoading', () => {
464
+ const { container } = render(
465
+ <WidgetTextField
466
+ placeholder="Test"
467
+ theme={Theme.STANDARD}
468
+ enableVoiceInput
469
+ isLoading
470
+ />,
471
+ );
472
+ const element = container.querySelector('[class*="envive-tw"]');
473
+ expect(element?.className).toContain('envive-tw-animate-pulse');
474
+ });
475
+
476
+ it('should apply custom className when provided', () => {
477
+ const { container } = render(
478
+ <WidgetTextField
479
+ placeholder="Test"
480
+ theme={Theme.STANDARD}
481
+ className="custom-class"
482
+ />,
483
+ );
484
+ const element = container.querySelector('.custom-class');
485
+ expect(element).toBeInTheDocument();
486
+ });
487
+
488
+ it('should apply custom style when provided', () => {
489
+ const { container } = render(
490
+ <WidgetTextField
491
+ placeholder="Test"
492
+ theme={Theme.STANDARD}
493
+ style={{ marginTop: '20px' }}
494
+ />,
495
+ );
496
+ const element = container.querySelector('[class*="envive-tw"]');
497
+ expect(element).toHaveStyle({ marginTop: '20px' });
498
+ });
499
+ });
385
500
  });
@@ -1,7 +1,7 @@
1
1
  import classNames from 'classnames';
2
- import { Stack } from '../../Stack';
3
- import { Container as ContainerComponent } from '../../Container';
4
2
  import { Theme } from '../../../../tokens/theme/theme';
3
+ import { Container as ContainerComponent } from '../../Container';
4
+ import { Stack } from '../../Stack';
5
5
  import { useGetContainerProperties } from '../hooks/useGetContainerProperties';
6
6
  import { useHandleKeyboard } from '../hooks/useHandleKeyboard';
7
7
 
@@ -11,9 +11,11 @@ type ContainerProps = {
11
11
  style?: React.CSSProperties;
12
12
  className?: string;
13
13
  theme: Theme;
14
+ minimalFrame?: 'full' | 'bottom-only';
14
15
  ariaLabel?: string;
15
16
  icon: React.ReactNode;
16
17
  text: React.ReactNode;
18
+ voiceInputButton?: React.ReactNode;
17
19
  disabled?: boolean;
18
20
  onClick?: () => void;
19
21
  };
@@ -24,43 +26,54 @@ export const Container = ({
24
26
  style,
25
27
  className,
26
28
  theme,
29
+ minimalFrame,
27
30
  ariaLabel,
28
31
  icon,
29
32
  text,
33
+ voiceInputButton,
30
34
  disabled,
31
35
  onClick,
32
36
  }: ContainerProps) => {
33
- const { baseClassName, themeContainerClassName } = useGetContainerProperties({ theme });
37
+ const { baseClassName, themeContainerClassName, containerWrapperClassName } =
38
+ useGetContainerProperties({
39
+ theme,
40
+ minimalFrame,
41
+ });
34
42
 
35
43
  const { handleKeyDown } = useHandleKeyboard({ onClick });
36
44
 
37
45
  return (
38
- <ContainerComponent
39
- id={id}
40
- testId={testId}
46
+ <div
47
+ className={containerWrapperClassName}
41
48
  style={style}
42
- className={classNames(
43
- className,
44
- baseClassName,
45
- themeContainerClassName,
46
- disabled && 'envive-tw-pointer-events-none envive-tw-opacity-50',
47
- )}
48
- aria-label={ariaLabel}
49
- fluid
50
- onClick={onClick}
51
- onKeyDown={handleKeyDown}
52
- role="button"
53
- tabIndex={onClick ? 0 : undefined}
54
49
  >
55
- <Stack
56
- direction="row"
57
- align="center"
58
- justify="between"
59
- gap="2"
50
+ <ContainerComponent
51
+ id={id}
52
+ testId={testId}
53
+ className={classNames(
54
+ className,
55
+ baseClassName,
56
+ themeContainerClassName,
57
+ disabled && 'envive-tw-pointer-events-none envive-tw-opacity-50',
58
+ )}
59
+ aria-label={ariaLabel}
60
+ fluid
61
+ onClick={onClick}
62
+ onKeyDown={handleKeyDown}
63
+ role="button"
64
+ tabIndex={onClick ? 0 : undefined}
60
65
  >
61
- <div className="envive-tw-min-w-0 envive-tw-flex-1 envive-tw-overflow-hidden">{text}</div>
62
- <div className="envive-tw-flex-shrink-0">{icon}</div>
63
- </Stack>
64
- </ContainerComponent>
66
+ <Stack
67
+ direction="row"
68
+ align="center"
69
+ justify="between"
70
+ gap="2"
71
+ >
72
+ <div className="envive-tw-min-w-0 envive-tw-flex-1 envive-tw-overflow-hidden">{text}</div>
73
+ <div className="envive-tw-flex-shrink-0">{icon}</div>
74
+ </Stack>
75
+ </ContainerComponent>
76
+ {voiceInputButton}
77
+ </div>
65
78
  );
66
79
  };
@@ -3,21 +3,33 @@ import { Theme } from '../../../../tokens/theme/theme';
3
3
 
4
4
  export type UseGetContainerPropertiesProps = {
5
5
  theme: Theme;
6
+ minimalFrame?: 'full' | 'bottom-only';
6
7
  };
7
8
 
8
- export const useGetContainerProperties = ({ theme }: UseGetContainerPropertiesProps) => {
9
+ export const useGetContainerProperties = ({
10
+ theme,
11
+ minimalFrame = 'full',
12
+ }: UseGetContainerPropertiesProps) => {
9
13
  const baseClassName =
10
14
  'envive-tw-cursor-text envive-tw-border-solid envive-tw-px-4 envive-tw-py-2';
11
15
 
12
16
  const themeContainerClassName = useMemo(() => {
17
+ const minimalBorderClass =
18
+ minimalFrame === 'bottom-only'
19
+ ? 'envive-tw-border-b-[1px] envive-tw-border-text-light'
20
+ : 'envive-tw-border-[1px] envive-tw-border-border-light';
21
+
13
22
  const themeCotainerMap = {
14
23
  [Theme.STANDARD]:
15
24
  'envive-tw-border-[1px] envive-tw-border-border-light envive-tw-rounded-global-custom',
16
25
  [Theme.MODERN]: 'envive-tw-border-[1px] envive-tw-border-border-light envive-tw-rounded-4',
17
- [Theme.MINIMAL]: 'envive-tw-border-[1px] envive-tw-border-border-light',
26
+ [Theme.MINIMAL]: minimalBorderClass,
18
27
  };
19
28
  return themeCotainerMap[theme] ?? '';
20
- }, [theme]);
29
+ }, [theme, minimalFrame]);
30
+
31
+ const containerWrapperClassName =
32
+ 'envive-tw-gap-4 envive-tw-flex envive-tw-w-full envive-tw-flex-row';
21
33
 
22
- return { baseClassName, themeContainerClassName };
34
+ return { baseClassName, themeContainerClassName, containerWrapperClassName };
23
35
  };