@gram-ai/elements 1.27.3 → 1.27.5

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 (278) hide show
  1. package/README.md +72 -60
  2. package/README.typedoc.md +6 -6
  3. package/bin/cli.js +74 -74
  4. package/dist/compat-shims-CO9JXXV4.cjs.map +1 -1
  5. package/dist/{compat-shims-BPJ7Q68c.js → compat-shims-DxtUrORi.js} +4 -2
  6. package/dist/compat-shims-DxtUrORi.js.map +1 -0
  7. package/dist/components/ShareButton/index.d.ts +2 -2
  8. package/dist/components/assistant-ui/message-feedback.d.ts +1 -1
  9. package/dist/components/assistant-ui/tooltip-icon-button.d.ts +2 -2
  10. package/dist/components/ui/avatar.d.ts +2 -2
  11. package/dist/components/ui/button.d.ts +1 -1
  12. package/dist/components/ui/calendar.d.ts +1 -1
  13. package/dist/components/ui/collapsible.d.ts +1 -1
  14. package/dist/components/ui/dialog.d.ts +4 -4
  15. package/dist/components/ui/popover.d.ts +2 -2
  16. package/dist/components/ui/skeleton.d.ts +1 -1
  17. package/dist/components/ui/time-range-picker.d.ts +4 -2
  18. package/dist/components/ui/tool-ui.d.ts +7 -7
  19. package/dist/components/ui/tooltip.d.ts +2 -2
  20. package/dist/contexts/ConnectionStatusContext.d.ts +1 -1
  21. package/dist/elements.cjs +1 -1
  22. package/dist/elements.css +1 -1
  23. package/dist/elements.js +2 -2
  24. package/dist/hooks/useDensity.d.ts +73 -73
  25. package/dist/hooks/useMCPTools.d.ts +1 -1
  26. package/dist/hooks/useRadius.d.ts +1 -1
  27. package/dist/{index-BpJstUh1.cjs → index-C4bFBGfl.cjs} +4 -4
  28. package/dist/{index-BpJstUh1.cjs.map → index-C4bFBGfl.cjs.map} +1 -1
  29. package/dist/{index-CUitXazZ.js → index-D93pV0_o.js} +55 -55
  30. package/dist/{index-CUitXazZ.js.map → index-D93pV0_o.js.map} +1 -1
  31. package/dist/{index-DBrhzauj.js → index-DuCQRbcQ.js} +6386 -6337
  32. package/dist/index-DuCQRbcQ.js.map +1 -0
  33. package/dist/{index-DxfW52oA.cjs → index-y_PNN5vK.cjs} +64 -46
  34. package/dist/index-y_PNN5vK.cjs.map +1 -0
  35. package/dist/lib/cassette.d.ts +4 -4
  36. package/dist/lib/errorTracking.d.ts +1 -1
  37. package/dist/lib/messageConverter.d.ts +1 -1
  38. package/dist/lib/models.d.ts +1 -1
  39. package/dist/plugins/chart/ui/bar-chart.d.ts +1 -1
  40. package/dist/plugins/generative-ui/ui/accordion-wrapper.d.ts +2 -2
  41. package/dist/plugins/generative-ui/ui/accordion.d.ts +1 -1
  42. package/dist/plugins/generative-ui/ui/action-button.d.ts +2 -2
  43. package/dist/plugins/generative-ui/ui/alert-wrapper.d.ts +1 -1
  44. package/dist/plugins/generative-ui/ui/alert.d.ts +4 -4
  45. package/dist/plugins/generative-ui/ui/avatar.d.ts +5 -5
  46. package/dist/plugins/generative-ui/ui/badge.d.ts +2 -2
  47. package/dist/plugins/generative-ui/ui/button-wrapper.d.ts +2 -2
  48. package/dist/plugins/generative-ui/ui/button.d.ts +2 -2
  49. package/dist/plugins/generative-ui/ui/card-wrapper.d.ts +2 -2
  50. package/dist/plugins/generative-ui/ui/card.d.ts +8 -8
  51. package/dist/plugins/generative-ui/ui/checkbox.d.ts +1 -1
  52. package/dist/plugins/generative-ui/ui/data-table.d.ts +2 -2
  53. package/dist/plugins/generative-ui/ui/dialog.d.ts +3 -3
  54. package/dist/plugins/generative-ui/ui/dropdown-menu.d.ts +3 -3
  55. package/dist/plugins/generative-ui/ui/grid.d.ts +3 -3
  56. package/dist/plugins/generative-ui/ui/input-wrapper.d.ts +1 -1
  57. package/dist/plugins/generative-ui/ui/input.d.ts +2 -2
  58. package/dist/plugins/generative-ui/ui/label.d.ts +1 -1
  59. package/dist/plugins/generative-ui/ui/metric.d.ts +3 -3
  60. package/dist/plugins/generative-ui/ui/pagination.d.ts +6 -6
  61. package/dist/plugins/generative-ui/ui/popover.d.ts +4 -4
  62. package/dist/plugins/generative-ui/ui/progress.d.ts +2 -2
  63. package/dist/plugins/generative-ui/ui/radio-group.d.ts +1 -1
  64. package/dist/plugins/generative-ui/ui/select.d.ts +2 -2
  65. package/dist/plugins/generative-ui/ui/separator.d.ts +1 -1
  66. package/dist/plugins/generative-ui/ui/skeleton.d.ts +1 -1
  67. package/dist/plugins/generative-ui/ui/stack.d.ts +6 -6
  68. package/dist/plugins/generative-ui/ui/switch.d.ts +2 -2
  69. package/dist/plugins/generative-ui/ui/table.d.ts +9 -9
  70. package/dist/plugins/generative-ui/ui/tabs-wrapper.d.ts +1 -1
  71. package/dist/plugins/generative-ui/ui/tabs.d.ts +1 -1
  72. package/dist/plugins/generative-ui/ui/text.d.ts +3 -3
  73. package/dist/plugins/generative-ui/ui/textarea.d.ts +2 -2
  74. package/dist/plugins/generative-ui/ui/tooltip.d.ts +1 -1
  75. package/dist/plugins.cjs +1 -1
  76. package/dist/plugins.js +1 -1
  77. package/dist/{profiler-D6ndqfsd.js → profiler-FpBY9eRv.js} +2 -2
  78. package/dist/{profiler-D6ndqfsd.js.map → profiler-FpBY9eRv.js.map} +1 -1
  79. package/dist/{profiler-DhnzZ34c.cjs → profiler-_mthyjvo.cjs} +2 -2
  80. package/dist/{profiler-DhnzZ34c.cjs.map → profiler-_mthyjvo.cjs.map} +1 -1
  81. package/dist/react-shim.js +1 -1
  82. package/dist/server/express.cjs.map +1 -1
  83. package/dist/server/express.js.map +1 -1
  84. package/dist/{startRecording-BwXmdmy1.cjs → startRecording-NJcpiHw-.cjs} +2 -2
  85. package/dist/{startRecording-BwXmdmy1.cjs.map → startRecording-NJcpiHw-.cjs.map} +1 -1
  86. package/dist/{startRecording-B_9CRZ_P.js → startRecording-r5MXQ2Dm.js} +2 -2
  87. package/dist/{startRecording-B_9CRZ_P.js.map → startRecording-r5MXQ2Dm.js.map} +1 -1
  88. package/dist/types/index.d.ts +2 -2
  89. package/package.json +1 -5
  90. package/src/compat-plugin.ts +14 -14
  91. package/src/compat-shims.ts +33 -31
  92. package/src/compat.test.ts +48 -48
  93. package/src/compat.ts +6 -6
  94. package/src/components/Chat/index.tsx +17 -17
  95. package/src/components/Chat/stories/Charts.stories.tsx +98 -98
  96. package/src/components/Chat/stories/Composer.stories.tsx +15 -15
  97. package/src/components/Chat/stories/ConnectionConfiguration.stories.tsx +44 -44
  98. package/src/components/Chat/stories/CustomComponents.stories.tsx +17 -17
  99. package/src/components/Chat/stories/Density.stories.tsx +20 -20
  100. package/src/components/Chat/stories/ErrorBoundary.stories.tsx +47 -47
  101. package/src/components/Chat/stories/FrontendTools.stories.tsx +39 -39
  102. package/src/components/Chat/stories/GenerativeUI.stories.tsx +48 -48
  103. package/src/components/Chat/stories/MessageFeedback.stories.tsx +52 -52
  104. package/src/components/Chat/stories/Modal.stories.tsx +28 -28
  105. package/src/components/Chat/stories/Model.stories.tsx +11 -11
  106. package/src/components/Chat/stories/Radius.stories.tsx +20 -20
  107. package/src/components/Chat/stories/Sidecar.stories.tsx +13 -13
  108. package/src/components/Chat/stories/StyleIsolation.stories.tsx +11 -11
  109. package/src/components/Chat/stories/Theme.stories.tsx +25 -25
  110. package/src/components/Chat/stories/Thread.stories.tsx +25 -25
  111. package/src/components/Chat/stories/ToolApproval.stories.tsx +55 -55
  112. package/src/components/Chat/stories/ToolMentions.stories.tsx +17 -17
  113. package/src/components/Chat/stories/Tools.stories.tsx +88 -88
  114. package/src/components/Chat/stories/Variants.stories.tsx +32 -32
  115. package/src/components/Chat/stories/Welcome.stories.tsx +14 -14
  116. package/src/components/ChatHistory.tsx +7 -7
  117. package/src/components/FrontendTools/index.tsx +5 -5
  118. package/src/components/Replay.stories.tsx +157 -157
  119. package/src/components/Replay.tsx +76 -73
  120. package/src/components/ShadowRoot.tsx +40 -40
  121. package/src/components/ShareButton/index.tsx +32 -32
  122. package/src/components/assistant-ui/assistant-modal.tsx +92 -87
  123. package/src/components/assistant-ui/assistant-sidecar.tsx +35 -35
  124. package/src/components/assistant-ui/attachment.tsx +80 -80
  125. package/src/components/assistant-ui/connection-status-indicator.tsx +33 -33
  126. package/src/components/assistant-ui/error-boundary.tsx +34 -34
  127. package/src/components/assistant-ui/follow-on-suggestions.tsx +26 -26
  128. package/src/components/assistant-ui/markdown-text.tsx +69 -69
  129. package/src/components/assistant-ui/mentioned-tools-badges.tsx +38 -38
  130. package/src/components/assistant-ui/message-feedback.tsx +74 -61
  131. package/src/components/assistant-ui/reasoning.tsx +83 -83
  132. package/src/components/assistant-ui/thread-list.tsx +45 -45
  133. package/src/components/assistant-ui/thread.tsx +278 -278
  134. package/src/components/assistant-ui/tool-fallback.tsx +37 -37
  135. package/src/components/assistant-ui/tool-group.tsx +26 -26
  136. package/src/components/assistant-ui/tool-mention-autocomplete.tsx +122 -122
  137. package/src/components/assistant-ui/tooltip-icon-button.tsx +18 -18
  138. package/src/components/ui/avatar.tsx +12 -12
  139. package/src/components/ui/button.tsx +12 -12
  140. package/src/components/ui/buttonVariants.ts +17 -17
  141. package/src/components/ui/calendar.tsx +106 -106
  142. package/src/components/ui/charts.stories.tsx +56 -56
  143. package/src/components/ui/collapsible.tsx +5 -5
  144. package/src/components/ui/dialog.tsx +30 -30
  145. package/src/components/ui/generative-ui.stories.tsx +200 -200
  146. package/src/components/ui/generative-ui.tsx +26 -26
  147. package/src/components/ui/popover.tsx +14 -14
  148. package/src/components/ui/skeleton.tsx +5 -5
  149. package/src/components/ui/time-range-picker.stories.tsx +80 -80
  150. package/src/components/ui/time-range-picker.tsx +272 -235
  151. package/src/components/ui/tool-ui.stories.tsx +37 -37
  152. package/src/components/ui/tool-ui.tsx +221 -215
  153. package/src/components/ui/tooltip.tsx +15 -15
  154. package/src/constants/tailwind.ts +1 -1
  155. package/src/contexts/ChatIdContext.tsx +7 -7
  156. package/src/contexts/ConnectionStatusContext.tsx +64 -64
  157. package/src/contexts/ElementsProvider.tsx +222 -211
  158. package/src/contexts/ReplayContext.ts +3 -3
  159. package/src/contexts/ToolApprovalContext.tsx +54 -54
  160. package/src/contexts/ToolExecutionContext.tsx +34 -34
  161. package/src/contexts/contexts.ts +7 -7
  162. package/src/contexts/portal-container-context.ts +2 -2
  163. package/src/contexts/portal-container.tsx +7 -7
  164. package/src/embedded.ts +1 -1
  165. package/src/global.css +25 -25
  166. package/src/hooks/useAuth.ts +72 -72
  167. package/src/hooks/useDensity.ts +79 -79
  168. package/src/hooks/useElements.ts +6 -6
  169. package/src/hooks/useExpanded.ts +12 -12
  170. package/src/hooks/useFollowOnSuggestions.ts +87 -82
  171. package/src/hooks/useGramThreadListAdapter.tsx +99 -99
  172. package/src/hooks/useMCPTools.ts +47 -47
  173. package/src/hooks/useModel.ts +14 -14
  174. package/src/hooks/usePluginComponents.ts +11 -11
  175. package/src/hooks/usePortalContainer.ts +5 -5
  176. package/src/hooks/useRadius.ts +23 -23
  177. package/src/hooks/useRecordCassette.ts +34 -34
  178. package/src/hooks/useSession.ts +11 -11
  179. package/src/hooks/useThemeProps.ts +13 -13
  180. package/src/hooks/useThreadId.ts +4 -4
  181. package/src/hooks/useToolApproval.ts +7 -7
  182. package/src/hooks/useToolMentions.ts +40 -40
  183. package/src/index.ts +26 -26
  184. package/src/lib/api.test.ts +61 -61
  185. package/src/lib/api.ts +4 -3
  186. package/src/lib/auth.ts +13 -13
  187. package/src/lib/cassette.ts +84 -84
  188. package/src/lib/easing.ts +1 -1
  189. package/src/lib/errorTracking.config.ts +5 -5
  190. package/src/lib/errorTracking.ts +29 -29
  191. package/src/lib/generative-ui.ts +7 -7
  192. package/src/lib/humanize.ts +3 -3
  193. package/src/lib/messageConverter.test.ts +130 -127
  194. package/src/lib/messageConverter.ts +196 -196
  195. package/src/lib/models.ts +21 -20
  196. package/src/lib/token.test.ts +56 -56
  197. package/src/lib/token.ts +14 -14
  198. package/src/lib/tool-mentions.ts +45 -45
  199. package/src/lib/tools.ts +66 -62
  200. package/src/lib/utils.ts +5 -5
  201. package/src/lib.d.ts +1 -1
  202. package/src/plugins/README.md +5 -5
  203. package/src/plugins/chart/catalog.ts +18 -18
  204. package/src/plugins/chart/chart.test.ts +31 -31
  205. package/src/plugins/chart/component.tsx +34 -34
  206. package/src/plugins/chart/index.ts +4 -4
  207. package/src/plugins/chart/ui/area-chart.tsx +42 -42
  208. package/src/plugins/chart/ui/bar-chart.tsx +46 -46
  209. package/src/plugins/chart/ui/donut-chart.tsx +48 -48
  210. package/src/plugins/chart/ui/index.ts +7 -7
  211. package/src/plugins/chart/ui/line-chart.tsx +43 -43
  212. package/src/plugins/chart/ui/pie-chart.tsx +44 -44
  213. package/src/plugins/chart/ui/radar-chart.tsx +33 -33
  214. package/src/plugins/chart/ui/scatter-chart.tsx +43 -43
  215. package/src/plugins/components/MacOSWindowFrame.tsx +15 -15
  216. package/src/plugins/components/PluginLoadingState.tsx +10 -10
  217. package/src/plugins/components/index.ts +1 -1
  218. package/src/plugins/generative-ui/catalog.ts +54 -54
  219. package/src/plugins/generative-ui/component.tsx +85 -85
  220. package/src/plugins/generative-ui/index.ts +4 -4
  221. package/src/plugins/generative-ui/ui/accordion-wrapper.tsx +16 -16
  222. package/src/plugins/generative-ui/ui/accordion.tsx +16 -16
  223. package/src/plugins/generative-ui/ui/action-button.tsx +28 -28
  224. package/src/plugins/generative-ui/ui/alert-wrapper.tsx +8 -8
  225. package/src/plugins/generative-ui/ui/alert.tsx +20 -20
  226. package/src/plugins/generative-ui/ui/avatar-wrapper.tsx +7 -7
  227. package/src/plugins/generative-ui/ui/avatar.tsx +30 -30
  228. package/src/plugins/generative-ui/ui/badge.tsx +22 -22
  229. package/src/plugins/generative-ui/ui/button-wrapper.tsx +12 -12
  230. package/src/plugins/generative-ui/ui/button.tsx +28 -28
  231. package/src/plugins/generative-ui/ui/card-wrapper.tsx +8 -8
  232. package/src/plugins/generative-ui/ui/card.tsx +27 -27
  233. package/src/plugins/generative-ui/ui/checkbox-wrapper.tsx +9 -9
  234. package/src/plugins/generative-ui/ui/checkbox.tsx +9 -9
  235. package/src/plugins/generative-ui/ui/data-table.tsx +8 -8
  236. package/src/plugins/generative-ui/ui/dialog.tsx +31 -31
  237. package/src/plugins/generative-ui/ui/dropdown-menu.tsx +44 -44
  238. package/src/plugins/generative-ui/ui/grid.tsx +12 -12
  239. package/src/plugins/generative-ui/ui/index.ts +40 -40
  240. package/src/plugins/generative-ui/ui/input-wrapper.tsx +11 -11
  241. package/src/plugins/generative-ui/ui/input.tsx +9 -9
  242. package/src/plugins/generative-ui/ui/label.tsx +8 -8
  243. package/src/plugins/generative-ui/ui/list.tsx +11 -11
  244. package/src/plugins/generative-ui/ui/metric.tsx +23 -23
  245. package/src/plugins/generative-ui/ui/pagination.tsx +28 -28
  246. package/src/plugins/generative-ui/ui/popover.tsx +21 -21
  247. package/src/plugins/generative-ui/ui/progress.tsx +13 -13
  248. package/src/plugins/generative-ui/ui/radio-group.tsx +12 -12
  249. package/src/plugins/generative-ui/ui/select-wrapper.tsx +7 -7
  250. package/src/plugins/generative-ui/ui/select.tsx +37 -37
  251. package/src/plugins/generative-ui/ui/separator.tsx +9 -9
  252. package/src/plugins/generative-ui/ui/skeleton-wrapper.tsx +10 -10
  253. package/src/plugins/generative-ui/ui/skeleton.tsx +5 -5
  254. package/src/plugins/generative-ui/ui/stack.tsx +28 -28
  255. package/src/plugins/generative-ui/ui/switch.tsx +11 -11
  256. package/src/plugins/generative-ui/ui/table.tsx +32 -32
  257. package/src/plugins/generative-ui/ui/tabs-wrapper.tsx +11 -11
  258. package/src/plugins/generative-ui/ui/tabs.tsx +26 -26
  259. package/src/plugins/generative-ui/ui/text.tsx +12 -12
  260. package/src/plugins/generative-ui/ui/textarea.tsx +7 -7
  261. package/src/plugins/generative-ui/ui/tooltip.tsx +12 -12
  262. package/src/plugins/index.ts +7 -7
  263. package/src/react-shim.ts +6 -6
  264. package/src/server/bun.ts +12 -12
  265. package/src/server/core.ts +25 -25
  266. package/src/server/express.ts +17 -15
  267. package/src/server/fastify.ts +14 -14
  268. package/src/server/hono.ts +9 -9
  269. package/src/server/nextjs.ts +12 -12
  270. package/src/server/tanstack-start.ts +12 -12
  271. package/src/server.ts +27 -27
  272. package/src/storybook.d.ts +4 -4
  273. package/src/types/index.ts +122 -122
  274. package/src/types/plugins.ts +7 -7
  275. package/src/vite-env.d.ts +12 -12
  276. package/dist/compat-shims-BPJ7Q68c.js.map +0 -1
  277. package/dist/index-DBrhzauj.js.map +0 -1
  278. package/dist/index-DxfW52oA.cjs.map +0 -1
@@ -3,93 +3,106 @@ import {
3
3
  TooltipContent,
4
4
  TooltipProvider,
5
5
  TooltipTrigger,
6
- } from '@/components/ui/tooltip'
7
- import { EASE_OUT_QUINT } from '@/lib/easing'
8
- import { cn } from '@/lib/utils'
9
- import { Heart, X } from 'lucide-react'
10
- import { AnimatePresence } from 'motion/react'
11
- import * as m from 'motion/react-m'
12
- import { useState, type FC } from 'react'
6
+ } from "@/components/ui/tooltip";
7
+ import { EASE_OUT_QUINT } from "@/lib/easing";
8
+ import { cn } from "@/lib/utils";
9
+ import { Heart, X } from "lucide-react";
10
+ import { AnimatePresence } from "motion/react";
11
+ import * as m from "motion/react-m";
12
+ import { useState, type FC } from "react";
13
13
 
14
- export type FeedbackType = 'dislike' | 'like'
14
+ export type FeedbackType = "dislike" | "like";
15
15
 
16
16
  interface MessageFeedbackProps {
17
- onFeedback?: (type: FeedbackType) => void
18
- onResolved?: () => void
19
- className?: string
17
+ onFeedback?: (type: FeedbackType) => void;
18
+ onResolved?: () => void;
19
+ className?: string;
20
20
  }
21
21
 
22
22
  const feedbackButtons = [
23
23
  {
24
- type: 'like' as const,
24
+ type: "like" as const,
25
25
  icon: Heart,
26
- label: 'This resolved my question',
27
- color: 'text-emerald-500',
28
- hoverBg: 'hover:bg-emerald-500/10',
29
- activeBg: 'bg-emerald-500/20',
26
+ label: "This resolved my question",
27
+ color: "text-emerald-500",
28
+ hoverBg: "hover:bg-emerald-500/10",
29
+ activeBg: "bg-emerald-500/20",
30
30
  },
31
31
  {
32
- type: 'dislike' as const,
32
+ type: "dislike" as const,
33
33
  icon: X,
34
34
  label: "This didn't help",
35
- color: 'text-rose-500',
36
- hoverBg: 'hover:bg-rose-500/10',
37
- activeBg: 'bg-rose-500/20',
35
+ color: "text-rose-500",
36
+ hoverBg: "hover:bg-rose-500/10",
37
+ activeBg: "bg-rose-500/20",
38
38
  },
39
- ]
39
+ ];
40
40
 
41
- const subtleBounceKeyframes = `
41
+ const feedbackStyles = `
42
42
  @keyframes subtle-bounce {
43
43
  0%, 100% { transform: translateY(0); }
44
44
  50% { transform: translateY(-2px); }
45
45
  }
46
- `
46
+ .aui-feedback-buttons {
47
+ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04), inset 0 1px 0 rgba(255, 255, 255, 0.6), inset 0 -1px 0 rgba(0, 0, 0, 0.02);
48
+ }
49
+ .dark .aui-feedback-buttons,
50
+ :host(.dark) .aui-feedback-buttons {
51
+ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4), 0 1px 2px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.06);
52
+ }
53
+ .aui-feedback-thank-you {
54
+ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04), inset 0 1px 0 rgba(255, 255, 255, 0.6);
55
+ }
56
+ .dark .aui-feedback-thank-you,
57
+ :host(.dark) .aui-feedback-thank-you {
58
+ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4), 0 1px 2px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.06);
59
+ }
60
+ `;
47
61
 
48
62
  export const MessageFeedback: FC<MessageFeedbackProps> = ({
49
63
  onFeedback,
50
64
  onResolved,
51
65
  className,
52
66
  }) => {
67
+ const [tooltipContainer, setTooltipContainer] =
68
+ useState<HTMLDivElement | null>(null);
53
69
  const [selectedFeedback, setSelectedFeedback] = useState<FeedbackType | null>(
54
- null
55
- )
56
- const [showDislikeFeedback, setShowDislikeFeedback] = useState(false)
70
+ null,
71
+ );
72
+ const [showDislikeFeedback, setShowDislikeFeedback] = useState(false);
57
73
 
58
74
  const handleFeedback = (type: FeedbackType) => {
59
- setSelectedFeedback(type)
60
- onFeedback?.(type)
61
- if (type === 'like') {
62
- onResolved?.()
75
+ setSelectedFeedback(type);
76
+ onFeedback?.(type);
77
+ if (type === "like") {
78
+ onResolved?.();
63
79
  } else {
64
- setShowDislikeFeedback(true)
80
+ setShowDislikeFeedback(true);
65
81
  }
66
- }
82
+ };
67
83
 
68
84
  return (
69
85
  <div
70
86
  className={cn(
71
- 'aui-message-feedback flex items-center justify-center',
72
- className
87
+ "aui-message-feedback flex items-center justify-center",
88
+ className,
73
89
  )}
74
90
  >
75
- <style>{subtleBounceKeyframes}</style>
91
+ <style>{feedbackStyles}</style>
76
92
  <AnimatePresence mode="wait">
77
93
  {!showDislikeFeedback ? (
78
94
  <m.div
79
95
  key="feedback-buttons"
80
- className="relative flex items-center gap-1.5 rounded-full border border-black/[0.08] bg-gradient-to-b from-white/80 to-white/60 px-3 py-1 shadow-lg backdrop-blur-2xl dark:border-white/[0.08] dark:from-white/15 dark:to-white/10"
96
+ ref={setTooltipContainer}
97
+ className="aui-feedback-buttons relative flex items-center gap-1.5 rounded-full border border-black/[0.08] bg-gradient-to-b from-white/80 to-white/60 px-3 py-1 backdrop-blur-2xl dark:border-white/5 dark:from-white/10 dark:to-white/[0.03]"
81
98
  initial={{ opacity: 0, scale: 0.8, y: 10 }}
82
99
  animate={{ opacity: 1, scale: 1, y: 0 }}
83
100
  exit={{ opacity: 0, scale: 0.8, y: 5 }}
84
101
  transition={{ duration: 0.4, delay: 0.75, ease: EASE_OUT_QUINT }}
85
- style={{
86
- boxShadow:
87
- '0 4px 24px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04), inset 0 1px 0 rgba(255, 255, 255, 0.6), inset 0 -1px 0 rgba(0, 0, 0, 0.02)',
88
- }}
89
102
  >
90
103
  <TooltipProvider delayDuration={300}>
91
104
  {feedbackButtons.map((button, index) => {
92
- const Icon = button.icon
105
+ const Icon = button.icon;
93
106
  return (
94
107
  <Tooltip key={button.type}>
95
108
  <TooltipTrigger asChild>
@@ -97,9 +110,9 @@ export const MessageFeedback: FC<MessageFeedbackProps> = ({
97
110
  type="button"
98
111
  onClick={() => handleFeedback(button.type)}
99
112
  className={cn(
100
- 'group/btn relative flex size-8 items-center justify-center rounded-full transition-[background-color] duration-200 ease-out',
113
+ "group/btn relative flex size-8 items-center justify-center rounded-full transition-[background-color] duration-200 ease-out",
101
114
  button.hoverBg,
102
- selectedFeedback === button.type && button.activeBg
115
+ selectedFeedback === button.type && button.activeBg,
103
116
  )}
104
117
  initial="initial"
105
118
  animate="animate"
@@ -113,7 +126,7 @@ export const MessageFeedback: FC<MessageFeedbackProps> = ({
113
126
  transition={{
114
127
  duration: 0.8,
115
128
  delay: 0.75 + index * 0.15,
116
- type: 'spring',
129
+ type: "spring",
117
130
  stiffness: 150,
118
131
  damping: 10,
119
132
  }}
@@ -122,55 +135,55 @@ export const MessageFeedback: FC<MessageFeedbackProps> = ({
122
135
  <span
123
136
  className="flex"
124
137
  style={{
125
- animation: 'none',
138
+ animation: "none",
126
139
  }}
127
140
  onMouseEnter={(e) => {
128
141
  e.currentTarget.style.animation =
129
- 'subtle-bounce 0.6s ease-in-out infinite'
142
+ "subtle-bounce 0.6s ease-in-out infinite";
130
143
  }}
131
144
  onMouseLeave={(e) => {
132
- e.currentTarget.style.animation = 'none'
145
+ e.currentTarget.style.animation = "none";
133
146
  }}
134
147
  >
135
148
  <Icon
136
149
  className={cn(
137
- 'size-5 transition-[fill] duration-200',
150
+ "size-5 transition-[fill] duration-200",
138
151
  button.color,
139
- button.type === 'like' &&
140
- 'group-hover/btn:fill-emerald-500',
152
+ button.type === "like" &&
153
+ "group-hover/btn:fill-emerald-500",
141
154
  selectedFeedback === button.type &&
142
- button.type === 'like' &&
143
- 'fill-emerald-500'
155
+ button.type === "like" &&
156
+ "fill-emerald-500",
144
157
  )}
145
158
  strokeWidth={2}
146
159
  />
147
160
  </span>
148
161
  </m.button>
149
162
  </TooltipTrigger>
150
- <TooltipContent side="top" sideOffset={8}>
163
+ <TooltipContent
164
+ side="top"
165
+ sideOffset={8}
166
+ container={tooltipContainer}
167
+ >
151
168
  {button.label}
152
169
  </TooltipContent>
153
170
  </Tooltip>
154
- )
171
+ );
155
172
  })}
156
173
  </TooltipProvider>
157
174
  </m.div>
158
175
  ) : (
159
176
  <m.div
160
177
  key="thank-you"
161
- className="text-muted-foreground rounded-full border border-black/[0.08] bg-gradient-to-b from-white/80 to-white/60 px-4 py-2 text-sm shadow-lg backdrop-blur-2xl dark:border-white/[0.08] dark:from-white/15 dark:to-white/10"
178
+ className="aui-feedback-thank-you rounded-full border border-black/[0.08] bg-gradient-to-b from-white/80 to-white/60 px-4 py-2 text-sm text-muted-foreground backdrop-blur-2xl dark:border-white/5 dark:from-white/10 dark:to-white/[0.03]"
162
179
  initial={{ opacity: 0, y: 5 }}
163
180
  animate={{ opacity: 1, y: 0 }}
164
181
  transition={{ duration: 0.25, ease: EASE_OUT_QUINT }}
165
- style={{
166
- boxShadow:
167
- '0 4px 24px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04), inset 0 1px 0 rgba(255, 255, 255, 0.6)',
168
- }}
169
182
  >
170
183
  Feedback received, thank you
171
184
  </m.div>
172
185
  )}
173
186
  </AnimatePresence>
174
187
  </div>
175
- )
176
- }
188
+ );
189
+ };
@@ -1,6 +1,6 @@
1
- 'use client'
1
+ "use client";
2
2
 
3
- import { BrainIcon, ChevronDownIcon } from 'lucide-react'
3
+ import { BrainIcon, ChevronDownIcon } from "lucide-react";
4
4
  import {
5
5
  memo,
6
6
  useCallback,
@@ -8,24 +8,24 @@ import {
8
8
  useState,
9
9
  type FC,
10
10
  type PropsWithChildren,
11
- } from 'react'
11
+ } from "react";
12
12
 
13
13
  import {
14
14
  useAssistantState,
15
15
  useScrollLock,
16
16
  type ReasoningGroupComponent,
17
17
  type ReasoningMessagePartComponent,
18
- } from '@assistant-ui/react'
18
+ } from "@assistant-ui/react";
19
19
 
20
- import { MarkdownText } from '@/components/assistant-ui/markdown-text'
20
+ import { MarkdownText } from "@/components/assistant-ui/markdown-text";
21
21
  import {
22
22
  Collapsible,
23
23
  CollapsibleContent,
24
24
  CollapsibleTrigger,
25
- } from '@/components/ui/collapsible'
26
- import { cn } from '@/lib/utils'
25
+ } from "@/components/ui/collapsible";
26
+ import { cn } from "@/lib/utils";
27
27
 
28
- const ANIMATION_DURATION = 200
28
+ const ANIMATION_DURATION = 200;
29
29
 
30
30
  /**
31
31
  * Root collapsible container that manages open/closed state and scroll lock.
@@ -33,41 +33,41 @@ const ANIMATION_DURATION = 200
33
33
  */
34
34
  const ReasoningRoot: FC<
35
35
  PropsWithChildren<{
36
- className?: string
36
+ className?: string;
37
37
  }>
38
38
  > = ({ className, children }) => {
39
- const collapsibleRef = useRef<HTMLDivElement>(null)
40
- const [isOpen, setIsOpen] = useState(false)
41
- const lockScroll = useScrollLock(collapsibleRef, ANIMATION_DURATION)
39
+ const collapsibleRef = useRef<HTMLDivElement>(null);
40
+ const [isOpen, setIsOpen] = useState(false);
41
+ const lockScroll = useScrollLock(collapsibleRef, ANIMATION_DURATION);
42
42
 
43
43
  const handleOpenChange = useCallback(
44
44
  (open: boolean) => {
45
45
  if (!open) {
46
- lockScroll()
46
+ lockScroll();
47
47
  }
48
- setIsOpen(open)
48
+ setIsOpen(open);
49
49
  },
50
- [lockScroll]
51
- )
50
+ [lockScroll],
51
+ );
52
52
 
53
53
  return (
54
54
  <Collapsible
55
55
  ref={collapsibleRef}
56
56
  open={isOpen}
57
57
  onOpenChange={handleOpenChange}
58
- className={cn('aui-reasoning-root mb-4 w-full', className)}
58
+ className={cn("aui-reasoning-root mb-4 w-full", className)}
59
59
  style={
60
60
  {
61
- '--animation-duration': `${ANIMATION_DURATION}ms`,
61
+ "--animation-duration": `${ANIMATION_DURATION}ms`,
62
62
  } as React.CSSProperties
63
63
  }
64
64
  >
65
65
  {children}
66
66
  </Collapsible>
67
- )
68
- }
67
+ );
68
+ };
69
69
 
70
- ReasoningRoot.displayName = 'ReasoningRoot'
70
+ ReasoningRoot.displayName = "ReasoningRoot";
71
71
 
72
72
  /**
73
73
  * Gradient overlay that softens the bottom edge during expand/collapse animations.
@@ -76,19 +76,19 @@ ReasoningRoot.displayName = 'ReasoningRoot'
76
76
  const GradientFade: FC<{ className?: string }> = ({ className }) => (
77
77
  <div
78
78
  className={cn(
79
- 'aui-reasoning-fade pointer-events-none absolute inset-x-0 bottom-0 z-10 h-16',
80
- 'bg-[linear-gradient(to_top,var(--color-background),transparent)]',
81
- 'fade-in-0 animate-in',
82
- 'group-data-[state=open]/collapsible-content:animate-out',
83
- 'group-data-[state=open]/collapsible-content:fade-out-0',
84
- 'group-data-[state=open]/collapsible-content:delay-[calc(var(--animation-duration)*0.75)]', // calc for timing the delay
85
- 'group-data-[state=open]/collapsible-content:fill-mode-forwards',
86
- 'duration-(--animation-duration)',
87
- 'group-data-[state=open]/collapsible-content:duration-(--animation-duration)',
88
- className
79
+ "aui-reasoning-fade pointer-events-none absolute inset-x-0 bottom-0 z-10 h-16",
80
+ "bg-[linear-gradient(to_top,var(--color-background),transparent)]",
81
+ "animate-in fade-in-0",
82
+ "group-data-[state=open]/collapsible-content:animate-out",
83
+ "group-data-[state=open]/collapsible-content:fade-out-0",
84
+ "group-data-[state=open]/collapsible-content:delay-[calc(var(--animation-duration)*0.75)]", // calc for timing the delay
85
+ "group-data-[state=open]/collapsible-content:fill-mode-forwards",
86
+ "duration-(--animation-duration)",
87
+ "group-data-[state=open]/collapsible-content:duration-(--animation-duration)",
88
+ className,
89
89
  )}
90
90
  />
91
- )
91
+ );
92
92
 
93
93
  /**
94
94
  * Trigger button for the Reasoning collapsible.
@@ -100,9 +100,9 @@ const ReasoningTrigger: FC<{ active: boolean; className?: string }> = ({
100
100
  }) => (
101
101
  <CollapsibleTrigger
102
102
  className={cn(
103
- 'aui-reasoning-trigger group/trigger text-muted-foreground hover:text-foreground -mb-2 flex max-w-[75%] items-center gap-2 py-2 text-sm transition-colors',
103
+ "aui-reasoning-trigger group/trigger -mb-2 flex max-w-[75%] items-center gap-2 py-2 text-sm text-muted-foreground transition-colors hover:text-foreground",
104
104
  className,
105
- active && 'shimmer'
105
+ active && "shimmer",
106
106
  )}
107
107
  >
108
108
  <BrainIcon className="aui-reasoning-trigger-icon size-4 shrink-0" />
@@ -111,7 +111,7 @@ const ReasoningTrigger: FC<{ active: boolean; className?: string }> = ({
111
111
  {active ? (
112
112
  <span
113
113
  aria-hidden
114
- className="aui-reasoning-trigger-shimmer shimmer pointer-events-none absolute inset-0 motion-reduce:animate-none"
114
+ className="aui-reasoning-trigger-shimmer pointer-events-none absolute inset-0 shimmer motion-reduce:animate-none"
115
115
  >
116
116
  Reasoning
117
117
  </span>
@@ -119,14 +119,14 @@ const ReasoningTrigger: FC<{ active: boolean; className?: string }> = ({
119
119
  </span>
120
120
  <ChevronDownIcon
121
121
  className={cn(
122
- 'aui-reasoning-trigger-chevron mt-0.5 size-4 shrink-0',
123
- 'transition-transform duration-(--animation-duration) ease-out',
124
- 'group-data-[state=closed]/trigger:-rotate-90',
125
- 'group-data-[state=open]/trigger:rotate-0'
122
+ "aui-reasoning-trigger-chevron mt-0.5 size-4 shrink-0",
123
+ "transition-transform duration-(--animation-duration) ease-out",
124
+ "group-data-[state=closed]/trigger:-rotate-90",
125
+ "group-data-[state=open]/trigger:rotate-0",
126
126
  )}
127
127
  />
128
128
  </CollapsibleTrigger>
129
- )
129
+ );
130
130
 
131
131
  /**
132
132
  * Collapsible content wrapper that handles height expand/collapse animation.
@@ -135,30 +135,30 @@ const ReasoningTrigger: FC<{ active: boolean; className?: string }> = ({
135
135
  */
136
136
  const ReasoningContent: FC<
137
137
  PropsWithChildren<{
138
- className?: string
139
- 'aria-busy'?: boolean
138
+ className?: string;
139
+ "aria-busy"?: boolean;
140
140
  }>
141
- > = ({ className, children, 'aria-busy': ariaBusy }) => (
141
+ > = ({ className, children, "aria-busy": ariaBusy }) => (
142
142
  <CollapsibleContent
143
143
  className={cn(
144
- 'aui-reasoning-content text-muted-foreground relative overflow-hidden text-sm outline-none',
145
- 'group/collapsible-content ease-out',
146
- 'data-[state=closed]:animate-collapsible-up',
147
- 'data-[state=open]:animate-collapsible-down',
148
- 'data-[state=closed]:fill-mode-forwards',
149
- 'data-[state=closed]:pointer-events-none',
150
- 'data-[state=open]:duration-(--animation-duration)',
151
- 'data-[state=closed]:duration-(--animation-duration)',
152
- className
144
+ "aui-reasoning-content relative overflow-hidden text-sm text-muted-foreground outline-none",
145
+ "group/collapsible-content ease-out",
146
+ "data-[state=closed]:animate-collapsible-up",
147
+ "data-[state=open]:animate-collapsible-down",
148
+ "data-[state=closed]:fill-mode-forwards",
149
+ "data-[state=closed]:pointer-events-none",
150
+ "data-[state=open]:duration-(--animation-duration)",
151
+ "data-[state=closed]:duration-(--animation-duration)",
152
+ className,
153
153
  )}
154
154
  aria-busy={ariaBusy}
155
155
  >
156
156
  {children}
157
157
  <GradientFade />
158
158
  </CollapsibleContent>
159
- )
159
+ );
160
160
 
161
- ReasoningContent.displayName = 'ReasoningContent'
161
+ ReasoningContent.displayName = "ReasoningContent";
162
162
 
163
163
  /**
164
164
  * Text content wrapper that animates the reasoning text visibility.
@@ -167,30 +167,30 @@ ReasoningContent.displayName = 'ReasoningContent'
167
167
  */
168
168
  const ReasoningText: FC<
169
169
  PropsWithChildren<{
170
- className?: string
170
+ className?: string;
171
171
  }>
172
172
  > = ({ className, children }) => (
173
173
  <div
174
174
  className={cn(
175
- 'aui-reasoning-text relative z-0 space-y-4 pt-4 pl-6 leading-relaxed',
176
- 'transform-gpu transition-[transform,opacity]',
177
- 'group-data-[state=open]/collapsible-content:animate-in',
178
- 'group-data-[state=closed]/collapsible-content:animate-out',
179
- 'group-data-[state=open]/collapsible-content:fade-in-0',
180
- 'group-data-[state=closed]/collapsible-content:fade-out-0',
181
- 'group-data-[state=open]/collapsible-content:slide-in-from-top-4',
182
- 'group-data-[state=closed]/collapsible-content:slide-out-to-top-4',
183
- 'group-data-[state=open]/collapsible-content:duration-(--animation-duration)',
184
- 'group-data-[state=closed]/collapsible-content:duration-(--animation-duration)',
185
- '[&_p]:-mb-2',
186
- className
175
+ "aui-reasoning-text relative z-0 space-y-4 pt-4 pl-6 leading-relaxed",
176
+ "transform-gpu transition-[transform,opacity]",
177
+ "group-data-[state=open]/collapsible-content:animate-in",
178
+ "group-data-[state=closed]/collapsible-content:animate-out",
179
+ "group-data-[state=open]/collapsible-content:fade-in-0",
180
+ "group-data-[state=closed]/collapsible-content:fade-out-0",
181
+ "group-data-[state=open]/collapsible-content:slide-in-from-top-4",
182
+ "group-data-[state=closed]/collapsible-content:slide-out-to-top-4",
183
+ "group-data-[state=open]/collapsible-content:duration-(--animation-duration)",
184
+ "group-data-[state=closed]/collapsible-content:duration-(--animation-duration)",
185
+ "[&_p]:-mb-2",
186
+ className,
187
187
  )}
188
188
  >
189
189
  {children}
190
190
  </div>
191
- )
191
+ );
192
192
 
193
- ReasoningText.displayName = 'ReasoningText'
193
+ ReasoningText.displayName = "ReasoningText";
194
194
 
195
195
  /**
196
196
  * Renders a single reasoning part's text with markdown support.
@@ -208,7 +208,7 @@ ReasoningText.displayName = 'ReasoningText'
208
208
  * />
209
209
  * ```
210
210
  */
211
- const ReasoningImpl: ReasoningMessagePartComponent = () => <MarkdownText />
211
+ const ReasoningImpl: ReasoningMessagePartComponent = () => <MarkdownText />;
212
212
 
213
213
  /**
214
214
  * Collapsible wrapper that groups consecutive reasoning parts together.
@@ -235,13 +235,13 @@ const ReasoningGroupImpl: ReasoningGroupComponent = ({
235
235
  * Detects if reasoning is currently streaming within this group's range.
236
236
  */
237
237
  const isReasoningStreaming = useAssistantState(({ message }) => {
238
- if (message.status?.type !== 'running') return false
239
- const lastIndex = message.parts.length - 1
240
- if (lastIndex < 0) return false
241
- const lastType = message.parts[lastIndex]?.type
242
- if (lastType !== 'reasoning') return false
243
- return lastIndex >= startIndex && lastIndex <= endIndex
244
- })
238
+ if (message.status?.type !== "running") return false;
239
+ const lastIndex = message.parts.length - 1;
240
+ if (lastIndex < 0) return false;
241
+ const lastType = message.parts[lastIndex]?.type;
242
+ if (lastType !== "reasoning") return false;
243
+ return lastIndex >= startIndex && lastIndex <= endIndex;
244
+ });
245
245
 
246
246
  return (
247
247
  <ReasoningRoot>
@@ -251,11 +251,11 @@ const ReasoningGroupImpl: ReasoningGroupComponent = ({
251
251
  <ReasoningText>{children}</ReasoningText>
252
252
  </ReasoningContent>
253
253
  </ReasoningRoot>
254
- )
255
- }
254
+ );
255
+ };
256
256
 
257
- export const Reasoning = memo(ReasoningImpl)
258
- Reasoning.displayName = 'Reasoning'
257
+ export const Reasoning = memo(ReasoningImpl);
258
+ Reasoning.displayName = "Reasoning";
259
259
 
260
- export const ReasoningGroup = memo(ReasoningGroupImpl)
261
- ReasoningGroup.displayName = 'ReasoningGroup'
260
+ export const ReasoningGroup = memo(ReasoningGroupImpl);
261
+ ReasoningGroup.displayName = "ReasoningGroup";