@envive-ai/react-toolkit-v3 0.3.11 → 0.3.13
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/CSSVariablesEditor/CssVariablesEditorComponent.d.cts +2 -2
- package/dist/CSSVariablesEditor/CssVariablesEditorComponent.d.ts +2 -2
- package/dist/Carousel/Carousel.d.cts +2 -2
- package/dist/Carousel/Carousel.d.ts +2 -2
- package/dist/Carousel/components/Container.cjs +11 -3
- package/dist/Carousel/components/Container.js +12 -4
- package/dist/ChatFooter/ChatFooter.d.cts +2 -2
- package/dist/ChatFooter/ChatFooter.d.ts +2 -2
- package/dist/ChatFooter/components/Layout.cjs +2 -8
- package/dist/ChatFooter/components/Layout.js +2 -8
- package/dist/ChatFooter/components/index.d.cts +5 -5
- package/dist/ChatFooter/components/index.d.ts +3 -3
- package/dist/ChatHeader/ChatHeader.d.cts +2 -2
- package/dist/ChatHeader/ChatHeader.d.ts +2 -2
- package/dist/ChatHeader/hooks/useGetCloseButtonProperties.cjs +1 -1
- package/dist/ChatHeader/hooks/useGetCloseButtonProperties.js +1 -1
- package/dist/ChatPreview/ChatPreview.d.cts +2 -2
- package/dist/ChatPreview/ChatPreview.d.ts +2 -2
- package/dist/ChatPreviewComparison/ChatPreviewComparison.d.cts +2 -2
- package/dist/ChatPreviewComparison/ChatPreviewComparison.d.ts +2 -2
- package/dist/ChatPreviewComparison/components/Layout.cjs +4 -3
- package/dist/ChatPreviewComparison/components/Layout.js +4 -3
- package/dist/ChatPreviewLoading/ChatPreviewLoading.d.cts +2 -2
- package/dist/ChatPreviewLoading/ChatPreviewLoading.d.ts +2 -2
- package/dist/Container/Container.d.cts +178 -178
- package/dist/Container/Container.d.ts +8 -8
- package/dist/DesignTokens/DesignTokensComponent.d.cts +2 -2
- package/dist/DesignTokens/DesignTokensComponent.d.ts +2 -2
- package/dist/DocumentRetrievalCard/DocumentRetrievalCard.d.cts +2 -2
- package/dist/DocumentRetrievalCard/DocumentRetrievalCard.d.ts +2 -2
- package/dist/FloatingButton/FloatingButton.d.cts +2 -2
- package/dist/FloatingButton/FloatingButton.d.ts +2 -2
- package/dist/FloatingChat/FloatingChat.cjs +6 -3
- package/dist/FloatingChat/FloatingChat.d.cts +2 -2
- package/dist/FloatingChat/FloatingChat.d.ts +2 -2
- package/dist/FloatingChat/FloatingChat.js +6 -3
- package/dist/FloatingChat/hooks/useSnapSetup.cjs +10 -7
- package/dist/FloatingChat/hooks/useSnapSetup.js +10 -7
- package/dist/FullPageSalesAgent/FullPageSalesAgent.cjs +3 -2
- package/dist/FullPageSalesAgent/FullPageSalesAgent.d.cts +2 -2
- package/dist/FullPageSalesAgent/FullPageSalesAgent.d.ts +2 -2
- package/dist/FullPageSalesAgent/FullPageSalesAgent.js +3 -2
- package/dist/FullPageSalesAgent/hooks/useContainerResizerObserver.cjs +3 -3
- package/dist/FullPageSalesAgent/hooks/useContainerResizerObserver.js +3 -3
- package/dist/Image/Image.cjs +5 -0
- package/dist/Image/Image.d.cts +2 -2
- package/dist/Image/Image.d.ts +2 -2
- package/dist/Image/Image.js +5 -0
- package/dist/ImageGallery/ImageGallery.d.cts +2 -2
- package/dist/MarkdownProcessor/MarkdownProcessor.cjs +14 -27
- package/dist/MarkdownProcessor/MarkdownProcessor.d.cts +3 -5
- package/dist/MarkdownProcessor/MarkdownProcessor.d.ts +1 -3
- package/dist/MarkdownProcessor/MarkdownProcessor.js +15 -26
- package/dist/MarkdownProcessor/components/index.cjs +1 -3
- package/dist/MarkdownProcessor/components/index.js +1 -3
- package/dist/MarkdownProcessor/utils/functions.cjs +1 -11
- package/dist/MarkdownProcessor/utils/functions.js +1 -10
- package/dist/ProductCard/ProductCard.d.cts +2 -2
- package/dist/ProductCard/components/Header.cjs +33 -7
- package/dist/ProductCard/components/Header.js +34 -8
- package/dist/PromptButton/PromptButton.d.cts +2 -2
- package/dist/PromptButtonCarouselWithImage/PromptButtonCarouselWithImage.d.cts +2 -2
- package/dist/PromptButtonCarouselWithImage/PromptButtonCarouselWithImage.d.ts +2 -2
- package/dist/PromptCarousel/PromptCarousel.cjs +19 -28
- package/dist/PromptCarousel/PromptCarousel.d.cts +2 -2
- package/dist/PromptCarousel/PromptCarousel.d.ts +2 -2
- package/dist/PromptCarousel/PromptCarousel.js +19 -28
- package/dist/ReviewCard/ReviewCard.d.cts +2 -2
- package/dist/ReviewCard/ReviewCard.d.ts +2 -2
- package/dist/ReviewCard/components/index.d.cts +6 -6
- package/dist/ReviewCard/components/index.d.ts +4 -4
- package/dist/SalesAgentProductCard/SalesAgentProductCard.d.cts +2 -2
- package/dist/SalesAgentProductCard/SalesAgentProductCard.d.ts +2 -2
- package/dist/SalesAgentProductCard/components/index.d.cts +8 -8
- package/dist/SalesAgentProductCard/components/index.d.ts +6 -6
- package/dist/SocialProof/SocialProof.d.cts +2 -2
- package/dist/SocialProof/SocialProof.d.ts +2 -2
- package/dist/Stack/Stack.d.ts +2 -2
- package/dist/TitledPromptCarousel/TitledPromptCarousel.d.ts +2 -2
- package/dist/TypingAnimation/TypingAnimation.cjs +58 -18
- package/dist/TypingAnimation/TypingAnimation.d.cts +2 -2
- package/dist/TypingAnimation/TypingAnimation.d.ts +2 -2
- package/dist/TypingAnimation/TypingAnimation.js +59 -19
- package/dist/Typography/Typography.d.cts +4 -4
- package/dist/Typography/Typography.d.ts +4 -4
- package/dist/WidgetTextField/WidgetTextField.d.cts +2 -2
- package/dist/WidgetTextField/WidgetTextField.d.ts +2 -2
- package/dist/WidgetWrapper/WidgetWrapper.d.cts +2 -2
- package/dist/WidgetWrapper/WidgetWrapper.d.ts +2 -2
- package/dist/WidgetWrapperWithTitle/WidgetWrapperWithTitle.d.cts +2 -2
- package/dist/styles.css +1 -1
- package/dist/utils/useAnimatedTextMinHeight.cjs +28 -0
- package/dist/utils/useAnimatedTextMinHeight.js +27 -0
- package/package.json +1 -3
- package/src/components/Carousel/components/Container.tsx +15 -3
- package/src/components/ChatFooter/components/Layout.tsx +2 -14
- package/src/components/ChatHeader/hooks/useGetCloseButtonProperties.ts +1 -1
- package/src/components/ChatPreviewComparison/components/Layout.tsx +2 -2
- package/src/components/FloatingChat/FloatingChat.tsx +5 -2
- package/src/components/FloatingChat/hooks/useSnapSetup.ts +11 -4
- package/src/components/FullPageSalesAgent/FullPageSalesAgent.tsx +6 -2
- package/src/components/FullPageSalesAgent/components/Layout.tsx +1 -1
- package/src/components/FullPageSalesAgent/hooks/useContainerResizerObserver.ts +4 -3
- package/src/components/FullPageSalesAgent/hooks/useIsMobile.ts +1 -1
- package/src/components/Image/Image.tsx +2 -0
- package/src/components/MarkdownProcessor/MarkdownProcessor.tsx +3 -19
- package/src/components/MarkdownProcessor/__tests__/MarkdownProcessor.test.tsx +1 -39
- package/src/components/MarkdownProcessor/components/index.ts +0 -2
- package/src/components/MarkdownProcessor/utils/functions.tsx +0 -19
- package/src/components/ProductCard/components/Header.tsx +39 -9
- package/src/components/PromptCarousel/PromptCarousel.tsx +29 -31
- package/src/components/TypingAnimation/TypingAnimation.tsx +68 -22
- package/src/components/utils/useAnimatedTextMinHeight.ts +29 -0
- package/dist/ChatFooter/hooks/useGetButtonScrollProperties.cjs +0 -18
- package/dist/ChatFooter/hooks/useGetButtonScrollProperties.js +0 -17
- package/dist/MarkdownProcessor/components/MarkdownSubscript.cjs +0 -15
- package/dist/MarkdownProcessor/components/MarkdownSubscript.js +0 -14
- package/src/components/MarkdownProcessor/components/MarkdownSubscript.tsx +0 -22
|
@@ -55,6 +55,7 @@ export const FloatingChat = ({
|
|
|
55
55
|
showEnviveLogo,
|
|
56
56
|
ignoreFirstModelResponse,
|
|
57
57
|
neverShowSingleProductCards,
|
|
58
|
+
partialViewConfig,
|
|
58
59
|
} = floatingChatConfig;
|
|
59
60
|
|
|
60
61
|
const {
|
|
@@ -95,6 +96,8 @@ export const FloatingChat = ({
|
|
|
95
96
|
}
|
|
96
97
|
};
|
|
97
98
|
|
|
99
|
+
const partialViewDisabled = partialViewConfig?.disabled ?? false;
|
|
100
|
+
|
|
98
101
|
const {
|
|
99
102
|
modalSheetControl,
|
|
100
103
|
maxSwipeableViewHeight,
|
|
@@ -110,7 +113,7 @@ export const FloatingChat = ({
|
|
|
110
113
|
shouldShowHeader,
|
|
111
114
|
isFullView,
|
|
112
115
|
isPartialView,
|
|
113
|
-
} = useSnapSetup({ isFloatingChatOpen });
|
|
116
|
+
} = useSnapSetup({ isFloatingChatOpen, partialViewDisabled });
|
|
114
117
|
|
|
115
118
|
const { showScrollButton, scrollToBottom, isFloatingLayout } = useScrollToBottom({
|
|
116
119
|
messagesRef: chatMessagesRef,
|
|
@@ -206,7 +209,7 @@ export const FloatingChat = ({
|
|
|
206
209
|
}}
|
|
207
210
|
textFieldPlaceholderText={chatFooterTextFieldPlaceholderText as string}
|
|
208
211
|
promptSuggestions={
|
|
209
|
-
isPendingResponse || isResponseStreaming
|
|
212
|
+
isPendingResponse || isResponseStreaming
|
|
210
213
|
? ['Loading suggestions 1...', 'Loading suggestions 2...'] // This is strings will not be shown to the user
|
|
211
214
|
: generalSuggestions
|
|
212
215
|
}
|
|
@@ -24,16 +24,19 @@ export interface UseSnapSetupReturn {
|
|
|
24
24
|
snap100Percent: number;
|
|
25
25
|
|
|
26
26
|
shouldShowHeader: boolean;
|
|
27
|
-
shouldShowScrolled: boolean;
|
|
28
27
|
isFullView: boolean;
|
|
29
28
|
isPartialView: boolean;
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
export interface UseSnapSetupProps {
|
|
33
32
|
isFloatingChatOpen: boolean;
|
|
33
|
+
partialViewDisabled?: boolean;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
export const useSnapSetup = ({
|
|
36
|
+
export const useSnapSetup = ({
|
|
37
|
+
isFloatingChatOpen,
|
|
38
|
+
partialViewDisabled,
|
|
39
|
+
}: UseSnapSetupProps): UseSnapSetupReturn => {
|
|
37
40
|
const maxSwipeableViewHeight = 89;
|
|
38
41
|
const modalSheetControl = useRef<ModalSheetControl>(null);
|
|
39
42
|
const { viewportWidth } = useCheckIsMobile();
|
|
@@ -46,8 +49,12 @@ export const useSnapSetup = ({ isFloatingChatOpen }: UseSnapSetupProps): UseSnap
|
|
|
46
49
|
?.selectedCustomizeOption,
|
|
47
50
|
);
|
|
48
51
|
|
|
49
|
-
const snaps =
|
|
50
|
-
|
|
52
|
+
const snaps = (() => {
|
|
53
|
+
if (partialViewDisabled) return shouldAutoExpand ? [100] : [0, 100];
|
|
54
|
+
return shouldAutoExpand ? [43, 100] : [0, 43, 100];
|
|
55
|
+
})();
|
|
56
|
+
const partialViewDisabledValue = shouldAutoExpand ? 0 : 1;
|
|
57
|
+
const initialSnap = partialViewDisabled ? partialViewDisabledValue : 1;
|
|
51
58
|
|
|
52
59
|
const [currentSnapPercentage, setCurrentSnapPercentage] = useState<number>(
|
|
53
60
|
snaps[initialSnap] || 43,
|
|
@@ -117,7 +117,7 @@ export const FullPageSalesAgent = ({
|
|
|
117
117
|
hideEnviveWatermark={!showEnviveLogo}
|
|
118
118
|
textFieldPlaceholderText={chatFooterTextFieldPlaceholderText as string}
|
|
119
119
|
promptSuggestions={
|
|
120
|
-
isPendingResponse || isResponseStreaming
|
|
120
|
+
isPendingResponse || isResponseStreaming
|
|
121
121
|
? ['Loading suggestions 1...', 'Loading suggestions 2...']
|
|
122
122
|
: generalSuggestions
|
|
123
123
|
}
|
|
@@ -132,7 +132,11 @@ export const FullPageSalesAgent = ({
|
|
|
132
132
|
}}
|
|
133
133
|
onChange={setQuery}
|
|
134
134
|
onSubmit={() => {
|
|
135
|
-
onTypedMessageSubmitted({
|
|
135
|
+
onTypedMessageSubmitted({
|
|
136
|
+
query,
|
|
137
|
+
userTyped: true,
|
|
138
|
+
displayLocation: ChatElementDisplayLocationV3.FLOATING_CHAT_TEXT_INPUT,
|
|
139
|
+
});
|
|
136
140
|
setAnswerSuggestions([]);
|
|
137
141
|
setGeneralSuggestions([]);
|
|
138
142
|
}}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import classNames from 'classnames';
|
|
2
2
|
import { isValidElement } from 'react';
|
|
3
|
-
import { Stack } from 'src/components/Stack';
|
|
4
3
|
import { Theme } from 'tokens/theme/theme';
|
|
4
|
+
import { Stack } from '../../Stack';
|
|
5
5
|
import { useGetContainerStyles } from '../hooks/useGetContainerStyles';
|
|
6
6
|
import { useGetFooterStyles } from '../hooks/useGetFooterStyles';
|
|
7
7
|
import { useGetScrollContentStyles } from '../hooks/useGetScrollContentStyles';
|
|
@@ -11,12 +11,13 @@ export const useContainerResizerObserver = ({
|
|
|
11
11
|
|
|
12
12
|
useEffect(() => {
|
|
13
13
|
if (!autoHeight) {
|
|
14
|
-
return
|
|
14
|
+
return () => {};
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
const watchResizing = () => {
|
|
18
|
-
const
|
|
19
|
-
|
|
18
|
+
const { height = 0, top = 0 } =
|
|
19
|
+
document.querySelector(headerContainer)?.getBoundingClientRect() || {};
|
|
20
|
+
setContainerHeight(window.innerHeight - (height + top));
|
|
20
21
|
};
|
|
21
22
|
|
|
22
23
|
window.addEventListener('resize', watchResizing);
|
|
@@ -88,8 +88,10 @@ export const Image = ({
|
|
|
88
88
|
objectFitClass,
|
|
89
89
|
isLoading && 'envive-tw-opacity-0',
|
|
90
90
|
)}
|
|
91
|
+
style={{ userSelect: 'none', WebkitUserDrag: 'none' } as React.CSSProperties}
|
|
91
92
|
onLoad={handleLoad}
|
|
92
93
|
onError={handleError}
|
|
94
|
+
draggable={false}
|
|
93
95
|
{...accessibilityProps}
|
|
94
96
|
{...rest}
|
|
95
97
|
/>
|
|
@@ -1,21 +1,14 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
2
|
import ReactMarkdown from 'react-markdown';
|
|
3
|
-
import remarkGfm from 'remark-gfm';
|
|
4
|
-
import rehypeRaw from 'rehype-raw';
|
|
5
3
|
import { MarkdownProcessorProps } from './types/types';
|
|
6
4
|
import { MarkdownProcessorComponents } from './components';
|
|
7
|
-
import {
|
|
8
|
-
createMarkdownParagraphComponent,
|
|
9
|
-
createMarkdownSubscriptComponent,
|
|
10
|
-
} from './utils/functions';
|
|
5
|
+
import { createMarkdownParagraphComponent } from './utils/functions';
|
|
11
6
|
|
|
12
7
|
export const MarkdownProcessor = ({
|
|
13
8
|
content,
|
|
14
9
|
clampParagraphs = undefined,
|
|
15
10
|
textColor,
|
|
16
11
|
textVariant,
|
|
17
|
-
subTextVariant,
|
|
18
|
-
subTextColor,
|
|
19
12
|
}: MarkdownProcessorProps) => {
|
|
20
13
|
const processedContent = content.replace(/<br\s*[\\/]?>/gi, '\n\n');
|
|
21
14
|
|
|
@@ -26,18 +19,9 @@ export const MarkdownProcessor = ({
|
|
|
26
19
|
ol: MarkdownProcessorComponents.MarkdownOrderedList,
|
|
27
20
|
a: MarkdownProcessorComponents.MarkdownLink,
|
|
28
21
|
p: createMarkdownParagraphComponent({ clampParagraphs, textColor, textVariant }),
|
|
29
|
-
sub: createMarkdownSubscriptComponent({ subTextVariant, subTextColor }),
|
|
30
22
|
}),
|
|
31
|
-
[clampParagraphs, textColor, textVariant
|
|
23
|
+
[clampParagraphs, textColor, textVariant],
|
|
32
24
|
);
|
|
33
25
|
|
|
34
|
-
return
|
|
35
|
-
<ReactMarkdown
|
|
36
|
-
remarkPlugins={[remarkGfm]}
|
|
37
|
-
rehypePlugins={[rehypeRaw]}
|
|
38
|
-
components={components}
|
|
39
|
-
>
|
|
40
|
-
{processedContent}
|
|
41
|
-
</ReactMarkdown>
|
|
42
|
-
);
|
|
26
|
+
return <ReactMarkdown components={components}>{processedContent}</ReactMarkdown>;
|
|
43
27
|
};
|
|
@@ -69,22 +69,6 @@ describe('MarkdownProcessor', () => {
|
|
|
69
69
|
});
|
|
70
70
|
});
|
|
71
71
|
|
|
72
|
-
describe('Subscript', () => {
|
|
73
|
-
it('should render subscript text', () => {
|
|
74
|
-
const content = 'Regular text<sub>subscript</sub>';
|
|
75
|
-
render(<MarkdownProcessor content={content} />);
|
|
76
|
-
expect(screen.getByText('Regular text')).toBeInTheDocument();
|
|
77
|
-
expect(screen.getByText('subscript')).toBeInTheDocument();
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('should render multiple subscript elements', () => {
|
|
81
|
-
const content = 'First<sub>sub1</sub> and second<sub>sub2</sub>';
|
|
82
|
-
render(<MarkdownProcessor content={content} />);
|
|
83
|
-
expect(screen.getByText('sub1')).toBeInTheDocument();
|
|
84
|
-
expect(screen.getByText('sub2')).toBeInTheDocument();
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
|
|
88
72
|
describe('Paragraph clamping', () => {
|
|
89
73
|
it('should not clamp paragraphs when clampParagraphs is undefined', () => {
|
|
90
74
|
const content =
|
|
@@ -131,34 +115,12 @@ describe('MarkdownProcessor', () => {
|
|
|
131
115
|
);
|
|
132
116
|
expect(screen.getByText('Custom color text')).toBeInTheDocument();
|
|
133
117
|
});
|
|
134
|
-
|
|
135
|
-
it('should apply custom subTextVariant', () => {
|
|
136
|
-
const content = 'Text<sub>subscript</sub>';
|
|
137
|
-
render(
|
|
138
|
-
<MarkdownProcessor
|
|
139
|
-
content={content}
|
|
140
|
-
subTextVariant={TypographyVariant.B4_RG}
|
|
141
|
-
/>,
|
|
142
|
-
);
|
|
143
|
-
expect(screen.getByText('subscript')).toBeInTheDocument();
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
it('should apply custom subTextColor', () => {
|
|
147
|
-
const content = 'Text<sub>subscript</sub>';
|
|
148
|
-
render(
|
|
149
|
-
<MarkdownProcessor
|
|
150
|
-
content={content}
|
|
151
|
-
subTextColor={TypographyColor.TEXT_ACCENT}
|
|
152
|
-
/>,
|
|
153
|
-
);
|
|
154
|
-
expect(screen.getByText('subscript')).toBeInTheDocument();
|
|
155
|
-
});
|
|
156
118
|
});
|
|
157
119
|
|
|
158
120
|
describe('Complex content', () => {
|
|
159
121
|
it('should render complex markdown with multiple elements', () => {
|
|
160
122
|
const content =
|
|
161
|
-
'# Heading\n\nThis is a paragraph with **bold** and *italic*.\n\n- List item 1\n- List item 2\n\n1. Ordered item 1\n2. Ordered item 2\n\n[Link text](https://example.com)
|
|
123
|
+
'# Heading\n\nThis is a paragraph with **bold** and *italic*.\n\n- List item 1\n- List item 2\n\n1. Ordered item 1\n2. Ordered item 2\n\n[Link text](https://example.com)';
|
|
162
124
|
render(<MarkdownProcessor content={content} />);
|
|
163
125
|
expect(screen.getByText(/This is a paragraph/i)).toBeInTheDocument();
|
|
164
126
|
expect(screen.getByText('List item 1')).toBeInTheDocument();
|
|
@@ -3,7 +3,6 @@ import { MarkdownLink } from './MarkdownLink';
|
|
|
3
3
|
import { MarkdownOrderedList } from './MarkdownOrderedList';
|
|
4
4
|
import { MarkdownUnorderedList } from './MarkdownUnorderedList';
|
|
5
5
|
import { MarkdownParagraph } from './MarkdownParagraph';
|
|
6
|
-
import { MarkdownSubscript } from './MarkdownSubscript';
|
|
7
6
|
|
|
8
7
|
export const MarkdownProcessorComponents = {
|
|
9
8
|
MarkdownListItem,
|
|
@@ -11,5 +10,4 @@ export const MarkdownProcessorComponents = {
|
|
|
11
10
|
MarkdownOrderedList,
|
|
12
11
|
MarkdownUnorderedList,
|
|
13
12
|
MarkdownParagraph,
|
|
14
|
-
MarkdownSubscript,
|
|
15
13
|
};
|
|
@@ -22,22 +22,3 @@ export const createMarkdownParagraphComponent = ({
|
|
|
22
22
|
Component.displayName = 'MarkdownParagraphComponent';
|
|
23
23
|
return Component;
|
|
24
24
|
};
|
|
25
|
-
|
|
26
|
-
export const createMarkdownSubscriptComponent = ({
|
|
27
|
-
subTextVariant,
|
|
28
|
-
subTextColor,
|
|
29
|
-
}: {
|
|
30
|
-
subTextVariant?: TypographyVariant;
|
|
31
|
-
subTextColor?: TypographyColor;
|
|
32
|
-
}) => {
|
|
33
|
-
const Component = ({ children }: { children?: React.ReactNode }) => (
|
|
34
|
-
<MarkdownProcessorComponents.MarkdownSubscript
|
|
35
|
-
subTextVariant={subTextVariant}
|
|
36
|
-
subTextColor={subTextColor}
|
|
37
|
-
>
|
|
38
|
-
{children}
|
|
39
|
-
</MarkdownProcessorComponents.MarkdownSubscript>
|
|
40
|
-
);
|
|
41
|
-
Component.displayName = 'MarkdownSubscriptComponent';
|
|
42
|
-
return Component;
|
|
43
|
-
};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { useCallback } from 'react';
|
|
1
|
+
import { useCallback, useMemo } from 'react';
|
|
2
2
|
import { AnimatedText } from '../../AnimatedText';
|
|
3
3
|
import { Stack } from '../../Stack';
|
|
4
4
|
import { Typography, TypographyColor, TypographyVariant } from '../../Typography';
|
|
5
|
+
import { useAnimatedTextMinHeight } from '../../utils/useAnimatedTextMinHeight';
|
|
5
6
|
import { useGetHeaderProperties } from '../hooks/useGetHeaderProperties';
|
|
6
7
|
import { HeaderProps } from '../types';
|
|
7
8
|
|
|
@@ -14,13 +15,19 @@ export const Header = ({
|
|
|
14
15
|
loop,
|
|
15
16
|
}: HeaderProps) => {
|
|
16
17
|
const { stackClasses, headlineClasses } = useGetHeaderProperties(italicizeHeadline);
|
|
18
|
+
const { measuringRef, minHeight } = useAnimatedTextMinHeight(animatedText);
|
|
19
|
+
|
|
20
|
+
const biggestText = useMemo(() => {
|
|
21
|
+
return animatedText.reduce((maxText, currText) => {
|
|
22
|
+
return currText.length > maxText.length ? currText : maxText;
|
|
23
|
+
}, '');
|
|
24
|
+
}, [animatedText]);
|
|
17
25
|
|
|
18
26
|
const animatedTextWrapper = useCallback(
|
|
19
27
|
(text: string) => (
|
|
20
28
|
<Typography
|
|
21
29
|
variant={TypographyVariant.B3_MD}
|
|
22
30
|
color={TypographyColor.TEXT_LIGHT}
|
|
23
|
-
numberOfLines={2}
|
|
24
31
|
>
|
|
25
32
|
{text}
|
|
26
33
|
</Typography>
|
|
@@ -42,13 +49,36 @@ export const Header = ({
|
|
|
42
49
|
{headline}
|
|
43
50
|
</Typography>
|
|
44
51
|
{animatedText.length > 0 && (
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
<div style={{ position: 'relative' }}>
|
|
53
|
+
<div
|
|
54
|
+
ref={measuringRef}
|
|
55
|
+
aria-hidden="true"
|
|
56
|
+
style={{
|
|
57
|
+
position: 'absolute',
|
|
58
|
+
visibility: 'hidden',
|
|
59
|
+
pointerEvents: 'none',
|
|
60
|
+
width: '100%',
|
|
61
|
+
}}
|
|
62
|
+
>
|
|
63
|
+
<div>
|
|
64
|
+
<Typography
|
|
65
|
+
variant={TypographyVariant.B3_MD}
|
|
66
|
+
color={TypographyColor.TEXT_LIGHT}
|
|
67
|
+
>
|
|
68
|
+
{biggestText}
|
|
69
|
+
</Typography>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
<div style={{ minHeight }}>
|
|
73
|
+
<AnimatedText
|
|
74
|
+
sequence={animatedText}
|
|
75
|
+
getNodeWrapper={animatedTextWrapper}
|
|
76
|
+
typingDuration={textTypingDuration}
|
|
77
|
+
transition={textTransition}
|
|
78
|
+
loop={loop}
|
|
79
|
+
/>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
52
82
|
)}
|
|
53
83
|
</Stack>
|
|
54
84
|
);
|
|
@@ -83,16 +83,20 @@ export const PromptCarousel = ({
|
|
|
83
83
|
const buttonKey = `button-${buttonId}`;
|
|
84
84
|
|
|
85
85
|
return (
|
|
86
|
-
<
|
|
87
|
-
id={buttonId}
|
|
86
|
+
<div
|
|
88
87
|
key={buttonKey}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
88
|
+
className="envive-tw-flex-shrink-0"
|
|
89
|
+
>
|
|
90
|
+
<PromptButton
|
|
91
|
+
id={buttonId}
|
|
92
|
+
label={text}
|
|
93
|
+
variant={promptButtonType}
|
|
94
|
+
theme={finalTheme}
|
|
95
|
+
isLoading={isLoading}
|
|
96
|
+
bold={boldFirstButton && index === 0 && duplicateIndex === 0}
|
|
97
|
+
onClick={() => handleButtonClick?.(text)}
|
|
98
|
+
/>
|
|
99
|
+
</div>
|
|
96
100
|
);
|
|
97
101
|
},
|
|
98
102
|
[id, promptButtonType, boldFirstButton, handleButtonClick, isLoading, finalTheme],
|
|
@@ -127,36 +131,30 @@ export const PromptCarousel = ({
|
|
|
127
131
|
gap="2"
|
|
128
132
|
>
|
|
129
133
|
<div
|
|
130
|
-
className="envive-tw-no-scrollbar envive-tw-relative envive-tw-w-full envive-tw-overflow-x-scroll"
|
|
131
134
|
ref={setRef1}
|
|
132
|
-
|
|
135
|
+
className="[&::-webkit-scrollbar]:hidden envive-tw-flex envive-tw-gap-2 envive-tw-overflow-x-auto"
|
|
136
|
+
style={{
|
|
137
|
+
scrollbarWidth: 'none',
|
|
138
|
+
msOverflowStyle: 'none',
|
|
139
|
+
cursor: 'grab',
|
|
140
|
+
userSelect: 'none',
|
|
141
|
+
}}
|
|
133
142
|
>
|
|
134
|
-
|
|
135
|
-
<Stack
|
|
136
|
-
direction="row"
|
|
137
|
-
gap="2"
|
|
138
|
-
className="envive-tw-pl-0 envive-tw-h-full envive-tw-items-center"
|
|
139
|
-
>
|
|
140
|
-
{renderButtonRow(visibleButtonsFirstRow, 0)}
|
|
141
|
-
</Stack>
|
|
142
|
-
</div>
|
|
143
|
+
{renderButtonRow(visibleButtonsFirstRow, 0)}
|
|
143
144
|
</div>
|
|
144
145
|
|
|
145
146
|
{shouldShowTwoRowsValue && (
|
|
146
147
|
<div
|
|
147
|
-
className="envive-tw-no-scrollbar envive-tw-relative envive-tw-w-full envive-tw-overflow-x-scroll"
|
|
148
148
|
ref={setRef2}
|
|
149
|
-
|
|
149
|
+
className="[&::-webkit-scrollbar]:hidden envive-tw-flex envive-tw-gap-2 envive-tw-overflow-x-auto"
|
|
150
|
+
style={{
|
|
151
|
+
scrollbarWidth: 'none',
|
|
152
|
+
msOverflowStyle: 'none',
|
|
153
|
+
cursor: 'grab',
|
|
154
|
+
userSelect: 'none',
|
|
155
|
+
}}
|
|
150
156
|
>
|
|
151
|
-
|
|
152
|
-
<Stack
|
|
153
|
-
direction="row"
|
|
154
|
-
gap="2"
|
|
155
|
-
className="envive-tw-pl-0 envive-tw-h-full envive-tw-items-center"
|
|
156
|
-
>
|
|
157
|
-
{renderButtonRow(visibleButtonsSecondRow, visibleButtonsFirstRow.length)}
|
|
158
|
-
</Stack>
|
|
159
|
-
</div>
|
|
157
|
+
{renderButtonRow(visibleButtonsSecondRow, visibleButtonsFirstRow.length)}
|
|
160
158
|
</div>
|
|
161
159
|
)}
|
|
162
160
|
</Stack>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback } from 'react';
|
|
1
|
+
import { useCallback, useMemo } from 'react';
|
|
2
2
|
import { AnimatedText } from '../AnimatedText';
|
|
3
3
|
import { Typography, TypographyColor } from '../Typography';
|
|
4
4
|
import { PromptCarousel, PromptCarouselRows } from '../PromptCarousel';
|
|
@@ -9,6 +9,7 @@ import { Theme } from '../Tokens';
|
|
|
9
9
|
import { WidgetWrapperWithTitle } from '../WidgetWrapperWithTitle';
|
|
10
10
|
import type { TypingAnimationProps } from './types';
|
|
11
11
|
import { useGetTypographyVariant } from './hooks/useGetTypographyVariant';
|
|
12
|
+
import { useAnimatedTextMinHeight } from '../utils/useAnimatedTextMinHeight';
|
|
12
13
|
import { Stack } from '../Stack';
|
|
13
14
|
|
|
14
15
|
export const TypingAnimation = ({
|
|
@@ -40,6 +41,15 @@ export const TypingAnimation = ({
|
|
|
40
41
|
|
|
41
42
|
const { handleButtonClick, handleTextFieldClick } = widgetEventProps || {};
|
|
42
43
|
const typographyVariant = useGetTypographyVariant(theme);
|
|
44
|
+
const { measuringRef, minHeight } = useAnimatedTextMinHeight(animatedTextSequence ?? []);
|
|
45
|
+
|
|
46
|
+
const biggestAnimatedText = useMemo(() => {
|
|
47
|
+
if (!animatedTextSequence || animatedTextSequence.length === 0) return '';
|
|
48
|
+
return animatedTextSequence.reduce(
|
|
49
|
+
(maxText, currText) => (currText.length > maxText.length ? currText : maxText),
|
|
50
|
+
'',
|
|
51
|
+
);
|
|
52
|
+
}, [animatedTextSequence]);
|
|
43
53
|
|
|
44
54
|
const getAnimatedTextWrapper = useCallback(
|
|
45
55
|
(text: string) => (
|
|
@@ -71,28 +81,64 @@ export const TypingAnimation = ({
|
|
|
71
81
|
>
|
|
72
82
|
{(headlineText || (animatedTextSequence && animatedTextSequence.length > 0)) &&
|
|
73
83
|
!isLoading && (
|
|
74
|
-
<
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
+
<div style={{ position: 'relative' }}>
|
|
85
|
+
<div
|
|
86
|
+
ref={measuringRef}
|
|
87
|
+
aria-hidden="true"
|
|
88
|
+
style={{
|
|
89
|
+
position: 'absolute',
|
|
90
|
+
visibility: 'hidden',
|
|
91
|
+
pointerEvents: 'none',
|
|
92
|
+
width: '100%',
|
|
93
|
+
}}
|
|
94
|
+
>
|
|
95
|
+
<p
|
|
96
|
+
className="envive-tw-max-w-[90ch]"
|
|
97
|
+
style={{ textAlign: 'left' }}
|
|
98
|
+
>
|
|
99
|
+
{headlineText && (
|
|
100
|
+
<Typography
|
|
101
|
+
variant={typographyVariant}
|
|
102
|
+
color={TypographyColor.TEXT_PRIMARY}
|
|
103
|
+
as="span"
|
|
104
|
+
>
|
|
105
|
+
{headlineText}
|
|
106
|
+
</Typography>
|
|
107
|
+
)}{' '}
|
|
108
|
+
<Typography
|
|
109
|
+
variant={typographyVariant}
|
|
110
|
+
color={TypographyColor.TEXT_ACCENT}
|
|
111
|
+
as="span"
|
|
112
|
+
>
|
|
113
|
+
{biggestAnimatedText}
|
|
114
|
+
</Typography>
|
|
115
|
+
</p>
|
|
116
|
+
</div>
|
|
117
|
+
<div style={{ minHeight }}>
|
|
118
|
+
<p
|
|
119
|
+
data-testid="typing-animation-headline-text"
|
|
120
|
+
className="envive-tw-max-w-[90ch]"
|
|
121
|
+
style={{ textAlign: 'left' }}
|
|
84
122
|
>
|
|
85
|
-
{headlineText
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
123
|
+
{headlineText && (
|
|
124
|
+
<Typography
|
|
125
|
+
variant={typographyVariant}
|
|
126
|
+
color={TypographyColor.TEXT_PRIMARY}
|
|
127
|
+
as="span"
|
|
128
|
+
>
|
|
129
|
+
{headlineText}
|
|
130
|
+
</Typography>
|
|
131
|
+
)}{' '}
|
|
132
|
+
{animatedTextSequence && animatedTextSequence.length > 0 ? (
|
|
133
|
+
<AnimatedText
|
|
134
|
+
sequence={animatedTextSequence}
|
|
135
|
+
loop
|
|
136
|
+
getNodeWrapper={getAnimatedTextWrapper}
|
|
137
|
+
/>
|
|
138
|
+
) : null}
|
|
139
|
+
</p>
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|
|
96
142
|
)}
|
|
97
143
|
{promptButtonTexts && promptButtonTexts.length > 0 && handleButtonClick && (
|
|
98
144
|
<PromptCarousel
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
export const useAnimatedTextMinHeight = (animatedText: string[]) => {
|
|
4
|
+
const measuringRef = useRef<HTMLDivElement>(null);
|
|
5
|
+
const [minHeight, setMinHeight] = useState(0);
|
|
6
|
+
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
const updateMinHeight = () => {
|
|
9
|
+
if (!measuringRef.current) return;
|
|
10
|
+
let maxHeight = 0;
|
|
11
|
+
const { children } = measuringRef.current;
|
|
12
|
+
for (let i = 0; i < children.length; i += 1) {
|
|
13
|
+
maxHeight = Math.max(maxHeight, (children[i] as HTMLElement).offsetHeight);
|
|
14
|
+
}
|
|
15
|
+
setMinHeight(maxHeight);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
updateMinHeight();
|
|
19
|
+
|
|
20
|
+
const observer = new ResizeObserver(updateMinHeight);
|
|
21
|
+
if (measuringRef.current) {
|
|
22
|
+
observer.observe(measuringRef.current);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return () => observer.disconnect();
|
|
26
|
+
}, [animatedText]);
|
|
27
|
+
|
|
28
|
+
return { measuringRef, minHeight };
|
|
29
|
+
};
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
//#region src/components/ChatFooter/hooks/useGetButtonScrollProperties.ts
|
|
3
|
-
const useGetButtonScrollProperties = () => {
|
|
4
|
-
return {
|
|
5
|
-
buttonScrollClasses: [
|
|
6
|
-
"envive-tw-overflow-x-scroll",
|
|
7
|
-
"envive-tw-overflow-y-hidden",
|
|
8
|
-
"[&::-webkit-scrollbar]:hidden"
|
|
9
|
-
],
|
|
10
|
-
buttonScrollStyle: {
|
|
11
|
-
scrollbarWidth: "none",
|
|
12
|
-
msOverflowStyle: "none"
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
//#endregion
|
|
18
|
-
exports.useGetButtonScrollProperties = useGetButtonScrollProperties;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
//#region src/components/ChatFooter/hooks/useGetButtonScrollProperties.ts
|
|
2
|
-
const useGetButtonScrollProperties = () => {
|
|
3
|
-
return {
|
|
4
|
-
buttonScrollClasses: [
|
|
5
|
-
"envive-tw-overflow-x-scroll",
|
|
6
|
-
"envive-tw-overflow-y-hidden",
|
|
7
|
-
"[&::-webkit-scrollbar]:hidden"
|
|
8
|
-
],
|
|
9
|
-
buttonScrollStyle: {
|
|
10
|
-
scrollbarWidth: "none",
|
|
11
|
-
msOverflowStyle: "none"
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
//#endregion
|
|
17
|
-
export { useGetButtonScrollProperties };
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
|
|
2
|
-
const require_index = require('../../Typography/types/index.cjs');
|
|
3
|
-
const require_Typography = require('../../Typography/Typography.cjs');
|
|
4
|
-
let react_jsx_runtime = require("react/jsx-runtime");
|
|
5
|
-
|
|
6
|
-
//#region src/components/MarkdownProcessor/components/MarkdownSubscript.tsx
|
|
7
|
-
const MarkdownSubscript = ({ children, subTextVariant, subTextColor }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Typography.Typography, {
|
|
8
|
-
variant: subTextVariant ?? require_index.TypographyVariant.B5_RG,
|
|
9
|
-
color: subTextColor ?? require_index.TypographyColor.TEXT_SECONDARY,
|
|
10
|
-
className: "envive-tw-inline",
|
|
11
|
-
children
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
//#endregion
|
|
15
|
-
exports.MarkdownSubscript = MarkdownSubscript;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { TypographyColor, TypographyVariant } from "../../Typography/types/index.js";
|
|
2
|
-
import { Typography } from "../../Typography/Typography.js";
|
|
3
|
-
import { jsx } from "react/jsx-runtime";
|
|
4
|
-
|
|
5
|
-
//#region src/components/MarkdownProcessor/components/MarkdownSubscript.tsx
|
|
6
|
-
const MarkdownSubscript = ({ children, subTextVariant, subTextColor }) => /* @__PURE__ */ jsx(Typography, {
|
|
7
|
-
variant: subTextVariant ?? TypographyVariant.B5_RG,
|
|
8
|
-
color: subTextColor ?? TypographyColor.TEXT_SECONDARY,
|
|
9
|
-
className: "envive-tw-inline",
|
|
10
|
-
children
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
//#endregion
|
|
14
|
-
export { MarkdownSubscript };
|