@envive-ai/react-toolkit-v3 0.3.22 → 0.3.23
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.
- package/dist/AnimatedText/AnimatedText.d.cts +3 -3
- package/dist/AnimatedText/AnimatedText.d.ts +3 -3
- package/dist/CSSVariablesEditor/CssVariablesEditorComponent.d.cts +2 -2
- package/dist/CSSVariablesEditor/CssVariablesEditorComponent.d.ts +2 -2
- package/dist/CSSVariablesEditor/hooks/useGetCssVariablesOptions.cjs +1 -1
- package/dist/CSSVariablesEditor/hooks/useGetCssVariablesOptions.js +1 -1
- package/dist/CSSVariablesEditor/hooks/useGetCurrentMerchantColors.cjs +1 -1
- package/dist/CSSVariablesEditor/hooks/useGetCurrentMerchantColors.js +1 -1
- package/dist/CSSVariablesEditor/hooks/useGetDefaultCssVariables.cjs +4 -4
- package/dist/CSSVariablesEditor/hooks/useGetDefaultCssVariables.js +4 -4
- package/dist/CSSVariablesEditor/hooks/useHandleUpdateCssVars.cjs +3 -3
- package/dist/CSSVariablesEditor/hooks/useHandleUpdateCssVars.js +3 -3
- package/dist/Carousel/Carousel.d.cts +2 -2
- package/dist/Carousel/Carousel.d.ts +2 -2
- package/dist/Carousel/components/Badge.cjs +1 -1
- package/dist/Carousel/components/Badge.js +1 -1
- package/dist/Carousel/components/Container.cjs +1 -1
- package/dist/Carousel/components/Container.js +1 -1
- package/dist/ChatFooter/ChatFooter.cjs +7 -3
- package/dist/ChatFooter/ChatFooter.d.cts +7 -3
- package/dist/ChatFooter/ChatFooter.d.ts +7 -3
- package/dist/ChatFooter/ChatFooter.js +7 -3
- package/dist/ChatFooter/components/Layout.cjs +1 -1
- package/dist/ChatFooter/components/Layout.js +1 -1
- package/dist/ChatFooter/components/index.d.cts +10 -6
- package/dist/ChatFooter/components/index.d.ts +10 -6
- package/dist/ChatFooter/types/types.d.cts +16 -0
- package/dist/ChatFooter/types/types.d.ts +16 -0
- package/dist/ChatHeader/ChatHeader.cjs +2 -1
- package/dist/ChatHeader/ChatHeader.d.cts +2 -2
- package/dist/ChatHeader/ChatHeader.d.ts +2 -2
- package/dist/ChatHeader/ChatHeader.js +2 -1
- package/dist/ChatHeader/components/Handle.cjs +2 -2
- package/dist/ChatHeader/components/Handle.js +2 -2
- package/dist/ChatHeader/hooks/useGetHandleProperties.cjs +4 -2
- package/dist/ChatHeader/hooks/useGetHandleProperties.js +4 -2
- package/dist/ChatHeader/hooks/useGetLayoutProperties.cjs +1 -1
- package/dist/ChatHeader/hooks/useGetLayoutProperties.js +1 -1
- package/dist/ChatHeader/hooks/useGetToggleOptionProperties.cjs +1 -1
- package/dist/ChatHeader/hooks/useGetToggleOptionProperties.js +1 -1
- package/dist/ChatPreview/ChatPreview.cjs +6 -3
- package/dist/ChatPreview/ChatPreview.d.cts +2 -2
- package/dist/ChatPreview/ChatPreview.d.ts +2 -2
- package/dist/ChatPreview/ChatPreview.js +6 -3
- package/dist/ChatPreview/index.d.cts +2 -2
- package/dist/ChatPreview/index.d.ts +2 -2
- package/dist/ChatPreview/types/types.d.cts +13 -1
- package/dist/ChatPreview/types/types.d.ts +13 -1
- package/dist/ChatPreviewComparison/ChatPreviewComparison.cjs +6 -3
- package/dist/ChatPreviewComparison/ChatPreviewComparison.d.cts +2 -2
- package/dist/ChatPreviewComparison/ChatPreviewComparison.d.ts +2 -2
- package/dist/ChatPreviewComparison/ChatPreviewComparison.js +6 -3
- package/dist/ChatPreviewComparison/components/Layout.cjs +2 -2
- package/dist/ChatPreviewComparison/components/Layout.js +2 -2
- package/dist/ChatPreviewComparison/index.d.cts +2 -2
- package/dist/ChatPreviewComparison/index.d.ts +2 -2
- package/dist/ChatPreviewComparison/types/types.d.cts +13 -1
- package/dist/ChatPreviewComparison/types/types.d.ts +13 -1
- package/dist/ChatPreviewLoading/ChatPreviewLoading.cjs +7 -2
- package/dist/ChatPreviewLoading/ChatPreviewLoading.d.cts +4 -3
- package/dist/ChatPreviewLoading/ChatPreviewLoading.d.ts +2 -1
- package/dist/ChatPreviewLoading/ChatPreviewLoading.js +7 -2
- package/dist/ChatPreviewLoading/types/types.d.cts +4 -0
- package/dist/ChatPreviewLoading/types/types.d.ts +4 -0
- package/dist/Container/Container.d.cts +174 -174
- package/dist/Container/Container.d.ts +174 -174
- package/dist/DesignTokens/DesignTokensComponent.d.cts +2 -2
- package/dist/DesignTokens/DesignTokensComponent.d.ts +2 -2
- package/dist/DesignTokens/components/FontFamily.cjs +1 -1
- package/dist/DesignTokens/components/FontFamily.js +1 -1
- package/dist/DesignTokens/components/FontSize.cjs +1 -1
- package/dist/DesignTokens/components/FontSize.js +1 -1
- package/dist/DesignTokens/components/FontWeight.cjs +1 -1
- package/dist/DesignTokens/components/FontWeight.js +1 -1
- package/dist/DesignTokens/components/LetterSpacing.cjs +1 -1
- package/dist/DesignTokens/components/LetterSpacing.js +1 -1
- package/dist/DesignTokens/components/LineHeight.cjs +1 -1
- package/dist/DesignTokens/components/LineHeight.js +1 -1
- package/dist/DesignTokens/components/Typography.cjs +1 -1
- package/dist/DesignTokens/components/Typography.js +1 -1
- package/dist/Disclaimer/components/Container.cjs +1 -1
- package/dist/Disclaimer/components/Container.js +1 -1
- package/dist/DocumentRetrievalCard/DocumentRetrievalCard.d.cts +2 -2
- package/dist/DocumentRetrievalCard/DocumentRetrievalCard.d.ts +2 -2
- package/dist/DocumentRetrievalCard/components/Image.cjs +1 -1
- package/dist/DocumentRetrievalCard/components/Image.js +1 -1
- package/dist/DocumentRetrievalCard/components/Layout.cjs +1 -1
- package/dist/DocumentRetrievalCard/components/Layout.js +1 -1
- package/dist/DocumentRetrievalCard/components/ViewArticleButton/components/Icon.cjs +1 -1
- package/dist/DocumentRetrievalCard/components/ViewArticleButton/components/Icon.js +1 -1
- package/dist/DocumentRetrievalCard/components/ViewArticleButton/components/Label.cjs +1 -1
- package/dist/DocumentRetrievalCard/components/ViewArticleButton/components/Label.js +1 -1
- package/dist/DocumentRetrievalCard/components/ViewArticleButton/components/Layout.cjs +1 -1
- package/dist/DocumentRetrievalCard/components/ViewArticleButton/components/Layout.js +1 -1
- package/dist/FloatingButton/FloatingButton.d.cts +2 -2
- package/dist/FloatingButton/FloatingButton.d.ts +2 -2
- package/dist/FloatingButton/components/Button.cjs +1 -1
- package/dist/FloatingButton/components/Button.js +1 -1
- package/dist/FloatingButton/components/Container.cjs +1 -1
- package/dist/FloatingButton/components/Container.js +1 -1
- package/dist/FloatingButton/components/Wrapper.cjs +1 -1
- package/dist/FloatingButton/components/Wrapper.js +1 -1
- package/dist/FloatingChat/FloatingChat.cjs +27 -4
- package/dist/FloatingChat/FloatingChat.d.cts +2 -2
- package/dist/FloatingChat/FloatingChat.d.ts +2 -2
- package/dist/FloatingChat/FloatingChat.js +28 -5
- package/dist/FloatingChat/components/AgentMessage.cjs +2 -2
- package/dist/FloatingChat/components/AgentMessage.js +2 -2
- package/dist/FloatingChat/components/ChatMessages.cjs +1 -1
- package/dist/FloatingChat/components/ChatMessages.js +1 -1
- package/dist/FloatingChat/components/Layout.cjs +1 -1
- package/dist/FloatingChat/components/Layout.js +1 -1
- package/dist/FloatingChat/components/ProductResultsModal.cjs +1 -1
- package/dist/FloatingChat/components/ProductResultsModal.js +1 -1
- package/dist/FloatingChat/components/ResultsGridView.cjs +1 -1
- package/dist/FloatingChat/components/ResultsGridView.js +1 -1
- package/dist/FloatingChat/components/SalesAgentBadgeContent.cjs +1 -1
- package/dist/FloatingChat/components/SalesAgentBadgeContent.js +1 -1
- package/dist/FloatingChat/hooks/useChatSuggestions.cjs +3 -5
- package/dist/FloatingChat/hooks/useChatSuggestions.js +4 -6
- package/dist/Form/Form.cjs +1 -1
- package/dist/Form/Form.js +1 -1
- package/dist/Form/components/Layout.cjs +1 -1
- package/dist/Form/components/Layout.js +1 -1
- package/dist/Form/components/SubmitButtonItem.cjs +1 -1
- package/dist/Form/components/SubmitButtonItem.js +1 -1
- package/dist/Form/components/TextFieldItem.cjs +1 -1
- package/dist/Form/components/TextFieldItem.js +1 -1
- package/dist/FullPageSalesAgent/FullPageSalesAgent.cjs +24 -2
- package/dist/FullPageSalesAgent/FullPageSalesAgent.d.cts +5 -3
- package/dist/FullPageSalesAgent/FullPageSalesAgent.d.ts +5 -3
- package/dist/FullPageSalesAgent/FullPageSalesAgent.js +25 -3
- package/dist/FullPageSalesAgent/components/Layout.cjs +1 -1
- package/dist/FullPageSalesAgent/components/Layout.js +1 -1
- package/dist/Image/Image.cjs +1 -1
- package/dist/Image/Image.d.cts +2 -2
- package/dist/Image/Image.d.ts +2 -2
- package/dist/Image/Image.js +1 -1
- package/dist/ImageGallery/ImageGallery.d.cts +2 -2
- package/dist/ImageGallery/components/Layout.cjs +1 -1
- package/dist/ImageGallery/components/Layout.js +1 -1
- package/dist/ImageGallery/utils/functions.cjs +1 -1
- package/dist/ImageGallery/utils/functions.js +1 -1
- package/dist/MarkdownProcessor/MarkdownProcessor.d.cts +2 -2
- package/dist/MarkdownProcessor/MarkdownProcessor.d.ts +2 -2
- package/dist/Message/components/Layout.cjs +1 -1
- package/dist/Message/components/Layout.js +1 -1
- package/dist/OrderLookupCard/OrderLookupCard.cjs +1 -1
- package/dist/OrderLookupCard/OrderLookupCard.js +1 -1
- package/dist/OrderLookupCard/components/Layout.cjs +1 -1
- package/dist/OrderLookupCard/components/Layout.js +1 -1
- package/dist/OrderLookupCard/components/MoreProductsOverlay.cjs +1 -1
- package/dist/OrderLookupCard/components/MoreProductsOverlay.js +1 -1
- package/dist/OrderLookupCard/components/ProductImageGridItem.cjs +1 -1
- package/dist/OrderLookupCard/components/ProductImageGridItem.js +1 -1
- package/dist/OrderLookupCard/components/ProductImageItem.cjs +1 -1
- package/dist/OrderLookupCard/components/ProductImageItem.js +1 -1
- package/dist/OrderLookupCard/components/ProductImagesGrid.cjs +1 -1
- package/dist/OrderLookupCard/components/ProductImagesGrid.js +1 -1
- package/dist/OrderLookupCard/components/StatusLabel.cjs +1 -1
- package/dist/OrderLookupCard/components/StatusLabel.js +1 -1
- package/dist/OrderLookupCard/components/TrackOrderLink.cjs +1 -1
- package/dist/OrderLookupCard/components/TrackOrderLink.js +1 -1
- package/dist/ProductCard/ProductCard.cjs +6 -2
- package/dist/ProductCard/ProductCard.d.cts +6 -3
- package/dist/ProductCard/ProductCard.d.ts +6 -3
- package/dist/ProductCard/ProductCard.js +6 -2
- package/dist/ProductCard/index.d.cts +2 -2
- package/dist/ProductCard/index.d.ts +2 -2
- package/dist/ProductCard/types/index.d.cts +7 -1
- package/dist/ProductCard/types/index.d.ts +7 -1
- package/dist/PromptButton/PromptButton.cjs +1 -1
- package/dist/PromptButton/PromptButton.d.cts +2 -2
- package/dist/PromptButton/PromptButton.d.ts +2 -2
- package/dist/PromptButton/PromptButton.js +1 -1
- package/dist/PromptButton/components/Layout.cjs +1 -1
- package/dist/PromptButton/components/Layout.js +1 -1
- package/dist/PromptButton/components/Loading.cjs +1 -1
- package/dist/PromptButton/components/Loading.js +1 -1
- package/dist/PromptButtonCarouselWithImage/PromptButtonCarouselWithImage.cjs +5 -2
- package/dist/PromptButtonCarouselWithImage/PromptButtonCarouselWithImage.d.cts +6 -3
- package/dist/PromptButtonCarouselWithImage/PromptButtonCarouselWithImage.d.ts +6 -3
- package/dist/PromptButtonCarouselWithImage/PromptButtonCarouselWithImage.js +5 -2
- package/dist/PromptButtonCarouselWithImage/components/Layout.cjs +1 -1
- package/dist/PromptButtonCarouselWithImage/components/Layout.js +1 -1
- package/dist/PromptButtonCarouselWithImage/components/Skeleton.cjs +1 -1
- package/dist/PromptButtonCarouselWithImage/components/Skeleton.js +1 -1
- package/dist/PromptButtonCarouselWithImage/types/types.d.cts +12 -0
- package/dist/PromptButtonCarouselWithImage/types/types.d.ts +12 -0
- package/dist/PromptCarousel/PromptCarousel.cjs +1 -1
- package/dist/PromptCarousel/PromptCarousel.d.cts +2 -2
- package/dist/PromptCarousel/PromptCarousel.d.ts +2 -2
- package/dist/PromptCarousel/PromptCarousel.js +1 -1
- package/dist/ReviewCard/ReviewCard.d.cts +2 -2
- package/dist/ReviewCard/ReviewCard.d.ts +2 -2
- package/dist/ReviewCard/components/Container.cjs +1 -1
- package/dist/ReviewCard/components/Container.js +1 -1
- package/dist/ReviewCard/components/Rating.cjs +1 -2
- package/dist/ReviewCard/components/Rating.js +1 -2
- package/dist/ReviewCard/components/ReadMoreButton.cjs +1 -1
- package/dist/ReviewCard/components/ReadMoreButton.js +1 -1
- package/dist/ReviewCard/components/index.d.cts +6 -6
- package/dist/ReviewCard/components/index.d.ts +6 -6
- package/dist/SalesAgentProductCard/SalesAgentProductCard.d.cts +2 -2
- package/dist/SalesAgentProductCard/SalesAgentProductCard.d.ts +2 -2
- package/dist/SalesAgentProductCard/components/Container.cjs +1 -1
- package/dist/SalesAgentProductCard/components/Container.js +1 -1
- package/dist/SalesAgentProductCard/components/ProductImage.cjs +1 -1
- package/dist/SalesAgentProductCard/components/ProductImage.js +1 -1
- package/dist/SalesAgentProductCard/components/ProductName.cjs +1 -1
- package/dist/SalesAgentProductCard/components/ProductName.js +1 -1
- package/dist/SalesAgentProductCard/components/index.d.cts +8 -8
- package/dist/SalesAgentProductCard/components/index.d.ts +8 -8
- package/dist/SocialProof/SocialProof.cjs +6 -3
- package/dist/SocialProof/SocialProof.d.cts +2 -2
- package/dist/SocialProof/SocialProof.d.ts +2 -2
- package/dist/SocialProof/SocialProof.js +6 -3
- package/dist/SocialProof/components/Headline.cjs +1 -1
- package/dist/SocialProof/components/Headline.js +1 -1
- package/dist/SocialProof/components/LayoutFourHorizontal.cjs +1 -1
- package/dist/SocialProof/components/LayoutFourHorizontal.js +1 -1
- package/dist/SocialProof/components/Textfield.cjs +5 -2
- package/dist/SocialProof/components/Textfield.js +5 -2
- package/dist/SocialProof/index.d.cts +2 -2
- package/dist/SocialProof/index.d.ts +2 -2
- package/dist/SocialProof/types/types.d.cts +13 -1
- package/dist/SocialProof/types/types.d.ts +13 -1
- package/dist/SparkleAnimation/SparkleAnimation.d.cts +2 -2
- package/dist/SparkleAnimation/SparkleAnimation.d.ts +2 -2
- package/dist/Stack/Stack.d.cts +2 -2
- package/dist/Stack/Stack.d.ts +2 -2
- package/dist/TextField/TextField.cjs +35 -3
- package/dist/TextField/TextField.d.cts +5 -1
- package/dist/TextField/TextField.d.ts +5 -1
- package/dist/TextField/TextField.js +35 -3
- package/dist/TextField/components/Input.cjs +1 -1
- package/dist/TextField/components/Input.js +1 -1
- package/dist/TextField/components/Layout.cjs +11 -8
- package/dist/TextField/components/Layout.js +11 -8
- package/dist/TextField/components/SendIcon.cjs +1 -1
- package/dist/TextField/components/SendIcon.js +1 -1
- package/dist/TextField/components/VoiceInputButton.cjs +45 -0
- package/dist/TextField/components/VoiceInputButton.js +39 -0
- package/dist/TextField/components/index.cjs +3 -1
- package/dist/TextField/components/index.js +3 -1
- package/dist/TextField/hooks/useGetMicButtonContainerProperties.cjs +20 -0
- package/dist/TextField/hooks/useGetMicButtonContainerProperties.js +19 -0
- package/dist/TextField/hooks/useGetSkeletonProperties.cjs +1 -1
- package/dist/TextField/hooks/useGetSkeletonProperties.js +1 -1
- package/dist/TextField/hooks/useVoiceInput.cjs +59 -0
- package/dist/TextField/hooks/useVoiceInput.js +57 -0
- package/dist/TextField/types/index.d.cts +11 -0
- package/dist/TextField/types/index.d.ts +11 -0
- package/dist/TextField/utils/getLayoutStateProperties.cjs +9 -1
- package/dist/TextField/utils/getLayoutStateProperties.js +8 -1
- package/dist/Title/Title.cjs +1 -1
- package/dist/Title/Title.js +1 -1
- package/dist/Title/components/Layout.cjs +1 -1
- package/dist/Title/components/Layout.js +1 -1
- package/dist/TitledPromptCarousel/TitledPromptCarousel.cjs +1 -1
- package/dist/TitledPromptCarousel/TitledPromptCarousel.d.cts +2 -2
- package/dist/TitledPromptCarousel/TitledPromptCarousel.d.ts +2 -2
- package/dist/TitledPromptCarousel/TitledPromptCarousel.js +1 -1
- package/dist/Tokens/index.cjs +6 -6
- package/dist/Tokens/index.js +6 -6
- package/dist/TypingAnimation/TypingAnimation.cjs +7 -3
- package/dist/TypingAnimation/TypingAnimation.d.cts +2 -2
- package/dist/TypingAnimation/TypingAnimation.d.ts +2 -2
- package/dist/TypingAnimation/TypingAnimation.js +7 -3
- package/dist/TypingAnimation/index.d.cts +2 -2
- package/dist/TypingAnimation/index.d.ts +2 -2
- package/dist/TypingAnimation/types/index.d.cts +13 -1
- package/dist/TypingAnimation/types/index.d.ts +13 -1
- package/dist/Typography/Typography.d.cts +4 -4
- package/dist/Typography/Typography.d.ts +4 -4
- package/dist/WelcomeMessage/components/Container.cjs +1 -1
- package/dist/WelcomeMessage/components/Container.js +1 -1
- package/dist/WidgetTextField/WidgetTextField.cjs +39 -7
- package/dist/WidgetTextField/WidgetTextField.d.cts +7 -3
- package/dist/WidgetTextField/WidgetTextField.d.ts +7 -3
- package/dist/WidgetTextField/WidgetTextField.js +33 -2
- package/dist/WidgetTextField/components/Container.cjs +32 -26
- package/dist/WidgetTextField/components/Container.js +32 -26
- package/dist/WidgetTextField/components/Skeleton.cjs +1 -1
- package/dist/WidgetTextField/components/Skeleton.js +1 -1
- package/dist/WidgetTextField/hooks/useGetContainerProperties.cjs +5 -3
- package/dist/WidgetTextField/hooks/useGetContainerProperties.js +5 -3
- package/dist/WidgetTextField/hooks/useGetMicWidgetButtonProperties.cjs +20 -0
- package/dist/WidgetTextField/hooks/useGetMicWidgetButtonProperties.js +19 -0
- package/dist/WidgetTextField/types/types.d.cts +21 -0
- package/dist/WidgetTextField/types/types.d.ts +21 -0
- package/dist/WidgetWrapper/WidgetWrapper.cjs +1 -1
- package/dist/WidgetWrapper/WidgetWrapper.d.cts +2 -2
- package/dist/WidgetWrapper/WidgetWrapper.d.ts +2 -2
- package/dist/WidgetWrapper/WidgetWrapper.js +1 -1
- package/dist/WidgetWrapper/hooks/useGetWrapperProperties.cjs +1 -1
- package/dist/WidgetWrapper/hooks/useGetWrapperProperties.js +1 -1
- package/dist/WidgetWrapperWithTitle/WidgetWrapperWithTitle.d.cts +2 -2
- package/dist/WidgetWrapperWithTitle/WidgetWrapperWithTitle.d.ts +2 -2
- package/dist/node_modules/jotai/esm/react.cjs +87 -0
- package/dist/node_modules/jotai/esm/react.js +88 -2
- package/dist/node_modules/jotai/esm/vanilla/internals.cjs +2 -1
- package/dist/node_modules/jotai/esm/vanilla/internals.js +1 -1
- package/dist/packages/components-v3/tokens/typography/typography.cjs +1 -1
- package/dist/packages/components-v3/tokens/typography/typography.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/utils/resolveTheme.cjs +1 -1
- package/dist/utils/resolveTheme.js +1 -1
- package/package.json +2 -1
- package/src/components/ChatFooter/ChatFooter.tsx +8 -0
- package/src/components/ChatFooter/__tests__/ChatFooter.test.tsx +43 -0
- package/src/components/ChatFooter/components/TextField.tsx +12 -0
- package/src/components/ChatFooter/types/types.ts +17 -0
- package/src/components/ChatHeader/ChatHeader.tsx +1 -0
- package/src/components/ChatHeader/components/Handle.tsx +7 -2
- package/src/components/ChatHeader/hooks/useGetHandleProperties.ts +5 -1
- package/src/components/ChatHeader/hooks/useGetToggleOptionProperties.ts +1 -1
- package/src/components/ChatHeader/types/index.ts +1 -0
- package/src/components/ChatPreview/ChatPreview.tsx +13 -2
- package/src/components/ChatPreview/__tests__/ChatPreview.test.tsx +44 -0
- package/src/components/ChatPreview/index.ts +1 -1
- package/src/components/ChatPreview/types/types.ts +13 -0
- package/src/components/ChatPreviewComparison/ChatPreviewComparison.tsx +6 -0
- package/src/components/ChatPreviewComparison/__tests__/ChatPreviewComparison.test.tsx +44 -0
- package/src/components/ChatPreviewComparison/index.ts +1 -1
- package/src/components/ChatPreviewComparison/types/types.ts +13 -0
- package/src/components/ChatPreviewLoading/ChatPreviewLoading.tsx +5 -3
- package/src/components/ChatPreviewLoading/__tests__/ChatPreviewLoading.test.tsx +40 -0
- package/src/components/ChatPreviewLoading/types/types.ts +5 -0
- package/src/components/FloatingChat/FloatingChat.tsx +38 -7
- package/src/components/FloatingChat/hooks/useChatSuggestions.ts +8 -12
- package/src/components/FullPageSalesAgent/FullPageSalesAgent.tsx +32 -1
- package/src/components/ProductCard/ProductCard.tsx +7 -0
- package/src/components/ProductCard/__tests__/ProductCard.test.tsx +33 -0
- package/src/components/ProductCard/index.ts +1 -1
- package/src/components/ProductCard/types/index.ts +6 -0
- package/src/components/PromptButtonCarouselWithImage/PromptButtonCarouselWithImage.tsx +6 -0
- package/src/components/PromptButtonCarouselWithImage/__tests__/PromptButtonCarouselWithImage.test.tsx +34 -0
- package/src/components/PromptButtonCarouselWithImage/types/types.ts +12 -0
- package/src/components/ReviewCard/components/Rating.tsx +0 -1
- package/src/components/SocialProof/SocialProof.tsx +6 -0
- package/src/components/SocialProof/__tests__/SocialProof.test.tsx +58 -0
- package/src/components/SocialProof/components/Textfield.tsx +9 -0
- package/src/components/SocialProof/index.ts +1 -1
- package/src/components/SocialProof/types/types.ts +13 -0
- package/src/components/TextField/TextField.tsx +49 -0
- package/src/components/TextField/__tests__/TextField.test.tsx +3 -3
- package/src/components/TextField/__tests__/VoiceInputButton.test.tsx +175 -0
- package/src/components/TextField/components/Layout.tsx +24 -17
- package/src/components/TextField/components/VoiceInputButton.tsx +69 -0
- package/src/components/TextField/components/index.ts +2 -0
- package/src/components/TextField/hooks/useGetMicButtonContainerProperties.ts +38 -0
- package/src/components/TextField/hooks/useGetSkeletonProperties.ts +1 -1
- package/src/components/TextField/hooks/useVoiceInput.ts +77 -0
- package/src/components/TextField/types/index.ts +11 -0
- package/src/components/TextField/utils/getLayoutStateProperties.ts +8 -0
- package/src/components/TypingAnimation/TypingAnimation.tsx +7 -0
- package/src/components/TypingAnimation/__tests__/TypingAnimation.test.tsx +47 -0
- package/src/components/TypingAnimation/index.ts +1 -1
- package/src/components/TypingAnimation/types/index.ts +14 -1
- package/src/components/WidgetTextField/WidgetTextField.tsx +47 -0
- package/src/components/WidgetTextField/__tests__/WidgetTextField.test.tsx +119 -4
- package/src/components/WidgetTextField/components/Container.tsx +40 -27
- package/src/components/WidgetTextField/hooks/useGetContainerProperties.ts +16 -4
- package/src/components/WidgetTextField/hooks/useGetMicWidgetButtonProperties.ts +38 -0
- package/src/components/WidgetTextField/types/types.ts +21 -0
- package/src/components/WidgetWrapper/hooks/useGetWrapperProperties.ts +1 -1
|
@@ -0,0 +1,77 @@
|
|
|
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(false);
|
|
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) {
|
|
53
|
+
handleStartListening();
|
|
54
|
+
setListeningToSpeech(true);
|
|
55
|
+
} else {
|
|
56
|
+
handleStopListening();
|
|
57
|
+
setListeningToSpeech(false);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
if (listeningToSpeech) {
|
|
63
|
+
handleStartListening();
|
|
64
|
+
}
|
|
65
|
+
return () => {
|
|
66
|
+
resetTranscript();
|
|
67
|
+
setListeningToSpeech(false);
|
|
68
|
+
};
|
|
69
|
+
}, []);
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
isListening: listeningToSpeech,
|
|
73
|
+
handleToggleListening,
|
|
74
|
+
handleAbortListening,
|
|
75
|
+
browserSupportsSpeechRecognition,
|
|
76
|
+
};
|
|
77
|
+
};
|
|
@@ -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(true);
|
|
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 {
|
|
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.
|
|
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.
|
|
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 } =
|
|
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
|
-
<
|
|
39
|
-
|
|
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
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
<
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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 = ({
|
|
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]:
|
|
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
|
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { Theme } from '../../../../tokens/theme/theme';
|
|
3
|
+
|
|
4
|
+
export type UseGetMicWidgetButtonPropertiesProps = {
|
|
5
|
+
theme: Theme;
|
|
6
|
+
isListening?: boolean;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type MicWidgetButtonProperties = {
|
|
10
|
+
micWidgetButtonClasses: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const useGetMicWidgetButtonProperties = ({
|
|
14
|
+
theme,
|
|
15
|
+
isListening = false,
|
|
16
|
+
}: UseGetMicWidgetButtonPropertiesProps): MicWidgetButtonProperties => {
|
|
17
|
+
const micWidgetButtonClasses = useMemo(() => {
|
|
18
|
+
const micWidgetButtonClassesMap: Record<Theme, string> = {
|
|
19
|
+
[Theme.STANDARD]:
|
|
20
|
+
'envive-tw-flex envive-tw-h-[42px] envive-tw-w-[44px] envive-tw-py-2 envive-tw-px-2 envive-tw-justify-center envive-tw-items-center envive-tw-border envive-tw-border-solid envive-tw-border-border-light envive-tw-rounded-global-custom',
|
|
21
|
+
[Theme.MODERN]:
|
|
22
|
+
'envive-tw-flex envive-tw-h-[42px] envive-tw-w-[44px] envive-tw-py-2 envive-tw-px-2 envive-tw-justify-center envive-tw-items-center envive-tw-border envive-tw-border-solid envive-tw-border-border-light envive-tw-rounded-4',
|
|
23
|
+
[Theme.MINIMAL]:
|
|
24
|
+
'envive-tw-flex envive-tw-h-[42px] envive-tw-w-[44px] envive-tw-py-2 envive-tw-px-2 envive-tw-justify-center envive-tw-items-center envive-tw-border envive-tw-border-solid envive-tw-border-border-light',
|
|
25
|
+
[Theme.GLOBAL_CUSTOM]:
|
|
26
|
+
'envive-tw-flex envive-tw-h-[42px] envive-tw-w-[44px] envive-tw-py-2 envive-tw-px-2 envive-tw-justify-center envive-tw-items-center envive-tw-border envive-tw-border-solid envive-tw-border-border-light envive-tw-rounded-global-custom',
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const baseClasses =
|
|
30
|
+
micWidgetButtonClassesMap[theme] ?? micWidgetButtonClassesMap[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 { micWidgetButtonClasses };
|
|
38
|
+
};
|