@envive-ai/react-toolkit-v3 0.3.21 → 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/Carousel/Carousel.cjs +1 -1
- package/dist/Carousel/Carousel.d.cts +2 -2
- package/dist/Carousel/Carousel.d.ts +2 -2
- package/dist/Carousel/Carousel.js +1 -1
- package/dist/Carousel/components/Container.cjs +2 -2
- package/dist/Carousel/components/Container.js +2 -2
- package/dist/ChatFooter/ChatFooter.cjs +7 -3
- package/dist/ChatFooter/ChatFooter.d.cts +7 -3
- package/dist/ChatFooter/ChatFooter.d.ts +5 -1
- package/dist/ChatFooter/ChatFooter.js +7 -3
- package/dist/ChatFooter/components/Layout.cjs +2 -2
- package/dist/ChatFooter/components/Layout.js +2 -2
- package/dist/ChatFooter/components/index.d.cts +10 -6
- package/dist/ChatFooter/components/index.d.ts +7 -3
- 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 +4 -4
- package/dist/ChatHeader/components/Handle.js +4 -4
- package/dist/ChatHeader/components/Toggle.cjs +3 -3
- package/dist/ChatHeader/components/Toggle.js +3 -3
- package/dist/ChatHeader/hooks/useGetHandleProperties.cjs +8 -6
- package/dist/ChatHeader/hooks/useGetHandleProperties.js +8 -6
- package/dist/ChatHeader/hooks/useGetToggleOptionProperties.cjs +1 -1
- package/dist/ChatHeader/hooks/useGetToggleOptionProperties.js +1 -1
- package/dist/ChatPreview/ChatPreview.cjs +7 -4
- package/dist/ChatPreview/ChatPreview.d.cts +2 -2
- package/dist/ChatPreview/ChatPreview.js +7 -4
- 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 +7 -4
- package/dist/ChatPreviewComparison/ChatPreviewComparison.d.cts +2 -2
- package/dist/ChatPreviewComparison/ChatPreviewComparison.d.ts +2 -2
- package/dist/ChatPreviewComparison/ChatPreviewComparison.js +7 -4
- package/dist/ChatPreviewComparison/components/Headline.cjs +2 -2
- package/dist/ChatPreviewComparison/components/Headline.js +2 -2
- package/dist/ChatPreviewComparison/components/Layout.cjs +4 -4
- package/dist/ChatPreviewComparison/components/Layout.js +4 -4
- package/dist/ChatPreviewComparison/components/Message.cjs +2 -2
- package/dist/ChatPreviewComparison/components/Message.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 +4 -3
- 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 +172 -172
- package/dist/Container/Container.d.ts +172 -172
- package/dist/DesignTokens/DesignTokensComponent.d.cts +2 -2
- package/dist/DesignTokens/DesignTokensComponent.d.ts +2 -2
- package/dist/Disclaimer/components/Container.cjs +2 -2
- package/dist/Disclaimer/components/Container.js +2 -2
- package/dist/DocumentRetrievalCard/DocumentRetrievalCard.d.cts +2 -2
- package/dist/DocumentRetrievalCard/DocumentRetrievalCard.d.ts +2 -2
- package/dist/DocumentRetrievalCard/components/Layout.cjs +2 -2
- package/dist/DocumentRetrievalCard/components/Layout.js +2 -2
- package/dist/DocumentRetrievalCard/components/ViewArticleButton/components/Icon.cjs +1 -1
- package/dist/DocumentRetrievalCard/components/ViewArticleButton/components/Icon.js +1 -1
- package/dist/FloatingButton/FloatingButton.d.cts +2 -2
- package/dist/FloatingButton/FloatingButton.d.ts +2 -2
- 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 +3 -3
- package/dist/FloatingChat/components/Layout.js +3 -3
- 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/FullPageSalesAgent/FullPageSalesAgent.cjs +25 -3
- package/dist/FullPageSalesAgent/FullPageSalesAgent.d.cts +5 -3
- package/dist/FullPageSalesAgent/FullPageSalesAgent.d.ts +5 -3
- package/dist/FullPageSalesAgent/FullPageSalesAgent.js +26 -4
- package/dist/Image/Image.d.cts +2 -2
- package/dist/Image/Image.d.ts +2 -2
- package/dist/ImageGallery/ImageGallery.d.cts +2 -2
- package/dist/ImageGallery/ImageGallery.d.ts +2 -2
- package/dist/ImageGallery/components/Layout.cjs +1 -1
- package/dist/ImageGallery/components/Layout.js +1 -1
- package/dist/MarkdownProcessor/MarkdownProcessor.d.cts +2 -2
- package/dist/MarkdownProcessor/MarkdownProcessor.d.ts +2 -2
- package/dist/Message/components/LinkButton.cjs +1 -1
- package/dist/Message/components/LinkButton.js +1 -1
- package/dist/OrderLookupCard/OrderLookupCard.cjs +1 -1
- package/dist/OrderLookupCard/OrderLookupCard.js +1 -1
- package/dist/ProductCard/ProductCard.cjs +7 -3
- package/dist/ProductCard/ProductCard.d.cts +6 -3
- package/dist/ProductCard/ProductCard.d.ts +6 -3
- package/dist/ProductCard/ProductCard.js +7 -3
- 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.d.cts +2 -2
- package/dist/PromptButton/PromptButton.d.ts +2 -2
- 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/PromptButtonsCarousel.cjs +1 -1
- package/dist/PromptButtonCarouselWithImage/components/PromptButtonsCarousel.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 +3 -3
- package/dist/PromptCarousel/PromptCarousel.d.cts +2 -2
- package/dist/PromptCarousel/PromptCarousel.d.ts +2 -2
- package/dist/PromptCarousel/PromptCarousel.js +3 -3
- package/dist/ReviewCard/ReviewCard.d.cts +2 -2
- package/dist/ReviewCard/ReviewCard.d.ts +2 -2
- package/dist/ReviewCard/components/Container.cjs +2 -2
- package/dist/ReviewCard/components/Container.js +2 -2
- package/dist/ReviewCard/components/Rating.cjs +0 -1
- package/dist/ReviewCard/components/Rating.js +0 -1
- package/dist/ReviewCard/components/ReadMoreButton.cjs +1 -1
- package/dist/ReviewCard/components/ReadMoreButton.js +1 -1
- package/dist/ReviewCard/components/index.d.cts +4 -4
- 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 +2 -2
- package/dist/SalesAgentProductCard/components/Container.js +2 -2
- package/dist/SalesAgentProductCard/components/index.d.cts +6 -6
- package/dist/SalesAgentProductCard/components/index.d.ts +8 -8
- package/dist/SocialProof/SocialProof.cjs +7 -4
- package/dist/SocialProof/SocialProof.d.cts +2 -2
- package/dist/SocialProof/SocialProof.js +7 -4
- package/dist/SocialProof/components/Headline.cjs +3 -3
- package/dist/SocialProof/components/Headline.js +3 -3
- package/dist/SocialProof/components/LayoutFourHorizontal.cjs +1 -1
- package/dist/SocialProof/components/LayoutFourHorizontal.js +1 -1
- package/dist/SocialProof/components/Subheadline.cjs +1 -1
- package/dist/SocialProof/components/Subheadline.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 +34 -2
- package/dist/TextField/TextField.d.cts +5 -1
- package/dist/TextField/TextField.d.ts +5 -1
- package/dist/TextField/TextField.js +34 -2
- package/dist/TextField/components/Layout.cjs +10 -7
- package/dist/TextField/components/Layout.js +10 -7
- 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/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 +1 -1
- package/dist/Tokens/index.js +1 -1
- package/dist/TypingAnimation/TypingAnimation.cjs +8 -4
- package/dist/TypingAnimation/TypingAnimation.d.cts +2 -2
- package/dist/TypingAnimation/TypingAnimation.js +8 -4
- package/dist/TypingAnimation/hooks/useGetTypographyVariant.cjs +1 -1
- package/dist/TypingAnimation/hooks/useGetTypographyVariant.js +1 -1
- 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 +2 -2
- package/dist/WelcomeMessage/components/Container.js +2 -2
- package/dist/WidgetTextField/WidgetTextField.cjs +40 -8
- package/dist/WidgetTextField/WidgetTextField.d.cts +7 -3
- package/dist/WidgetTextField/WidgetTextField.d.ts +7 -3
- package/dist/WidgetTextField/WidgetTextField.js +34 -3
- package/dist/WidgetTextField/components/Container.cjs +33 -27
- package/dist/WidgetTextField/components/Container.js +33 -27
- package/dist/WidgetTextField/components/Icon.cjs +1 -1
- package/dist/WidgetTextField/components/Icon.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.d.cts +2 -2
- package/dist/WidgetWrapper/WidgetWrapper.d.ts +2 -2
- 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/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/styles.css +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 +9 -5
- 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
|
@@ -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
|
+
};
|
|
@@ -30,6 +30,12 @@ export type WidgetTextFieldProps = {
|
|
|
30
30
|
* @default Theme.GLOBAL_CUSTOM
|
|
31
31
|
*/
|
|
32
32
|
theme?: Theme;
|
|
33
|
+
/**
|
|
34
|
+
* When the resolved theme is MINIMAL, controls border treatment.
|
|
35
|
+
* `full` matches overlays (full frame). `bottom-only` matches embedded contexts like product cards.
|
|
36
|
+
* @default 'full'
|
|
37
|
+
*/
|
|
38
|
+
minimalFrame?: 'full' | 'bottom-only';
|
|
33
39
|
/** Placeholder text displayed in the text field. */
|
|
34
40
|
placeholder?: string;
|
|
35
41
|
/** Accessible label for screen readers. If not provided, the placeholder will be used. */
|
|
@@ -47,6 +53,21 @@ export type WidgetTextFieldProps = {
|
|
|
47
53
|
isLoading?: boolean;
|
|
48
54
|
/** Callback function invoked when the text field is clicked or activated via keyboard. */
|
|
49
55
|
onClick?: () => void;
|
|
56
|
+
/** Enable voice input button */
|
|
57
|
+
enableVoiceInput?: boolean;
|
|
58
|
+
/** Voice input button class name */
|
|
59
|
+
voiceInputClassName?: string;
|
|
60
|
+
/**
|
|
61
|
+
* Callback function invoked when voice transcription starts (user begins recording).
|
|
62
|
+
* Use this to track when the user starts using voice input.
|
|
63
|
+
*/
|
|
64
|
+
onTranscriptionStarted?: () => void;
|
|
65
|
+
/**
|
|
66
|
+
* Callback function invoked when voice transcription completes (user stops recording).
|
|
67
|
+
* @param transcript - The transcribed text from the voice input.
|
|
68
|
+
* Use this to track the completed voice transcription and the resulting text.
|
|
69
|
+
*/
|
|
70
|
+
onTranscriptionCompleted?: (transcript: string) => void;
|
|
50
71
|
};
|
|
51
72
|
|
|
52
73
|
export enum IconVariant {
|
|
@@ -9,7 +9,7 @@ export const useGetWrapperProperties = (variant: WidgetWrapperVariant) => {
|
|
|
9
9
|
case WidgetWrapperVariant.CARD_NO_BORDER:
|
|
10
10
|
return 'envive-tw-rounded-global-custom envive-tw-bg-background-light envive-tw-md:p-6 envive-tw-p-3';
|
|
11
11
|
case WidgetWrapperVariant.INLINE_WITH_BORDER:
|
|
12
|
-
return 'envive-tw-border-t envive-tw-border-b envive-tw-border-solid envive-tw-border-border-light envive-tw-
|
|
12
|
+
return 'envive-tw-border-t envive-tw-border-b envive-tw-border-solid envive-tw-border-border-light envive-tw-py-6';
|
|
13
13
|
case WidgetWrapperVariant.INLINE_NO_BORDER:
|
|
14
14
|
return undefined;
|
|
15
15
|
default:
|