@envive-ai/react-toolkit-v3 0.3.8 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/dist/AnimatedText/AnimatedText.cjs +1 -0
  2. package/dist/AnimatedText/AnimatedText.js +1 -0
  3. package/dist/CSSVariablesEditor/CssVariablesEditorComponent.d.cts +2 -2
  4. package/dist/CSSVariablesEditor/CssVariablesEditorComponent.d.ts +2 -2
  5. package/dist/CSSVariablesEditor/components/CSSVariablesEditor.cjs +1 -1
  6. package/dist/CSSVariablesEditor/components/CSSVariablesEditor.js +1 -1
  7. package/dist/Carousel/Carousel.d.cts +2 -2
  8. package/dist/Carousel/Carousel.d.ts +2 -2
  9. package/dist/Carousel/components/Container.cjs +1 -1
  10. package/dist/Carousel/components/Container.js +1 -1
  11. package/dist/ChatFooter/ChatFooter.d.cts +2 -2
  12. package/dist/ChatFooter/components/index.d.cts +3 -3
  13. package/dist/ChatFooter/components/index.d.ts +5 -5
  14. package/dist/ChatHeader/ChatHeader.d.cts +2 -2
  15. package/dist/ChatHeader/ChatHeader.d.ts +2 -2
  16. package/dist/ChatPreview/ChatPreview.cjs +13 -3
  17. package/dist/ChatPreview/ChatPreview.d.cts +2 -2
  18. package/dist/ChatPreview/ChatPreview.d.ts +2 -2
  19. package/dist/ChatPreview/ChatPreview.js +13 -3
  20. package/dist/ChatPreview/components/Message.cjs +1 -1
  21. package/dist/ChatPreview/components/Message.js +1 -1
  22. package/dist/ChatPreview/types/types.d.cts +5 -4
  23. package/dist/ChatPreview/types/types.d.ts +5 -4
  24. package/dist/ChatPreviewComparison/ChatPreviewComparison.cjs +13 -3
  25. package/dist/ChatPreviewComparison/ChatPreviewComparison.d.cts +2 -2
  26. package/dist/ChatPreviewComparison/ChatPreviewComparison.d.ts +2 -2
  27. package/dist/ChatPreviewComparison/ChatPreviewComparison.js +13 -3
  28. package/dist/ChatPreviewComparison/components/Message.cjs +1 -1
  29. package/dist/ChatPreviewComparison/components/Message.js +1 -1
  30. package/dist/ChatPreviewComparison/types/types.d.cts +4 -4
  31. package/dist/ChatPreviewComparison/types/types.d.ts +4 -4
  32. package/dist/ChatPreviewLoading/ChatPreviewLoading.cjs +1 -1
  33. package/dist/ChatPreviewLoading/ChatPreviewLoading.d.cts +2 -2
  34. package/dist/ChatPreviewLoading/ChatPreviewLoading.d.ts +2 -2
  35. package/dist/ChatPreviewLoading/ChatPreviewLoading.js +1 -1
  36. package/dist/Container/Container.d.cts +174 -174
  37. package/dist/Container/Container.d.ts +174 -174
  38. package/dist/DesignTokens/DesignTokensComponent.cjs +1 -1
  39. package/dist/DesignTokens/DesignTokensComponent.d.cts +2 -2
  40. package/dist/DesignTokens/DesignTokensComponent.d.ts +2 -2
  41. package/dist/DesignTokens/DesignTokensComponent.js +1 -1
  42. package/dist/DocumentRetrievalCard/DocumentRetrievalCard.d.ts +2 -2
  43. package/dist/FloatingButton/FloatingButton.d.cts +2 -2
  44. package/dist/FloatingButton/FloatingButton.d.ts +2 -2
  45. package/dist/FloatingChat/FloatingChat.cjs +4 -3
  46. package/dist/FloatingChat/FloatingChat.d.cts +2 -2
  47. package/dist/FloatingChat/FloatingChat.d.ts +2 -2
  48. package/dist/FloatingChat/FloatingChat.js +4 -3
  49. package/dist/FloatingChat/components/AgentMessage.cjs +9 -5
  50. package/dist/FloatingChat/components/AgentMessage.js +9 -5
  51. package/dist/FloatingChat/components/ChatMessages.cjs +1 -1
  52. package/dist/FloatingChat/components/ChatMessages.js +1 -1
  53. package/dist/FloatingChat/components/Layout.cjs +11 -11
  54. package/dist/FloatingChat/components/Layout.js +11 -11
  55. package/dist/FloatingChat/components/ModalSheet.cjs +1 -1
  56. package/dist/FloatingChat/components/ModalSheet.js +1 -1
  57. package/dist/FloatingChat/components/ReviewCardsCarousel.cjs +2 -1
  58. package/dist/FloatingChat/components/ReviewCardsCarousel.js +2 -1
  59. package/dist/FloatingChat/components/ScrollToBottomButton.cjs +1 -1
  60. package/dist/FloatingChat/components/ScrollToBottomButton.js +1 -1
  61. package/dist/Form/Form.cjs +1 -1
  62. package/dist/Form/Form.js +1 -1
  63. package/dist/Image/Image.d.cts +2 -2
  64. package/dist/Image/Image.d.ts +2 -2
  65. package/dist/ImageGallery/ImageGallery.d.cts +2 -2
  66. package/dist/ImageGallery/ImageGallery.d.ts +2 -2
  67. package/dist/ImageGallery/components/NormalLayout.cjs +1 -1
  68. package/dist/ImageGallery/components/NormalLayout.js +1 -1
  69. package/dist/MarkdownProcessor/MarkdownProcessor.cjs +1 -1
  70. package/dist/MarkdownProcessor/MarkdownProcessor.d.cts +2 -2
  71. package/dist/MarkdownProcessor/MarkdownProcessor.d.ts +2 -2
  72. package/dist/MarkdownProcessor/MarkdownProcessor.js +1 -1
  73. package/dist/Message/components/AgentContent.cjs +1 -1
  74. package/dist/Message/components/AgentContent.js +1 -1
  75. package/dist/ProductCard/ProductCard.cjs +9 -5
  76. package/dist/ProductCard/ProductCard.d.cts +2 -2
  77. package/dist/ProductCard/ProductCard.d.ts +2 -2
  78. package/dist/ProductCard/ProductCard.js +4 -1
  79. package/dist/ProductCard/components/Header.cjs +3 -3
  80. package/dist/ProductCard/components/Header.js +3 -3
  81. package/dist/PromptButton/PromptButton.d.cts +2 -2
  82. package/dist/PromptButton/PromptButton.d.ts +2 -2
  83. package/dist/PromptButtonCarouselWithImage/PromptButtonCarouselWithImage.cjs +3 -2
  84. package/dist/PromptButtonCarouselWithImage/PromptButtonCarouselWithImage.d.cts +2 -2
  85. package/dist/PromptButtonCarouselWithImage/PromptButtonCarouselWithImage.d.ts +2 -2
  86. package/dist/PromptButtonCarouselWithImage/PromptButtonCarouselWithImage.js +3 -2
  87. package/dist/PromptButtonCarouselWithImage/components/Layout.cjs +8 -3
  88. package/dist/PromptButtonCarouselWithImage/components/Layout.js +8 -3
  89. package/dist/PromptButtonCarouselWithImage/components/PromptButtonsCarousel.cjs +53 -3
  90. package/dist/PromptButtonCarouselWithImage/components/PromptButtonsCarousel.js +53 -3
  91. package/dist/PromptCarousel/PromptCarousel.cjs +70 -33
  92. package/dist/PromptCarousel/PromptCarousel.d.cts +2 -2
  93. package/dist/PromptCarousel/PromptCarousel.d.ts +2 -2
  94. package/dist/PromptCarousel/PromptCarousel.js +71 -34
  95. package/dist/PromptCarousel/hooks/index.cjs +2 -4
  96. package/dist/PromptCarousel/hooks/index.js +2 -4
  97. package/dist/PromptCarousel/hooks/useCoordinatedScrollAnimation.cjs +91 -0
  98. package/dist/PromptCarousel/hooks/useCoordinatedScrollAnimation.js +90 -0
  99. package/dist/PromptCarousel/hooks/useScrollSync.cjs +65 -0
  100. package/dist/PromptCarousel/hooks/useScrollSync.js +64 -0
  101. package/dist/ReviewCard/ReviewCard.cjs +1 -1
  102. package/dist/ReviewCard/ReviewCard.d.cts +2 -2
  103. package/dist/ReviewCard/ReviewCard.d.ts +2 -2
  104. package/dist/ReviewCard/ReviewCard.js +1 -1
  105. package/dist/ReviewCard/components/index.d.cts +6 -6
  106. package/dist/ReviewCard/components/index.d.ts +6 -6
  107. package/dist/SalesAgentProductCard/SalesAgentProductCard.d.cts +2 -2
  108. package/dist/SalesAgentProductCard/SalesAgentProductCard.d.ts +2 -2
  109. package/dist/SalesAgentProductCard/components/index.d.cts +8 -8
  110. package/dist/SalesAgentProductCard/components/index.d.ts +6 -6
  111. package/dist/SocialProof/SocialProof.d.cts +2 -2
  112. package/dist/SocialProof/SocialProof.d.ts +2 -2
  113. package/dist/SocialProof/components/Headline.cjs +1 -1
  114. package/dist/SocialProof/components/Headline.js +1 -1
  115. package/dist/SocialProof/components/LayoutSingle.cjs +1 -1
  116. package/dist/SocialProof/components/LayoutSingle.js +1 -1
  117. package/dist/Stack/Stack.d.cts +2 -2
  118. package/dist/Stack/Stack.d.ts +2 -2
  119. package/dist/Stack/hooks/useFormatStackChildren.cjs +1 -1
  120. package/dist/Stack/hooks/useFormatStackChildren.js +1 -1
  121. package/dist/Title/components/Image.cjs +1 -1
  122. package/dist/Title/components/Image.js +1 -1
  123. package/dist/TitledPromptCarousel/TitledPromptCarousel.d.cts +2 -2
  124. package/dist/TitledPromptCarousel/TitledPromptCarousel.d.ts +2 -2
  125. package/dist/TypingAnimation/TypingAnimation.cjs +2 -2
  126. package/dist/TypingAnimation/TypingAnimation.d.ts +2 -2
  127. package/dist/TypingAnimation/TypingAnimation.js +2 -2
  128. package/dist/Typography/Typography.d.cts +4 -4
  129. package/dist/Typography/Typography.d.ts +4 -4
  130. package/dist/WidgetTextField/WidgetTextField.cjs +11 -6
  131. package/dist/WidgetTextField/WidgetTextField.d.cts +3 -2
  132. package/dist/WidgetTextField/WidgetTextField.d.ts +3 -2
  133. package/dist/WidgetTextField/WidgetTextField.js +7 -2
  134. package/dist/WidgetTextField/components/FakeTextInput.cjs +2 -2
  135. package/dist/WidgetTextField/components/FakeTextInput.js +2 -2
  136. package/dist/WidgetTextField/components/Icon.cjs +10 -9
  137. package/dist/WidgetTextField/components/Icon.js +10 -9
  138. package/dist/WidgetTextField/components/Skeleton.cjs +1 -1
  139. package/dist/WidgetTextField/components/Skeleton.js +1 -1
  140. package/dist/WidgetTextField/types/types.d.cts +3 -0
  141. package/dist/WidgetTextField/types/types.d.ts +3 -0
  142. package/dist/WidgetWrapper/WidgetWrapper.d.cts +2 -2
  143. package/dist/WidgetWrapper/WidgetWrapper.d.ts +2 -2
  144. package/dist/WidgetWrapperWithTitle/WidgetWrapperWithTitle.d.cts +2 -2
  145. package/dist/WidgetWrapperWithTitle/WidgetWrapperWithTitle.d.ts +2 -2
  146. package/dist/styles.css +1 -1
  147. package/dist/utils/CustomIcon.cjs +1 -1
  148. package/dist/utils/CustomIcon.js +1 -1
  149. package/dist/utils/useDragToScroll.cjs +68 -0
  150. package/dist/utils/useDragToScroll.js +67 -0
  151. package/package.json +1 -1
  152. package/src/components/AnimatedText/AnimatedText.tsx +2 -0
  153. package/src/components/ChatPreview/ChatPreview.tsx +20 -3
  154. package/src/components/ChatPreview/types/types.ts +5 -4
  155. package/src/components/ChatPreviewComparison/ChatPreviewComparison.tsx +20 -3
  156. package/src/components/ChatPreviewComparison/types/types.ts +4 -4
  157. package/src/components/FloatingChat/FloatingChat.tsx +3 -2
  158. package/src/components/FloatingChat/components/AgentMessage.tsx +1 -0
  159. package/src/components/FloatingChat/components/Layout.tsx +7 -2
  160. package/src/components/FloatingChat/components/ReviewCardsCarousel.tsx +3 -0
  161. package/src/components/ProductCard/ProductCard.tsx +12 -1
  162. package/src/components/ProductCard/components/Header.tsx +10 -8
  163. package/src/components/PromptButtonCarouselWithImage/PromptButtonCarouselWithImage.tsx +6 -3
  164. package/src/components/PromptButtonCarouselWithImage/components/Layout.tsx +13 -4
  165. package/src/components/PromptButtonCarouselWithImage/components/PromptButtonsCarousel.tsx +63 -20
  166. package/src/components/PromptCarousel/PromptCarousel.tsx +88 -51
  167. package/src/components/PromptCarousel/hooks/index.ts +2 -4
  168. package/src/components/PromptCarousel/hooks/useCoordinatedScrollAnimation.ts +115 -0
  169. package/src/components/PromptCarousel/hooks/useHorizontalScrollAnimation.ts +71 -78
  170. package/src/components/PromptCarousel/hooks/useScrollSync.ts +83 -0
  171. package/src/components/WidgetTextField/WidgetTextField.tsx +9 -1
  172. package/src/components/WidgetTextField/components/FakeTextInput.tsx +6 -2
  173. package/src/components/WidgetTextField/components/Icon.tsx +43 -9
  174. package/src/components/WidgetTextField/types/types.ts +3 -0
  175. package/src/components/utils/useDragToScroll.ts +83 -0
  176. package/dist/PromptCarousel/components/BlockScrollContainer.cjs +0 -23
  177. package/dist/PromptCarousel/components/BlockScrollContainer.js +0 -21
  178. package/dist/PromptCarousel/components/ButtonContainerRow.cjs +0 -34
  179. package/dist/PromptCarousel/components/ButtonContainerRow.js +0 -32
  180. package/dist/PromptCarousel/components/CarouselContentWithBlockScroll.cjs +0 -45
  181. package/dist/PromptCarousel/components/CarouselContentWithBlockScroll.js +0 -44
  182. package/dist/PromptCarousel/components/CarouselContentWithRowScroll.cjs +0 -33
  183. package/dist/PromptCarousel/components/CarouselContentWithRowScroll.js +0 -32
  184. package/dist/PromptCarousel/components/index.cjs +0 -13
  185. package/dist/PromptCarousel/components/index.js +0 -13
  186. package/dist/PromptCarousel/hooks/useButtonScrollPosition.cjs +0 -79
  187. package/dist/PromptCarousel/hooks/useButtonScrollPosition.js +0 -78
  188. package/dist/PromptCarousel/hooks/useCarouselAnimation.cjs +0 -23
  189. package/dist/PromptCarousel/hooks/useCarouselAnimation.js +0 -22
  190. package/dist/PromptCarousel/hooks/useCarouselRefs.cjs +0 -20
  191. package/dist/PromptCarousel/hooks/useCarouselRefs.js +0 -19
  192. package/dist/PromptCarousel/hooks/useGetScrollProperties.cjs +0 -18
  193. package/dist/PromptCarousel/hooks/useGetScrollProperties.js +0 -17
  194. package/dist/PromptCarousel/hooks/useHorizontalScrollAnimation.cjs +0 -78
  195. package/dist/PromptCarousel/hooks/useHorizontalScrollAnimation.js +0 -77
  196. package/src/components/PromptCarousel/components/BlockScrollContainer.tsx +0 -34
  197. package/src/components/PromptCarousel/components/ButtonContainerRow.tsx +0 -46
  198. package/src/components/PromptCarousel/components/CarouselContentWithBlockScroll.tsx +0 -83
  199. package/src/components/PromptCarousel/components/CarouselContentWithRowScroll.tsx +0 -71
  200. package/src/components/PromptCarousel/components/index.ts +0 -9
  201. package/src/components/PromptCarousel/hooks/useButtonScrollPosition.ts +0 -128
  202. package/src/components/PromptCarousel/hooks/useCarouselAnimation.ts +0 -47
  203. package/src/components/PromptCarousel/hooks/useCarouselRefs.ts +0 -27
@@ -1,103 +1,96 @@
1
1
  import { useEffect, useRef } from 'react';
2
2
  import { AnimationSpeed } from '../types/types';
3
3
 
4
- export function useHorizontalScrollAnimation(
5
- scrollContainerRefs: React.RefObject<HTMLDivElement>[],
6
- onStopAll: (mouseX?: number, mouseY?: number) => void,
7
- animationSpeed: `${AnimationSpeed}` = 'none',
8
- ) {
9
- const animationRefs = useRef<(number | null)[]>([]);
10
- const lastTimestampRefs = useRef<(number | null)[]>([]);
11
- const accumulatedScrollRefs = useRef<number[]>([]);
12
- const isStoppedRef = useRef(false);
13
-
14
- useEffect(() => {
15
- if (animationSpeed === AnimationSpeed.NONE) {
16
- return undefined;
17
- }
18
-
19
- const containers = scrollContainerRefs
20
- .map(ref => ref.current)
21
- .filter((container): container is HTMLDivElement => container !== null);
22
-
23
- if (containers.length === 0) {
24
- return undefined;
25
- }
26
-
27
- animationRefs.current = containers.map(() => null);
28
- lastTimestampRefs.current = containers.map(() => null);
29
- accumulatedScrollRefs.current = containers.map(() => 0);
4
+ interface UseHorizontalScrollAnimationOptions {
5
+ scrollContainerRef: React.RefObject<HTMLDivElement>;
6
+ animationSpeed?: `${AnimationSpeed}`;
7
+ }
30
8
 
31
- const PIXELS_PER_SECOND = animationSpeed === AnimationSpeed.FAST ? 60 : 30;
9
+ export function useHorizontalScrollAnimation({
10
+ scrollContainerRef,
11
+ animationSpeed = AnimationSpeed.NONE,
12
+ }: UseHorizontalScrollAnimationOptions): void {
13
+ const resumeTimeoutRef = useRef<number | null>(null);
14
+ const scrollAnimationRef = useRef<number | null>(null);
15
+
16
+ let PIXELS_PER_SECOND = 0;
17
+ switch (animationSpeed) {
18
+ case AnimationSpeed.FAST:
19
+ PIXELS_PER_SECOND = 60;
20
+ break;
21
+ case AnimationSpeed.SLOW:
22
+ PIXELS_PER_SECOND = 30;
23
+ break;
24
+ default:
25
+ PIXELS_PER_SECOND = 0;
26
+ }
27
+ const RESUME_DELAY_MS = 1500;
28
+ const isAnimated = animationSpeed !== AnimationSpeed.NONE;
32
29
 
33
- const cancelAllAnimations = () => {
34
- animationRefs.current.forEach(rafId => {
35
- if (rafId !== null) {
36
- cancelAnimationFrame(rafId);
37
- }
38
- });
39
- };
30
+ useEffect(() => {
31
+ if (!isAnimated || !scrollContainerRef) return undefined;
40
32
 
41
- const createAnimationLoop = (index: number) => {
42
- const step = (timestamp: number) => {
43
- if (isStoppedRef.current) return;
33
+ const container = scrollContainerRef.current;
34
+ if (!container) return undefined;
35
+ if (container.scrollWidth <= container.clientWidth) return undefined;
44
36
 
45
- const container = containers[index];
46
- if (!container || container.scrollWidth <= container.clientWidth) {
47
- animationRefs.current[index] = requestAnimationFrame(step);
48
- return;
49
- }
37
+ let isPaused = false;
38
+ let lastTimestamp: number | null = null;
39
+ let accumulatedScroll = 0;
50
40
 
51
- if (lastTimestampRefs.current[index] === null) {
52
- lastTimestampRefs.current[index] = timestamp;
53
- }
41
+ const step = (timestamp: number) => {
42
+ if (lastTimestamp === null) lastTimestamp = timestamp;
43
+ if (!isPaused) {
44
+ const delta = timestamp - lastTimestamp;
45
+ lastTimestamp = timestamp;
54
46
 
55
- const delta = timestamp - lastTimestampRefs.current[index]!;
56
- lastTimestampRefs.current[index] = timestamp;
57
- accumulatedScrollRefs.current[index] += PIXELS_PER_SECOND * (delta / 1000);
47
+ accumulatedScroll += PIXELS_PER_SECOND * (delta / 1000);
58
48
 
59
- const pixelsToScroll = Math.floor(accumulatedScrollRefs.current[index]);
49
+ const pixelsToScroll = Math.floor(accumulatedScroll);
60
50
  if (pixelsToScroll > 0) {
61
- const newScrollLeft = container.scrollLeft + pixelsToScroll;
62
- const maxScroll = container.scrollWidth - container.clientWidth;
51
+ container.scrollLeft += pixelsToScroll;
52
+ accumulatedScroll -= pixelsToScroll;
63
53
 
64
- if (Math.ceil(newScrollLeft) >= maxScroll) {
54
+ if (Math.ceil(container.scrollLeft) >= container.scrollWidth - container.clientWidth) {
65
55
  container.scrollLeft = 0;
66
- accumulatedScrollRefs.current[index] = 0;
67
- } else {
68
- container.scrollLeft = newScrollLeft;
69
- accumulatedScrollRefs.current[index] -= pixelsToScroll;
56
+ accumulatedScroll = 0;
70
57
  }
71
58
  }
59
+ }
60
+ scrollAnimationRef.current = requestAnimationFrame(step);
61
+ };
72
62
 
73
- if (!isStoppedRef.current) {
74
- animationRefs.current[index] = requestAnimationFrame(step);
75
- }
76
- };
63
+ // Start animation
64
+ scrollAnimationRef.current = requestAnimationFrame(step);
77
65
 
78
- return step;
66
+ const pauseAnimation = () => {
67
+ isPaused = true;
68
+ if (resumeTimeoutRef.current) {
69
+ clearTimeout(resumeTimeoutRef.current);
70
+ resumeTimeoutRef.current = null;
71
+ }
79
72
  };
80
73
 
81
- containers.forEach((container, index) => {
82
- animationRefs.current[index] = requestAnimationFrame(createAnimationLoop(index));
83
- });
84
-
85
- const handleMouseEnter = (event: MouseEvent) => {
86
- isStoppedRef.current = true;
87
- onStopAll(event.clientX, event.clientY);
88
- cancelAllAnimations();
74
+ const scheduleResumeAnimation = () => {
75
+ resumeTimeoutRef.current = window.setTimeout(() => {
76
+ isPaused = false;
77
+ lastTimestamp = null;
78
+ }, RESUME_DELAY_MS);
89
79
  };
90
80
 
91
- containers.forEach(container => {
92
- container.addEventListener('mouseenter', handleMouseEnter);
93
- });
81
+ // Attach pause/resume listeners for hover behavior
82
+ container.addEventListener('mouseenter', pauseAnimation);
83
+ container.addEventListener('mouseleave', scheduleResumeAnimation);
94
84
 
95
85
  return () => {
96
- isStoppedRef.current = true;
97
- cancelAllAnimations();
98
- containers.forEach(container => {
99
- container.removeEventListener('mouseenter', handleMouseEnter);
100
- });
86
+ if (scrollAnimationRef.current) {
87
+ cancelAnimationFrame(scrollAnimationRef.current);
88
+ }
89
+ container.removeEventListener('mouseenter', pauseAnimation);
90
+ container.removeEventListener('mouseleave', scheduleResumeAnimation);
91
+ if (resumeTimeoutRef.current) {
92
+ clearTimeout(resumeTimeoutRef.current);
93
+ }
101
94
  };
102
- }, [animationSpeed, scrollContainerRefs, onStopAll]);
95
+ }, [isAnimated, PIXELS_PER_SECOND, scrollContainerRef]);
103
96
  }
@@ -0,0 +1,83 @@
1
+ import { useEffect, useRef } from 'react';
2
+
3
+ interface UseScrollSyncOptions {
4
+ scrollContainerRefs: React.RefObject<HTMLDivElement>[];
5
+ enabled: boolean;
6
+ }
7
+
8
+ export function useScrollSync({ scrollContainerRefs, enabled }: UseScrollSyncOptions): void {
9
+ const isSyncingRef = useRef(false);
10
+ const isDraggingRef = useRef(false);
11
+
12
+ useEffect(() => {
13
+ if (!enabled || scrollContainerRefs.length === 0) return undefined;
14
+
15
+ const containers = scrollContainerRefs
16
+ .map(ref => ref.current)
17
+ .filter((el): el is HTMLDivElement => el !== null);
18
+
19
+ if (containers.length === 0) return undefined;
20
+
21
+ const handleScroll = (sourceContainer: HTMLDivElement) => {
22
+ // Only sync when user is actively dragging, not during auto-scroll animation
23
+ if (!isDraggingRef.current) return;
24
+ if (isSyncingRef.current) return;
25
+
26
+ isSyncingRef.current = true;
27
+ const { scrollLeft } = sourceContainer;
28
+
29
+ containers.forEach(container => {
30
+ if (container !== sourceContainer) {
31
+ const element = container;
32
+ element.scrollLeft = scrollLeft;
33
+ }
34
+ });
35
+
36
+ requestAnimationFrame(() => {
37
+ isSyncingRef.current = false;
38
+ });
39
+ };
40
+
41
+ const handleMouseDown = () => {
42
+ isDraggingRef.current = true;
43
+ };
44
+
45
+ const handleMouseUp = () => {
46
+ isDraggingRef.current = false;
47
+ };
48
+
49
+ // Prevent all trackpad and mouse wheel scrolling
50
+ const handleWheel = (e: WheelEvent) => {
51
+ e.preventDefault();
52
+ };
53
+
54
+ const scrollListeners = containers.map(container => {
55
+ const listener = () => handleScroll(container);
56
+ container.addEventListener('scroll', listener);
57
+ return { container, listener };
58
+ });
59
+
60
+ // Track mouse events to detect when user is dragging
61
+ containers.forEach(container => {
62
+ container.addEventListener('mousedown', handleMouseDown);
63
+ container.addEventListener('mouseup', handleMouseUp);
64
+ // Disable trackpad and mouse wheel scrolling
65
+ container.addEventListener('wheel', handleWheel, { passive: false });
66
+ });
67
+
68
+ // Also listen for mouseup on document in case user releases outside container
69
+ document.addEventListener('mouseup', handleMouseUp);
70
+
71
+ return () => {
72
+ scrollListeners.forEach(({ container, listener }) => {
73
+ container.removeEventListener('scroll', listener);
74
+ });
75
+ containers.forEach(container => {
76
+ container.removeEventListener('mousedown', handleMouseDown);
77
+ container.removeEventListener('mouseup', handleMouseUp);
78
+ container.removeEventListener('wheel', handleWheel);
79
+ });
80
+ document.removeEventListener('mouseup', handleMouseUp);
81
+ };
82
+ }, [enabled, scrollContainerRefs]);
83
+ }
@@ -1,4 +1,5 @@
1
1
  import { Theme } from '../../../tokens/theme/theme';
2
+ import { TypographyColor } from '../Typography/types';
2
3
  import { resolveTheme } from '../utils/resolveTheme';
3
4
  import { WidgetTextFieldComponents } from './components';
4
5
  import { IconVariant, type WidgetTextFieldProps } from './types/types';
@@ -10,6 +11,7 @@ export const WidgetTextField = ({
10
11
  className,
11
12
  theme = Theme.GLOBAL_CUSTOM,
12
13
  iconVariant = IconVariant.DEFAULT,
14
+ textColor = TypographyColor.TEXT_SECONDARY,
13
15
  placeholder,
14
16
  ariaLabel,
15
17
  disabled,
@@ -34,11 +36,17 @@ export const WidgetTextField = ({
34
36
  ariaLabel={ariaLabel}
35
37
  icon={
36
38
  <WidgetTextFieldComponents.Icon
39
+ textColor={textColor}
37
40
  variant={iconVariant}
38
41
  theme={resolvedTheme}
39
42
  />
40
43
  }
41
- text={<WidgetTextFieldComponents.FakeTextInput placeholder={placeholder} />}
44
+ text={
45
+ <WidgetTextFieldComponents.FakeTextInput
46
+ placeholder={placeholder}
47
+ textColor={textColor}
48
+ />
49
+ }
42
50
  />
43
51
  );
44
52
  };
@@ -3,13 +3,17 @@ import { TypographyColor, TypographyVariant } from '../../Typography/types';
3
3
 
4
4
  type FakeTextInputProps = {
5
5
  placeholder: string;
6
+ textColor: TypographyColor;
6
7
  };
7
8
 
8
- export const FakeTextInput = ({ placeholder }: FakeTextInputProps) => {
9
+ export const FakeTextInput = ({
10
+ placeholder,
11
+ textColor = TypographyColor.TEXT_SECONDARY,
12
+ }: FakeTextInputProps) => {
9
13
  return (
10
14
  <Typography
11
15
  variant={TypographyVariant.B3_RG}
12
- color={TypographyColor.TEXT_SECONDARY}
16
+ color={textColor}
13
17
  noWrap
14
18
  >
15
19
  {placeholder}
@@ -6,20 +6,26 @@ import SendStandard from '@envive-ai/react-icons/SendStandard';
6
6
  import { Theme } from '../../../../tokens/theme/theme';
7
7
  import { CustomIcon } from '../../utils/CustomIcon';
8
8
  import { IconVariant } from '../types/types';
9
+ import { TypographyColor } from '../../Typography/types';
9
10
 
10
11
  type IconProps = {
11
12
  theme: Theme;
12
13
  variant: IconVariant;
14
+ textColor: TypographyColor;
13
15
  };
14
16
 
15
- export const Icon = ({ variant, theme }: IconProps) => {
17
+ export const Icon = ({ variant, theme, textColor }: IconProps) => {
16
18
  if (theme === Theme.STANDARD) {
17
19
  if (variant === IconVariant.DEFAULT) {
18
20
  return (
19
21
  <CustomIcon
20
22
  IconComponent={<SendStandard />}
21
23
  className="envive-tw-h-6 envive-tw-w-6"
22
- fill="var(--envive-colors-border-medium)"
24
+ fill={
25
+ textColor !== TypographyColor.TEXT_SECONDARY
26
+ ? `var(--envive-colors-${textColor})`
27
+ : 'var(--envive-colors-border-medium)'
28
+ }
23
29
  />
24
30
  );
25
31
  }
@@ -27,7 +33,11 @@ export const Icon = ({ variant, theme }: IconProps) => {
27
33
  <CustomIcon
28
34
  IconComponent={<SvgSendStandard />}
29
35
  className="envive-tw-h-6 envive-tw-w-6"
30
- fill="var(--envive-colors-border-medium)"
36
+ fill={
37
+ textColor !== TypographyColor.TEXT_SECONDARY
38
+ ? `var(--envive-colors-${textColor})`
39
+ : 'var(--envive-colors-border-medium)'
40
+ }
31
41
  />
32
42
  );
33
43
  }
@@ -38,7 +48,11 @@ export const Icon = ({ variant, theme }: IconProps) => {
38
48
  <CustomIcon
39
49
  IconComponent={<SendModern />}
40
50
  className="envive-tw-h-6 envive-tw-w-6"
41
- fill="var(--envive-colors-border-medium)"
51
+ fill={
52
+ textColor !== TypographyColor.TEXT_SECONDARY
53
+ ? `var(--envive-colors-${textColor})`
54
+ : 'var(--envive-colors-border-medium)'
55
+ }
42
56
  />
43
57
  );
44
58
  }
@@ -46,7 +60,11 @@ export const Icon = ({ variant, theme }: IconProps) => {
46
60
  <CustomIcon
47
61
  IconComponent={<SvgSendModern />}
48
62
  className="envive-tw-h-6 envive-tw-w-6"
49
- stroke="var(--envive-colors-border-medium)"
63
+ stroke={
64
+ textColor !== TypographyColor.TEXT_SECONDARY
65
+ ? `var(--envive-colors-${textColor})`
66
+ : 'var(--envive-colors-border-medium)'
67
+ }
50
68
  />
51
69
  );
52
70
  }
@@ -57,7 +75,11 @@ export const Icon = ({ variant, theme }: IconProps) => {
57
75
  <CustomIcon
58
76
  IconComponent={<SendMinimalist />}
59
77
  className="envive-tw-h-6 envive-tw-w-6"
60
- stroke="var(--envive-colors-text-secondary)"
78
+ stroke={
79
+ textColor !== TypographyColor.TEXT_SECONDARY
80
+ ? `var(--envive-colors-${textColor})`
81
+ : 'var(--envive-colors-text-secondary)'
82
+ }
61
83
  />
62
84
  );
63
85
  }
@@ -65,7 +87,11 @@ export const Icon = ({ variant, theme }: IconProps) => {
65
87
  <CustomIcon
66
88
  IconComponent={<SendMinimalist />}
67
89
  className="envive-tw-h-6 envive-tw-w-6"
68
- stroke="var(--envive-colors-text-light)"
90
+ stroke={
91
+ textColor !== TypographyColor.TEXT_SECONDARY
92
+ ? `var(--envive-colors-${textColor})`
93
+ : 'var(--envive-colors-text-light)'
94
+ }
69
95
  />
70
96
  );
71
97
  }
@@ -75,7 +101,11 @@ export const Icon = ({ variant, theme }: IconProps) => {
75
101
  <CustomIcon
76
102
  IconComponent={<SendStandard />}
77
103
  className="envive-tw-h-6 envive-tw-w-6"
78
- fill="var(--envive-colors-border-medium)"
104
+ fill={
105
+ textColor !== TypographyColor.TEXT_SECONDARY
106
+ ? `var(--envive-colors-${textColor})`
107
+ : 'var(--envive-colors-border-medium)'
108
+ }
79
109
  />
80
110
  );
81
111
  }
@@ -84,7 +114,11 @@ export const Icon = ({ variant, theme }: IconProps) => {
84
114
  <CustomIcon
85
115
  IconComponent={<SvgSendStandard />}
86
116
  className="envive-tw-h-6 envive-tw-w-6"
87
- fill="var(--envive-colors-border-medium)"
117
+ fill={
118
+ textColor !== TypographyColor.TEXT_SECONDARY
119
+ ? `var(--envive-colors-${textColor})`
120
+ : 'var(--envive-colors-border-medium)'
121
+ }
88
122
  />
89
123
  );
90
124
  };
@@ -1,4 +1,5 @@
1
1
  import { Theme } from '../../../../tokens/theme/theme';
2
+ import { TypographyColor } from '../../Typography/types';
2
3
 
3
4
  /**
4
5
  * Props for the WidgetTextField component.
@@ -33,6 +34,8 @@ export type WidgetTextFieldProps = {
33
34
  placeholder?: string;
34
35
  /** Accessible label for screen readers. If not provided, the placeholder will be used. */
35
36
  ariaLabel?: string;
37
+ /** Text color for the text field. */
38
+ textColor?: TypographyColor;
36
39
  /** Whether the text field is disabled. */
37
40
  disabled?: boolean;
38
41
  /**
@@ -0,0 +1,83 @@
1
+ import { useEffect, useRef } from 'react';
2
+
3
+ type DragDirection = 'x' | 'y';
4
+
5
+ type UseDragToScrollOptions = {
6
+ direction: DragDirection;
7
+ isEnabled?: boolean;
8
+ };
9
+
10
+ /**
11
+ * Hook to enable drag-to-scroll on a container (mouse or touch).
12
+ * Uses the same ref as the scroll container so it can be composed with useHorizontalWheelScroll.
13
+ */
14
+ export const useDragToScroll = (
15
+ scrollContainerRef: React.RefObject<HTMLDivElement | null>,
16
+ options: UseDragToScrollOptions,
17
+ ) => {
18
+ const { direction, isEnabled = true } = options;
19
+ const dragRef = useRef({
20
+ isDragging: false,
21
+ startX: 0,
22
+ startY: 0,
23
+ startScrollLeft: 0,
24
+ startScrollTop: 0,
25
+ });
26
+
27
+ useEffect(() => {
28
+ if (!isEnabled || !scrollContainerRef.current) {
29
+ return undefined;
30
+ }
31
+
32
+ const container = scrollContainerRef.current;
33
+
34
+ const handlePointerDown = (e: PointerEvent) => {
35
+ if (e.button !== 0) return;
36
+ dragRef.current = {
37
+ isDragging: true,
38
+ startX: e.clientX,
39
+ startY: e.clientY,
40
+ startScrollLeft: container.scrollLeft,
41
+ startScrollTop: container.scrollTop,
42
+ };
43
+ container.setPointerCapture(e.pointerId);
44
+ container.style.cursor = 'grabbing';
45
+ container.style.userSelect = 'none';
46
+ };
47
+
48
+ const handlePointerMove = (e: PointerEvent) => {
49
+ const { isDragging, startX, startY, startScrollLeft, startScrollTop } = dragRef.current;
50
+ if (!isDragging) return;
51
+
52
+ e.preventDefault();
53
+ if (direction === 'x') {
54
+ container.scrollLeft = startScrollLeft + (startX - e.clientX);
55
+ } else {
56
+ container.scrollTop = startScrollTop + (startY - e.clientY);
57
+ }
58
+ };
59
+
60
+ const handlePointerUp = (e: PointerEvent) => {
61
+ if (e.button !== 0) return;
62
+ dragRef.current.isDragging = false;
63
+ container.releasePointerCapture(e.pointerId);
64
+ container.style.cursor = 'grab';
65
+ container.style.userSelect = '';
66
+ };
67
+
68
+ container.style.cursor = 'grab';
69
+
70
+ container.addEventListener('pointerdown', handlePointerDown);
71
+ container.addEventListener('pointermove', handlePointerMove, { passive: false });
72
+ container.addEventListener('pointerup', handlePointerUp);
73
+ container.addEventListener('pointercancel', handlePointerUp);
74
+
75
+ return () => {
76
+ container.removeEventListener('pointerdown', handlePointerDown);
77
+ container.removeEventListener('pointermove', handlePointerMove);
78
+ container.removeEventListener('pointerup', handlePointerUp);
79
+ container.removeEventListener('pointercancel', handlePointerUp);
80
+ container.style.cursor = '';
81
+ };
82
+ }, [isEnabled, direction, scrollContainerRef]);
83
+ };
@@ -1,23 +0,0 @@
1
- const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
2
- const require_useGetScrollProperties = require('../hooks/useGetScrollProperties.cjs');
3
- let react_jsx_runtime = require("react/jsx-runtime");
4
- let classnames = require("classnames");
5
- classnames = require_rolldown_runtime.__toESM(classnames);
6
-
7
- //#region src/components/PromptCarousel/components/BlockScrollContainer.tsx
8
- const BlockScrollContainer = ({ children, scrollRef, className, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy }) => {
9
- const { scrollStyle, scrollClasses } = require_useGetScrollProperties.useGetScrollProperties();
10
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
11
- ref: scrollRef,
12
- className: (0, classnames.default)(...scrollClasses, className),
13
- style: scrollStyle,
14
- role: "group",
15
- "aria-label": ariaLabel,
16
- "aria-labelledby": ariaLabelledBy,
17
- tabIndex: 0,
18
- children
19
- });
20
- };
21
-
22
- //#endregion
23
- exports.BlockScrollContainer = BlockScrollContainer;
@@ -1,21 +0,0 @@
1
- import { useGetScrollProperties } from "../hooks/useGetScrollProperties.js";
2
- import { jsx } from "react/jsx-runtime";
3
- import classNames from "classnames";
4
-
5
- //#region src/components/PromptCarousel/components/BlockScrollContainer.tsx
6
- const BlockScrollContainer = ({ children, scrollRef, className, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy }) => {
7
- const { scrollStyle, scrollClasses } = useGetScrollProperties();
8
- return /* @__PURE__ */ jsx("div", {
9
- ref: scrollRef,
10
- className: classNames(...scrollClasses, className),
11
- style: scrollStyle,
12
- role: "group",
13
- "aria-label": ariaLabel,
14
- "aria-labelledby": ariaLabelledBy,
15
- tabIndex: 0,
16
- children
17
- });
18
- };
19
-
20
- //#endregion
21
- export { BlockScrollContainer };
@@ -1,34 +0,0 @@
1
- const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
2
- const require_Stack = require('../../Stack/Stack.cjs');
3
- require('../../Stack/index.cjs');
4
- const require_useGetScrollProperties = require('../hooks/useGetScrollProperties.cjs');
5
- let react_jsx_runtime = require("react/jsx-runtime");
6
- let classnames = require("classnames");
7
- classnames = require_rolldown_runtime.__toESM(classnames);
8
-
9
- //#region src/components/PromptCarousel/components/ButtonContainerRow.tsx
10
- const ButtonContainerRow = ({ children, scrollRef, stackRef, className, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy }) => {
11
- const { scrollStyle, scrollClasses } = require_useGetScrollProperties.useGetScrollProperties();
12
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
13
- ref: scrollRef,
14
- className: (0, classnames.default)(...scrollClasses, className),
15
- style: scrollStyle,
16
- role: "group",
17
- "aria-label": ariaLabel,
18
- "aria-labelledby": ariaLabelledBy,
19
- tabIndex: 0,
20
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
21
- ref: stackRef,
22
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Stack.Stack, {
23
- direction: "row",
24
- align: "center",
25
- gap: "2",
26
- className: "envive-tw-h-full envive-tw-w-max envive-tw-whitespace-nowrap",
27
- children
28
- })
29
- })
30
- });
31
- };
32
-
33
- //#endregion
34
- exports.ButtonContainerRow = ButtonContainerRow;
@@ -1,32 +0,0 @@
1
- import { Stack } from "../../Stack/Stack.js";
2
- import "../../Stack/index.js";
3
- import { useGetScrollProperties } from "../hooks/useGetScrollProperties.js";
4
- import { jsx } from "react/jsx-runtime";
5
- import classNames from "classnames";
6
-
7
- //#region src/components/PromptCarousel/components/ButtonContainerRow.tsx
8
- const ButtonContainerRow = ({ children, scrollRef, stackRef, className, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy }) => {
9
- const { scrollStyle, scrollClasses } = useGetScrollProperties();
10
- return /* @__PURE__ */ jsx("div", {
11
- ref: scrollRef,
12
- className: classNames(...scrollClasses, className),
13
- style: scrollStyle,
14
- role: "group",
15
- "aria-label": ariaLabel,
16
- "aria-labelledby": ariaLabelledBy,
17
- tabIndex: 0,
18
- children: /* @__PURE__ */ jsx("div", {
19
- ref: stackRef,
20
- children: /* @__PURE__ */ jsx(Stack, {
21
- direction: "row",
22
- align: "center",
23
- gap: "2",
24
- className: "envive-tw-h-full envive-tw-w-max envive-tw-whitespace-nowrap",
25
- children
26
- })
27
- })
28
- });
29
- };
30
-
31
- //#endregion
32
- export { ButtonContainerRow };