@wallarm-org/design-system 3.2.0 → 3.3.0

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 (169) hide show
  1. package/dist/components/AnimatedBackground/blur/BlurBackground.d.ts +6 -0
  2. package/dist/components/AnimatedBackground/blur/BlurBackground.js +176 -76
  3. package/dist/components/AnimatedBackground/blur/index.d.ts +1 -1
  4. package/dist/components/AnimatedBackground/index.d.ts +1 -1
  5. package/dist/components/ApprovalCard/ApprovalCard.d.ts +13 -0
  6. package/dist/components/ApprovalCard/ApprovalCard.js +249 -0
  7. package/dist/components/ApprovalCard/ApprovalCardActions.d.ts +6 -0
  8. package/dist/components/ApprovalCard/ApprovalCardActions.js +50 -0
  9. package/dist/components/ApprovalCard/ApprovalCardContent.d.ts +6 -0
  10. package/dist/components/ApprovalCard/ApprovalCardContent.js +50 -0
  11. package/dist/components/ApprovalCard/classes.d.ts +10 -0
  12. package/dist/components/ApprovalCard/classes.js +26 -0
  13. package/dist/components/ApprovalCard/index.d.ts +3 -0
  14. package/dist/components/ApprovalCard/index.js +3 -0
  15. package/dist/components/AssistantMessage/AssistantMessage.d.ts +12 -0
  16. package/dist/components/AssistantMessage/AssistantMessage.js +66 -0
  17. package/dist/components/AssistantMessage/AssistantMessageContent.d.ts +10 -0
  18. package/dist/components/AssistantMessage/AssistantMessageContent.js +50 -0
  19. package/dist/components/AssistantMessage/AssistantMessageError.d.ts +13 -0
  20. package/dist/components/AssistantMessage/AssistantMessageError.js +93 -0
  21. package/dist/components/AssistantMessage/AssistantMessageLoader.d.ts +13 -0
  22. package/dist/components/AssistantMessage/AssistantMessageLoader.js +88 -0
  23. package/dist/components/AssistantMessage/AssistantMessageMarkdown.d.ts +71 -0
  24. package/dist/components/AssistantMessage/AssistantMessageMarkdown.js +278 -0
  25. package/dist/components/AssistantMessage/AssistantMessageMarkdownCodeBlock.d.ts +17 -0
  26. package/dist/components/AssistantMessage/AssistantMessageMarkdownCodeBlock.js +94 -0
  27. package/dist/components/AssistantMessage/AssistantMessageMarkdownInlineCode.d.ts +10 -0
  28. package/dist/components/AssistantMessage/AssistantMessageMarkdownInlineCode.js +59 -0
  29. package/dist/components/AssistantMessage/AssistantMessageMarkdownLink.d.ts +14 -0
  30. package/dist/components/AssistantMessage/AssistantMessageMarkdownLink.js +65 -0
  31. package/dist/components/AssistantMessage/AssistantMessageMarkdownTable.d.ts +7 -0
  32. package/dist/components/AssistantMessage/AssistantMessageMarkdownTable.js +70 -0
  33. package/dist/components/AssistantMessage/classes.d.ts +38 -0
  34. package/dist/components/AssistantMessage/classes.js +46 -0
  35. package/dist/components/AssistantMessage/index.d.ts +9 -0
  36. package/dist/components/AssistantMessage/index.js +9 -0
  37. package/dist/components/AssistantMessage/lib/markdown.d.ts +20 -0
  38. package/dist/components/AssistantMessage/lib/markdown.js +51 -0
  39. package/dist/components/ChainOfThought/ChainOfThought.d.ts +10 -0
  40. package/dist/components/ChainOfThought/ChainOfThought.js +66 -0
  41. package/dist/components/ChainOfThought/ChainOfThoughtStep.d.ts +31 -0
  42. package/dist/components/ChainOfThought/ChainOfThoughtStep.js +312 -0
  43. package/dist/components/ChainOfThought/classes.d.ts +20 -0
  44. package/dist/components/ChainOfThought/classes.js +84 -0
  45. package/dist/components/ChainOfThought/index.d.ts +2 -0
  46. package/dist/components/ChainOfThought/index.js +2 -0
  47. package/dist/components/Chat/Chat.d.ts +12 -0
  48. package/dist/components/Chat/Chat.js +90 -0
  49. package/dist/components/Chat/ChatBody.d.ts +12 -0
  50. package/dist/components/Chat/ChatBody.js +52 -0
  51. package/dist/components/Chat/ChatFooter.d.ts +7 -0
  52. package/dist/components/Chat/ChatFooter.js +50 -0
  53. package/dist/components/Chat/ChatGreeting.d.ts +8 -0
  54. package/dist/components/Chat/ChatGreeting.js +94 -0
  55. package/dist/components/Chat/ChatHeader.d.ts +6 -0
  56. package/dist/components/Chat/ChatHeader.js +50 -0
  57. package/dist/components/Chat/ChatHeaderActions.d.ts +7 -0
  58. package/dist/components/Chat/ChatHeaderActions.js +50 -0
  59. package/dist/components/Chat/ChatHeaderTitle.d.ts +12 -0
  60. package/dist/components/Chat/ChatHeaderTitle.js +99 -0
  61. package/dist/components/Chat/ChatSuggestion.d.ts +7 -0
  62. package/dist/components/Chat/ChatSuggestion.js +56 -0
  63. package/dist/components/Chat/ChatSuggestions.d.ts +14 -0
  64. package/dist/components/Chat/ChatSuggestions.js +111 -0
  65. package/dist/components/Chat/ChatSuggestionsContext.d.ts +7 -0
  66. package/dist/components/Chat/ChatSuggestionsContext.js +7 -0
  67. package/dist/components/Chat/ChatTrigger.d.ts +13 -0
  68. package/dist/components/Chat/ChatTrigger.js +101 -0
  69. package/dist/components/Chat/classes.d.ts +17 -0
  70. package/dist/components/Chat/classes.js +44 -0
  71. package/dist/components/Chat/index.d.ts +10 -0
  72. package/dist/components/Chat/index.js +10 -0
  73. package/dist/components/ChatInput/ChatInput.d.ts +30 -0
  74. package/dist/components/ChatInput/ChatInput.js +230 -0
  75. package/dist/components/ChatInput/ChatInputContext.d.ts +11 -0
  76. package/dist/components/ChatInput/ChatInputContext.js +8 -0
  77. package/dist/components/ChatInput/ChatInputSubmit.d.ts +10 -0
  78. package/dist/components/ChatInput/ChatInputSubmit.js +175 -0
  79. package/dist/components/ChatInput/ChatInputTextarea.d.ts +6 -0
  80. package/dist/components/ChatInput/ChatInputTextarea.js +155 -0
  81. package/dist/components/ChatInput/classes.d.ts +9 -0
  82. package/dist/components/ChatInput/classes.js +22 -0
  83. package/dist/components/ChatInput/index.d.ts +3 -0
  84. package/dist/components/ChatInput/index.js +3 -0
  85. package/dist/components/ChatPermissions/ChatPermissions.d.ts +12 -0
  86. package/dist/components/ChatPermissions/ChatPermissions.js +66 -0
  87. package/dist/components/ChatPermissions/ChatPermissionsContent.d.ts +7 -0
  88. package/dist/components/ChatPermissions/ChatPermissionsContent.js +73 -0
  89. package/dist/components/ChatPermissions/ChatPermissionsContext.d.ts +7 -0
  90. package/dist/components/ChatPermissions/ChatPermissionsContext.js +8 -0
  91. package/dist/components/ChatPermissions/ChatPermissionsItem.d.ts +17 -0
  92. package/dist/components/ChatPermissions/ChatPermissionsItem.js +115 -0
  93. package/dist/components/ChatPermissions/ChatPermissionsTrigger.d.ts +6 -0
  94. package/dist/components/ChatPermissions/ChatPermissionsTrigger.js +110 -0
  95. package/dist/components/ChatPermissions/classes.d.ts +3 -0
  96. package/dist/components/ChatPermissions/classes.js +5 -0
  97. package/dist/components/ChatPermissions/index.d.ts +4 -0
  98. package/dist/components/ChatPermissions/index.js +4 -0
  99. package/dist/components/Conversation/Conversation.d.ts +19 -0
  100. package/dist/components/Conversation/Conversation.js +102 -0
  101. package/dist/components/Conversation/ConversationContent.d.ts +11 -0
  102. package/dist/components/Conversation/ConversationContent.js +103 -0
  103. package/dist/components/Conversation/ConversationContext.d.ts +14 -0
  104. package/dist/components/Conversation/ConversationContext.js +8 -0
  105. package/dist/components/Conversation/ConversationEmptyState.d.ts +15 -0
  106. package/dist/components/Conversation/ConversationEmptyState.js +70 -0
  107. package/dist/components/Conversation/ConversationScrollButton.d.ts +13 -0
  108. package/dist/components/Conversation/ConversationScrollButton.js +138 -0
  109. package/dist/components/Conversation/classes.d.ts +13 -0
  110. package/dist/components/Conversation/classes.js +8 -0
  111. package/dist/components/Conversation/index.d.ts +4 -0
  112. package/dist/components/Conversation/index.js +4 -0
  113. package/dist/components/Conversation/useStickToBottom.d.ts +9 -0
  114. package/dist/components/Conversation/useStickToBottom.js +203 -0
  115. package/dist/components/MessageActions/MessageAction.d.ts +18 -0
  116. package/dist/components/MessageActions/MessageAction.js +109 -0
  117. package/dist/components/MessageActions/MessageActions.d.ts +12 -0
  118. package/dist/components/MessageActions/MessageActions.js +74 -0
  119. package/dist/components/MessageActions/MessageTimestamp.d.ts +7 -0
  120. package/dist/components/MessageActions/MessageTimestamp.js +50 -0
  121. package/dist/components/MessageActions/classes.d.ts +5 -0
  122. package/dist/components/MessageActions/classes.js +15 -0
  123. package/dist/components/MessageActions/index.d.ts +3 -0
  124. package/dist/components/MessageActions/index.js +3 -0
  125. package/dist/components/Popover/PopoverContent.d.ts +2 -1
  126. package/dist/components/Popover/PopoverContent.js +42 -39
  127. package/dist/components/UserMessage/UserMessage.d.ts +10 -0
  128. package/dist/components/UserMessage/UserMessage.js +66 -0
  129. package/dist/components/UserMessage/UserMessageBubble.d.ts +16 -0
  130. package/dist/components/UserMessage/UserMessageBubble.js +175 -0
  131. package/dist/components/UserMessage/UserMessageContext.d.ts +9 -0
  132. package/dist/components/UserMessage/UserMessageContext.js +4 -0
  133. package/dist/components/UserMessage/UserMessageShowMore.d.ts +15 -0
  134. package/dist/components/UserMessage/UserMessageShowMore.js +87 -0
  135. package/dist/components/UserMessage/classes.d.ts +11 -0
  136. package/dist/components/UserMessage/classes.js +32 -0
  137. package/dist/components/UserMessage/index.d.ts +3 -0
  138. package/dist/components/UserMessage/index.js +3 -0
  139. package/dist/components/WallyAssistant/WallyAssistant.d.ts +56 -0
  140. package/dist/components/WallyAssistant/WallyAssistant.js +541 -0
  141. package/dist/components/WallyAssistant/index.d.ts +10 -0
  142. package/dist/components/WallyAssistant/index.js +8 -0
  143. package/dist/components/WallyAssistant/model/deriveChatState.d.ts +33 -0
  144. package/dist/components/WallyAssistant/model/deriveChatState.js +54 -0
  145. package/dist/components/WallyAssistant/model/labels.d.ts +43 -0
  146. package/dist/components/WallyAssistant/model/labels.js +33 -0
  147. package/dist/components/WallyAssistant/model/model.d.ts +184 -0
  148. package/dist/components/WallyAssistant/model/model.js +0 -0
  149. package/dist/components/WallyAssistant/views/ApprovalCardView.d.ts +20 -0
  150. package/dist/components/WallyAssistant/views/ApprovalCardView.js +274 -0
  151. package/dist/components/WallyAssistant/views/ChainOfThoughtView.d.ts +18 -0
  152. package/dist/components/WallyAssistant/views/ChainOfThoughtView.js +301 -0
  153. package/dist/components/WallyAssistant/views/ChatMessageView.d.ts +15 -0
  154. package/dist/components/WallyAssistant/views/ChatMessageView.js +372 -0
  155. package/dist/components/WallyAssistant/views/ChatPartView.d.ts +16 -0
  156. package/dist/components/WallyAssistant/views/ChatPartView.js +171 -0
  157. package/dist/components/WallyAssistant/views/ChatViewContext.d.ts +98 -0
  158. package/dist/components/WallyAssistant/views/ChatViewContext.js +44 -0
  159. package/dist/components/WallyAssistant/views/ChatViewProvider.d.ts +18 -0
  160. package/dist/components/WallyAssistant/views/ChatViewProvider.js +96 -0
  161. package/dist/components/WallyAssistant/views/stepIcons.d.ts +8 -0
  162. package/dist/components/WallyAssistant/views/stepIcons.js +47 -0
  163. package/dist/index.d.ts +10 -0
  164. package/dist/index.js +10 -0
  165. package/dist/metadata/components.json +30786 -15960
  166. package/dist/theme/components/animated-background.css +6 -1
  167. package/dist/theme/index.css +1 -0
  168. package/dist/theme/utilities/shimmer-text.css +27 -0
  169. package/package.json +3 -1
@@ -0,0 +1,138 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { c } from "react/compiler-runtime";
3
+ import { useId } from "react";
4
+ import { ArrowDown } from "../../icons/index.js";
5
+ import { useTestId } from "../../utils/testId.js";
6
+ import { Button } from "../Button/index.js";
7
+ import { Tooltip, TooltipContent, TooltipTrigger } from "../Tooltip/index.js";
8
+ import { useConversationInternal } from "./ConversationContext.js";
9
+ import { conversationScrollButtonVariants } from "./classes.js";
10
+ const ConversationScrollButton = (t0)=>{
11
+ const $ = c(31);
12
+ let className;
13
+ let id;
14
+ let onClick;
15
+ let props;
16
+ let ref;
17
+ let t1;
18
+ let testIdProp;
19
+ if ($[0] !== t0) {
20
+ ({ ref, id, label: t1, className, onClick, "data-testid": testIdProp, ...props } = t0);
21
+ $[0] = t0;
22
+ $[1] = className;
23
+ $[2] = id;
24
+ $[3] = onClick;
25
+ $[4] = props;
26
+ $[5] = ref;
27
+ $[6] = t1;
28
+ $[7] = testIdProp;
29
+ } else {
30
+ className = $[1];
31
+ id = $[2];
32
+ onClick = $[3];
33
+ props = $[4];
34
+ ref = $[5];
35
+ t1 = $[6];
36
+ testIdProp = $[7];
37
+ }
38
+ const label = void 0 === t1 ? "Scroll to latest message" : t1;
39
+ const { isAtBottom, scrollToBottom, scrollEl } = useConversationInternal("ConversationScrollButton");
40
+ const testId = useTestId("scroll-button", testIdProp);
41
+ const fallbackId = useId();
42
+ const triggerId = id ?? fallbackId;
43
+ if (isAtBottom) return null;
44
+ let t2;
45
+ if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
46
+ t2 = conversationScrollButtonVariants();
47
+ $[8] = t2;
48
+ } else t2 = $[8];
49
+ let t3;
50
+ if ($[9] !== triggerId) {
51
+ t3 = {
52
+ trigger: triggerId
53
+ };
54
+ $[9] = triggerId;
55
+ $[10] = t3;
56
+ } else t3 = $[10];
57
+ let t4;
58
+ if ($[11] !== onClick || $[12] !== scrollEl || $[13] !== scrollToBottom) {
59
+ t4 = (event)=>{
60
+ onClick?.(event);
61
+ if (event.defaultPrevented) return;
62
+ scrollToBottom("smooth");
63
+ const end = scrollEl?.lastElementChild;
64
+ (end instanceof HTMLElement ? end : scrollEl)?.focus({
65
+ preventScroll: true
66
+ });
67
+ };
68
+ $[11] = onClick;
69
+ $[12] = scrollEl;
70
+ $[13] = scrollToBottom;
71
+ $[14] = t4;
72
+ } else t4 = $[14];
73
+ let t5;
74
+ if ($[15] === Symbol.for("react.memo_cache_sentinel")) {
75
+ t5 = /*#__PURE__*/ jsx(ArrowDown, {});
76
+ $[15] = t5;
77
+ } else t5 = $[15];
78
+ let t6;
79
+ if ($[16] !== className || $[17] !== label || $[18] !== props || $[19] !== ref || $[20] !== t4 || $[21] !== testId || $[22] !== triggerId) {
80
+ t6 = /*#__PURE__*/ jsx(TooltipTrigger, {
81
+ asChild: true,
82
+ children: /*#__PURE__*/ jsx(Button, {
83
+ type: "button",
84
+ "aria-label": label,
85
+ ...props,
86
+ ref: ref,
87
+ id: triggerId,
88
+ variant: "outline",
89
+ color: "neutral",
90
+ size: "small",
91
+ "data-slot": "conversation-scroll-button",
92
+ "data-testid": testId,
93
+ className: className,
94
+ onClick: t4,
95
+ children: t5
96
+ })
97
+ });
98
+ $[16] = className;
99
+ $[17] = label;
100
+ $[18] = props;
101
+ $[19] = ref;
102
+ $[20] = t4;
103
+ $[21] = testId;
104
+ $[22] = triggerId;
105
+ $[23] = t6;
106
+ } else t6 = $[23];
107
+ let t7;
108
+ if ($[24] !== label) {
109
+ t7 = /*#__PURE__*/ jsx(TooltipContent, {
110
+ children: label
111
+ });
112
+ $[24] = label;
113
+ $[25] = t7;
114
+ } else t7 = $[25];
115
+ let t8;
116
+ if ($[26] !== t3 || $[27] !== t6 || $[28] !== t7 || $[29] !== testId) {
117
+ t8 = /*#__PURE__*/ jsx("div", {
118
+ "data-slot": "conversation-scroll-button-anchor",
119
+ className: t2,
120
+ children: /*#__PURE__*/ jsxs(Tooltip, {
121
+ ids: t3,
122
+ "data-testid": testId,
123
+ children: [
124
+ t6,
125
+ t7
126
+ ]
127
+ })
128
+ });
129
+ $[26] = t3;
130
+ $[27] = t6;
131
+ $[28] = t7;
132
+ $[29] = testId;
133
+ $[30] = t8;
134
+ } else t8 = $[30];
135
+ return t8;
136
+ };
137
+ ConversationScrollButton.displayName = "ConversationScrollButton";
138
+ export { ConversationScrollButton };
@@ -0,0 +1,13 @@
1
+ export declare const conversationVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
2
+ /**
3
+ * The scroller (ChatBody). `overflow-anchor: none`: browser scroll anchoring would shift
4
+ * scrollTop on its own as content grows and fight the stick-to-bottom animator. Focus ring inset:
5
+ * not clipped.
6
+ */
7
+ export declare const conversationScrollerVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
8
+ /** The inner measured column: no gap — the 30px actions row spaces the messages (v1 §3.1). */
9
+ export declare const conversationContentVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
10
+ /** Zero-height focus target; its ring draws a bar at the end of the thread. */
11
+ export declare const conversationEndVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
12
+ export declare const conversationEmptyStateVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
13
+ export declare const conversationScrollButtonVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
@@ -0,0 +1,8 @@
1
+ import { cva } from "class-variance-authority";
2
+ const conversationVariants = cva('relative flex min-h-0 flex-1 flex-col');
3
+ const conversationScrollerVariants = cva('[overflow-anchor:none] outline-none focus-visible:ring-3 focus-visible:ring-focus-primary focus-visible:ring-inset');
4
+ const conversationContentVariants = cva('flex flex-col');
5
+ const conversationEndVariants = cva('block shrink-0 outline-none focus-visible:ring-3 focus-visible:ring-focus-primary');
6
+ const conversationEmptyStateVariants = cva('flex flex-col');
7
+ const conversationScrollButtonVariants = cva('absolute bottom-12 left-1/2 flex -translate-x-1/2');
8
+ export { conversationContentVariants, conversationEmptyStateVariants, conversationEndVariants, conversationScrollButtonVariants, conversationScrollerVariants, conversationVariants };
@@ -0,0 +1,4 @@
1
+ export { Conversation, type ConversationProps } from './Conversation.js';
2
+ export { ConversationContent, type ConversationContentProps } from './ConversationContent.js';
3
+ export { ConversationEmptyState, type ConversationEmptyStateProps, } from './ConversationEmptyState.js';
4
+ export { ConversationScrollButton, type ConversationScrollButtonProps, } from './ConversationScrollButton.js';
@@ -0,0 +1,4 @@
1
+ export { Conversation } from "./Conversation.js";
2
+ export { ConversationContent } from "./ConversationContent.js";
3
+ export { ConversationEmptyState } from "./ConversationEmptyState.js";
4
+ export { ConversationScrollButton } from "./ConversationScrollButton.js";
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Keeps a scroll element pinned to the bottom while its content grows, until the reader scrolls
3
+ * up; re-sticks on scroll back down, `scrollToBottom()` or an `autoScrollKey` change.
4
+ * Internal to `Conversation` (spec v2 §7.6).
5
+ */
6
+ export declare function useStickToBottom(scrollEl: HTMLElement | null, contentEl: HTMLElement | null, threshold: number, autoScrollKey: unknown): {
7
+ isAtBottom: boolean;
8
+ scrollToBottom: (behavior?: ScrollBehavior) => void;
9
+ };
@@ -0,0 +1,203 @@
1
+ import { c } from "react/compiler-runtime";
2
+ import { useEffect, useRef, useState } from "react";
3
+ const reducedMotion = ()=>"function" == typeof window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
4
+ const isEditable = (target)=>target instanceof HTMLElement && (target.isContentEditable || target.matches("input, textarea, select"));
5
+ const SCROLL_UP_KEYS = new Set([
6
+ "ArrowUp",
7
+ "PageUp",
8
+ "Home"
9
+ ]);
10
+ const innerScrollsUp = (target, root)=>{
11
+ for(let el = target instanceof Element ? target : null; el && el !== root; el = el.parentElement)if (el.scrollTop > 0) return true;
12
+ return false;
13
+ };
14
+ const pin = (el)=>{
15
+ el.scrollTop = el.scrollHeight;
16
+ };
17
+ const setTop = (el, top)=>{
18
+ el.scrollTop = top;
19
+ };
20
+ const OMEGA = 0.02;
21
+ const MAX_SPEED = 3;
22
+ const MAX_DT = 1000 / 60;
23
+ function useStickToBottom(scrollEl, contentEl, threshold, autoScrollKey) {
24
+ const $ = c(13);
25
+ const [isAtBottom, setIsAtBottom] = useState(true);
26
+ const stuck = useRef(true);
27
+ const follow = useRef(null);
28
+ let t0;
29
+ let t1;
30
+ if ($[0] !== contentEl || $[1] !== scrollEl || $[2] !== threshold) {
31
+ t0 = ()=>{
32
+ if (!scrollEl || !contentEl) return;
33
+ let lastTop = scrollEl.scrollTop;
34
+ let lastHeight = scrollEl.scrollHeight;
35
+ const near = ()=>scrollEl.scrollHeight - scrollEl.scrollTop - scrollEl.clientHeight <= threshold;
36
+ let frame = 0;
37
+ let velocity = 0;
38
+ let lastTime = 0;
39
+ const sync = ()=>{
40
+ lastTop = scrollEl.scrollTop;
41
+ lastHeight = scrollEl.scrollHeight;
42
+ setIsAtBottom(stuck.current && 0 !== frame || near());
43
+ };
44
+ const selecting = ()=>{
45
+ const selection = document.getSelection();
46
+ return !!selection && !selection.isCollapsed && scrollEl.contains(selection.anchorNode);
47
+ };
48
+ const stop = ()=>{
49
+ if (frame) cancelAnimationFrame(frame);
50
+ frame = 0;
51
+ velocity = 0;
52
+ };
53
+ const step = (now)=>{
54
+ frame = 0;
55
+ if (!stuck.current || selecting()) return stop();
56
+ const top = scrollEl.scrollTop;
57
+ const gap = scrollEl.scrollHeight - scrollEl.clientHeight - top;
58
+ if (gap <= 1) {
59
+ if (gap > 0) setTop(scrollEl, top + gap);
60
+ return stop();
61
+ }
62
+ const dt = lastTime && now > lastTime ? Math.min(now - lastTime, MAX_DT) : MAX_DT;
63
+ lastTime = now;
64
+ velocity = Math.min(MAX_SPEED, Math.max(0, velocity + (OMEGA * OMEGA * gap - 2 * OMEGA * velocity) * dt));
65
+ frame = requestAnimationFrame(step);
66
+ setTop(scrollEl, top + Math.min(gap, Math.max(1, velocity * dt)));
67
+ };
68
+ const start = ()=>{
69
+ if (!stuck.current || selecting()) return;
70
+ if (reducedMotion()) return void pin(scrollEl);
71
+ if (frame) return;
72
+ lastTime = 0;
73
+ frame = requestAnimationFrame(step);
74
+ };
75
+ follow.current = start;
76
+ const onResize = ()=>{
77
+ start();
78
+ sync();
79
+ };
80
+ const onScroll = ()=>{
81
+ const shrank = scrollEl.scrollHeight < lastHeight;
82
+ const clamped = scrollEl.scrollTop >= scrollEl.scrollHeight - scrollEl.clientHeight - 1;
83
+ if (shrank || clamped || !(scrollEl.scrollTop < lastTop - 1)) {
84
+ if (near()) stuck.current = true;
85
+ } else {
86
+ stuck.current = false;
87
+ stop();
88
+ }
89
+ sync();
90
+ };
91
+ const unstick = (target)=>{
92
+ if (scrollEl.scrollTop > 0 && !innerScrollsUp(target, scrollEl)) {
93
+ stuck.current = false;
94
+ stop();
95
+ }
96
+ };
97
+ const onWheel = (event)=>{
98
+ if (event.deltaY < 0 && -event.deltaY >= Math.abs(event.deltaX)) unstick(event.target);
99
+ };
100
+ const onKeyDown = (event_0)=>{
101
+ if (!event_0.defaultPrevented && SCROLL_UP_KEYS.has(event_0.key) && event_0.target instanceof Node && scrollEl.contains(event_0.target) && !isEditable(event_0.target)) unstick(event_0.target);
102
+ };
103
+ let touchY = 0;
104
+ const onTouchStart = (event_1)=>{
105
+ touchY = event_1.touches[0]?.clientY ?? 0;
106
+ };
107
+ const onTouchMove = (event_2)=>{
108
+ const y = event_2.touches[0]?.clientY ?? touchY;
109
+ if (y > touchY) unstick(event_2.target);
110
+ touchY = y;
111
+ };
112
+ const observer = new ResizeObserver(onResize);
113
+ observer.observe(contentEl);
114
+ observer.observe(scrollEl);
115
+ scrollEl.addEventListener("scroll", onScroll, {
116
+ passive: true
117
+ });
118
+ scrollEl.addEventListener("wheel", onWheel, {
119
+ passive: true
120
+ });
121
+ scrollEl.addEventListener("touchstart", onTouchStart, {
122
+ passive: true
123
+ });
124
+ scrollEl.addEventListener("touchmove", onTouchMove, {
125
+ passive: true
126
+ });
127
+ const doc = scrollEl.ownerDocument;
128
+ doc.addEventListener("keydown", onKeyDown);
129
+ pin(scrollEl);
130
+ sync();
131
+ return ()=>{
132
+ stop();
133
+ follow.current = null;
134
+ observer.disconnect();
135
+ scrollEl.removeEventListener("scroll", onScroll);
136
+ scrollEl.removeEventListener("wheel", onWheel);
137
+ scrollEl.removeEventListener("touchstart", onTouchStart);
138
+ scrollEl.removeEventListener("touchmove", onTouchMove);
139
+ doc.removeEventListener("keydown", onKeyDown);
140
+ };
141
+ };
142
+ t1 = [
143
+ scrollEl,
144
+ contentEl,
145
+ threshold
146
+ ];
147
+ $[0] = contentEl;
148
+ $[1] = scrollEl;
149
+ $[2] = threshold;
150
+ $[3] = t0;
151
+ $[4] = t1;
152
+ } else {
153
+ t0 = $[3];
154
+ t1 = $[4];
155
+ }
156
+ useEffect(t0, t1);
157
+ const lastKey = useRef(autoScrollKey);
158
+ let t2;
159
+ let t3;
160
+ if ($[5] !== autoScrollKey) {
161
+ t2 = ()=>{
162
+ if (Object.is(lastKey.current, autoScrollKey)) return;
163
+ lastKey.current = autoScrollKey;
164
+ stuck.current = true;
165
+ follow.current?.();
166
+ };
167
+ t3 = [
168
+ autoScrollKey
169
+ ];
170
+ $[5] = autoScrollKey;
171
+ $[6] = t2;
172
+ $[7] = t3;
173
+ } else {
174
+ t2 = $[6];
175
+ t3 = $[7];
176
+ }
177
+ useEffect(t2, t3);
178
+ let t4;
179
+ if ($[8] !== scrollEl) {
180
+ t4 = (t5)=>{
181
+ const behavior = void 0 === t5 ? "smooth" : t5;
182
+ if (!scrollEl) return;
183
+ stuck.current = true;
184
+ if ("smooth" === behavior) follow.current?.();
185
+ else pin(scrollEl);
186
+ };
187
+ $[8] = scrollEl;
188
+ $[9] = t4;
189
+ } else t4 = $[9];
190
+ const scrollToBottom = t4;
191
+ let t5;
192
+ if ($[10] !== isAtBottom || $[11] !== scrollToBottom) {
193
+ t5 = {
194
+ isAtBottom,
195
+ scrollToBottom
196
+ };
197
+ $[10] = isAtBottom;
198
+ $[11] = scrollToBottom;
199
+ $[12] = t5;
200
+ } else t5 = $[12];
201
+ return t5;
202
+ }
203
+ export { useStickToBottom };
@@ -0,0 +1,18 @@
1
+ import { type ButtonHTMLAttributes, type FC, type ReactNode, type Ref } from 'react';
2
+ import { type TestableProps } from '../../utils/testId.js';
3
+ export interface MessageActionProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'color'>, TestableProps {
4
+ ref?: Ref<HTMLButtonElement>;
5
+ /** Required: the accessible name and the tooltip text. */
6
+ 'aria-label': string;
7
+ /** The icon. */
8
+ children: ReactNode;
9
+ }
10
+ /**
11
+ * Icon-only ghost button with a tooltip. The tooltip anchors to the button's `id`, so
12
+ * an outer `DropdownMenuTrigger asChild` (which injects its own id) just works.
13
+ *
14
+ * The tooltip derives its test id from the action (`<action-id>--content`). As a
15
+ * `DropdownMenuTrigger asChild` child, pass an explicit `data-testid` — the trigger
16
+ * injects `<base>--trigger`, which otherwise replaces the cascaded `<base>--action`.
17
+ */
18
+ export declare const MessageAction: FC<MessageActionProps>;
@@ -0,0 +1,109 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { c } from "react/compiler-runtime";
3
+ import { useId } from "react";
4
+ import { cn } from "../../utils/cn.js";
5
+ import { useTestId } from "../../utils/testId.js";
6
+ import { Button } from "../Button/index.js";
7
+ import { Tooltip, TooltipContent, TooltipTrigger } from "../Tooltip/index.js";
8
+ import { messageActionVariants } from "./classes.js";
9
+ const MessageAction = (t0)=>{
10
+ const $ = c(27);
11
+ let ariaLabel;
12
+ let children;
13
+ let className;
14
+ let id;
15
+ let props;
16
+ let ref;
17
+ let testIdProp;
18
+ if ($[0] !== t0) {
19
+ ({ ref, id, className, children, "aria-label": ariaLabel, "data-testid": testIdProp, ...props } = t0);
20
+ $[0] = t0;
21
+ $[1] = ariaLabel;
22
+ $[2] = children;
23
+ $[3] = className;
24
+ $[4] = id;
25
+ $[5] = props;
26
+ $[6] = ref;
27
+ $[7] = testIdProp;
28
+ } else {
29
+ ariaLabel = $[1];
30
+ children = $[2];
31
+ className = $[3];
32
+ id = $[4];
33
+ props = $[5];
34
+ ref = $[6];
35
+ testIdProp = $[7];
36
+ }
37
+ const testId = useTestId("action", testIdProp);
38
+ const autoId = useId();
39
+ const triggerId = id ?? autoId;
40
+ let t1;
41
+ if ($[8] !== triggerId) {
42
+ t1 = {
43
+ trigger: triggerId
44
+ };
45
+ $[8] = triggerId;
46
+ $[9] = t1;
47
+ } else t1 = $[9];
48
+ let t2;
49
+ if ($[10] !== className) {
50
+ t2 = cn(messageActionVariants(), className);
51
+ $[10] = className;
52
+ $[11] = t2;
53
+ } else t2 = $[11];
54
+ let t3;
55
+ if ($[12] !== ariaLabel || $[13] !== children || $[14] !== props || $[15] !== ref || $[16] !== t2 || $[17] !== testId || $[18] !== triggerId) {
56
+ t3 = /*#__PURE__*/ jsx(TooltipTrigger, {
57
+ asChild: true,
58
+ children: /*#__PURE__*/ jsx(Button, {
59
+ type: "button",
60
+ ...props,
61
+ ref: ref,
62
+ id: triggerId,
63
+ variant: "ghost",
64
+ color: "neutral",
65
+ size: "small",
66
+ "aria-label": ariaLabel,
67
+ "data-slot": "message-action",
68
+ "data-testid": testId,
69
+ className: t2,
70
+ children: children
71
+ })
72
+ });
73
+ $[12] = ariaLabel;
74
+ $[13] = children;
75
+ $[14] = props;
76
+ $[15] = ref;
77
+ $[16] = t2;
78
+ $[17] = testId;
79
+ $[18] = triggerId;
80
+ $[19] = t3;
81
+ } else t3 = $[19];
82
+ let t4;
83
+ if ($[20] !== ariaLabel) {
84
+ t4 = /*#__PURE__*/ jsx(TooltipContent, {
85
+ children: ariaLabel
86
+ });
87
+ $[20] = ariaLabel;
88
+ $[21] = t4;
89
+ } else t4 = $[21];
90
+ let t5;
91
+ if ($[22] !== t1 || $[23] !== t3 || $[24] !== t4 || $[25] !== testId) {
92
+ t5 = /*#__PURE__*/ jsxs(Tooltip, {
93
+ ids: t1,
94
+ "data-testid": testId,
95
+ children: [
96
+ t3,
97
+ t4
98
+ ]
99
+ });
100
+ $[22] = t1;
101
+ $[23] = t3;
102
+ $[24] = t4;
103
+ $[25] = testId;
104
+ $[26] = t5;
105
+ } else t5 = $[26];
106
+ return t5;
107
+ };
108
+ MessageAction.displayName = "MessageAction";
109
+ export { MessageAction };
@@ -0,0 +1,12 @@
1
+ import type { FC, HTMLAttributes, Ref } from 'react';
2
+ import { type TestableProps } from '../../utils/testId.js';
3
+ export interface MessageActionsProps extends HTMLAttributes<HTMLDivElement>, TestableProps {
4
+ ref?: Ref<HTMLDivElement>;
5
+ /**
6
+ * Force-show the row (e.g. the latest answer). By default the row is revealed on
7
+ * hover / focus-within of the nearest `group/message` parent, and always shown on
8
+ * `hover: none` devices. Hidden rows keep their 30px height and stay tabbable.
9
+ */
10
+ visible?: boolean;
11
+ }
12
+ export declare const MessageActions: FC<MessageActionsProps>;
@@ -0,0 +1,74 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { c } from "react/compiler-runtime";
3
+ import { cn } from "../../utils/cn.js";
4
+ import { TestIdProvider, useTestId } from "../../utils/testId.js";
5
+ import { messageActionsVariants } from "./classes.js";
6
+ const MessageActions = (t0)=>{
7
+ const $ = c(19);
8
+ let children;
9
+ let className;
10
+ let props;
11
+ let ref;
12
+ let t1;
13
+ let testIdProp;
14
+ if ($[0] !== t0) {
15
+ ({ ref, visible: t1, className, children, "data-testid": testIdProp, ...props } = t0);
16
+ $[0] = t0;
17
+ $[1] = children;
18
+ $[2] = className;
19
+ $[3] = props;
20
+ $[4] = ref;
21
+ $[5] = t1;
22
+ $[6] = testIdProp;
23
+ } else {
24
+ children = $[1];
25
+ className = $[2];
26
+ props = $[3];
27
+ ref = $[4];
28
+ t1 = $[5];
29
+ testIdProp = $[6];
30
+ }
31
+ const visible = void 0 === t1 ? false : t1;
32
+ const testId = useTestId("actions", testIdProp);
33
+ let t2;
34
+ if ($[7] !== className || $[8] !== visible) {
35
+ t2 = cn(messageActionsVariants({
36
+ visible
37
+ }), className);
38
+ $[7] = className;
39
+ $[8] = visible;
40
+ $[9] = t2;
41
+ } else t2 = $[9];
42
+ let t3;
43
+ if ($[10] !== children || $[11] !== testId) {
44
+ t3 = /*#__PURE__*/ jsx(TestIdProvider, {
45
+ value: testId,
46
+ children: children
47
+ });
48
+ $[10] = children;
49
+ $[11] = testId;
50
+ $[12] = t3;
51
+ } else t3 = $[12];
52
+ let t4;
53
+ if ($[13] !== props || $[14] !== ref || $[15] !== t2 || $[16] !== t3 || $[17] !== testId) {
54
+ t4 = /*#__PURE__*/ jsx("div", {
55
+ role: "group",
56
+ "aria-label": "Message actions",
57
+ ...props,
58
+ ref: ref,
59
+ "data-slot": "message-actions",
60
+ "data-testid": testId,
61
+ className: t2,
62
+ children: t3
63
+ });
64
+ $[13] = props;
65
+ $[14] = ref;
66
+ $[15] = t2;
67
+ $[16] = t3;
68
+ $[17] = testId;
69
+ $[18] = t4;
70
+ } else t4 = $[18];
71
+ return t4;
72
+ };
73
+ MessageActions.displayName = "MessageActions";
74
+ export { MessageActions };
@@ -0,0 +1,7 @@
1
+ import type { FC, Ref, TimeHTMLAttributes } from 'react';
2
+ import { type TestableProps } from '../../utils/testId.js';
3
+ export interface MessageTimestampProps extends TimeHTMLAttributes<HTMLTimeElement>, TestableProps {
4
+ /** Children are the pre-formatted text; set `dateTime` to the ISO value. */
5
+ ref?: Ref<HTMLTimeElement>;
6
+ }
7
+ export declare const MessageTimestamp: FC<MessageTimestampProps>;
@@ -0,0 +1,50 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { c } from "react/compiler-runtime";
3
+ import { cn } from "../../utils/cn.js";
4
+ import { useTestId } from "../../utils/testId.js";
5
+ import { messageTimestampVariants } from "./classes.js";
6
+ const MessageTimestamp = (t0)=>{
7
+ const $ = c(12);
8
+ let className;
9
+ let props;
10
+ let ref;
11
+ let testIdProp;
12
+ if ($[0] !== t0) {
13
+ ({ ref, className, "data-testid": testIdProp, ...props } = t0);
14
+ $[0] = t0;
15
+ $[1] = className;
16
+ $[2] = props;
17
+ $[3] = ref;
18
+ $[4] = testIdProp;
19
+ } else {
20
+ className = $[1];
21
+ props = $[2];
22
+ ref = $[3];
23
+ testIdProp = $[4];
24
+ }
25
+ const testId = useTestId("timestamp", testIdProp);
26
+ let t1;
27
+ if ($[5] !== className) {
28
+ t1 = cn(messageTimestampVariants(), className);
29
+ $[5] = className;
30
+ $[6] = t1;
31
+ } else t1 = $[6];
32
+ let t2;
33
+ if ($[7] !== props || $[8] !== ref || $[9] !== t1 || $[10] !== testId) {
34
+ t2 = /*#__PURE__*/ jsx("time", {
35
+ ...props,
36
+ ref: ref,
37
+ "data-slot": "message-timestamp",
38
+ "data-testid": testId,
39
+ className: t1
40
+ });
41
+ $[7] = props;
42
+ $[8] = ref;
43
+ $[9] = t1;
44
+ $[10] = testId;
45
+ $[11] = t2;
46
+ } else t2 = $[11];
47
+ return t2;
48
+ };
49
+ MessageTimestamp.displayName = "MessageTimestamp";
50
+ export { MessageTimestamp };
@@ -0,0 +1,5 @@
1
+ export declare const messageActionsVariants: (props?: ({
2
+ visible?: boolean | null | undefined;
3
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
4
+ export declare const messageActionVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
5
+ export declare const messageTimestampVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;