@gram-ai/elements 1.34.0 → 1.35.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 (233) hide show
  1. package/dist/compat-shims-CO9JXXV4.cjs.map +1 -1
  2. package/dist/compat-shims-DxtUrORi.js.map +1 -1
  3. package/dist/compat-shims.d.ts +9 -8
  4. package/dist/components/Chat/index.d.ts +2 -1
  5. package/dist/components/ChatHistory.d.ts +1 -1
  6. package/dist/components/FrontendTools/index.d.ts +1 -1
  7. package/dist/components/Replay.d.ts +1 -1
  8. package/dist/components/Replay.stories.d.ts +2 -2
  9. package/dist/components/ShadowRoot.d.ts +1 -1
  10. package/dist/components/ShareButton/index.d.ts +1 -1
  11. package/dist/components/ui/avatar.d.ts +3 -3
  12. package/dist/components/ui/button.d.ts +2 -2
  13. package/dist/components/ui/buttonVariants.d.ts +2 -2
  14. package/dist/components/ui/calendar.d.ts +2 -1
  15. package/dist/components/ui/collapsible.d.ts +3 -3
  16. package/dist/components/ui/dialog.d.ts +10 -10
  17. package/dist/components/ui/popover.d.ts +4 -4
  18. package/dist/components/ui/skeleton.d.ts +1 -1
  19. package/dist/components/ui/time-range-picker.d.ts +2 -1
  20. package/dist/components/ui/tool-ui.d.ts +7 -7
  21. package/dist/components/ui/tooltip.d.ts +4 -4
  22. package/dist/contexts/ConnectionStatusContext.d.ts +1 -1
  23. package/dist/contexts/ElementsProvider.d.ts +1 -1
  24. package/dist/contexts/ToolApprovalContext.d.ts +2 -2
  25. package/dist/contexts/ToolExecutionContext.d.ts +1 -1
  26. package/dist/contexts/portal-container.d.ts +1 -1
  27. package/dist/elements.cjs +1 -1
  28. package/dist/elements.css +1 -1
  29. package/dist/elements.js +2 -2
  30. package/dist/hooks/useDensity.d.ts +1 -1
  31. package/dist/hooks/useElements.d.ts +2 -1
  32. package/dist/hooks/useGramThreadListAdapter.d.ts +13 -0
  33. package/dist/hooks/useRadius.d.ts +1 -1
  34. package/dist/hooks/useThemeProps.d.ts +1 -1
  35. package/dist/hooks/useToolApproval.d.ts +2 -1
  36. package/dist/{index-BFU6NvbL.js → index-BhIowiZF.js} +9408 -9204
  37. package/dist/index-BhIowiZF.js.map +1 -0
  38. package/dist/{index-C08dvTEo.cjs → index-D0jIGQr7.cjs} +3 -3
  39. package/dist/index-D0jIGQr7.cjs.map +1 -0
  40. package/dist/{index-B5lZrrO2.js → index-Dz13dSDa.js} +57 -15
  41. package/dist/index-Dz13dSDa.js.map +1 -0
  42. package/dist/index-PXd3rs95.cjs +194 -0
  43. package/dist/index-PXd3rs95.cjs.map +1 -0
  44. package/dist/lib/errorTracking.d.ts +1 -1
  45. package/dist/lib/tools.d.ts +11 -10
  46. package/dist/plugins/generative-ui/catalog.d.ts +3 -3
  47. package/dist/plugins/generative-ui/ui/accordion-wrapper.d.ts +2 -2
  48. package/dist/plugins/generative-ui/ui/accordion.d.ts +4 -4
  49. package/dist/plugins/generative-ui/ui/action-button.d.ts +1 -1
  50. package/dist/plugins/generative-ui/ui/alert-wrapper.d.ts +2 -1
  51. package/dist/plugins/generative-ui/ui/alert.d.ts +3 -3
  52. package/dist/plugins/generative-ui/ui/avatar-wrapper.d.ts +2 -1
  53. package/dist/plugins/generative-ui/ui/avatar.d.ts +6 -6
  54. package/dist/plugins/generative-ui/ui/badge.d.ts +2 -2
  55. package/dist/plugins/generative-ui/ui/button-wrapper.d.ts +2 -1
  56. package/dist/plugins/generative-ui/ui/button.d.ts +3 -3
  57. package/dist/plugins/generative-ui/ui/card-wrapper.d.ts +1 -1
  58. package/dist/plugins/generative-ui/ui/card.d.ts +7 -7
  59. package/dist/plugins/generative-ui/ui/checkbox-wrapper.d.ts +2 -1
  60. package/dist/plugins/generative-ui/ui/checkbox.d.ts +1 -1
  61. package/dist/plugins/generative-ui/ui/data-table.d.ts +1 -1
  62. package/dist/plugins/generative-ui/ui/dialog.d.ts +10 -10
  63. package/dist/plugins/generative-ui/ui/dropdown-menu.d.ts +15 -15
  64. package/dist/plugins/generative-ui/ui/grid.d.ts +1 -1
  65. package/dist/plugins/generative-ui/ui/index.d.ts +57 -40
  66. package/dist/plugins/generative-ui/ui/input-wrapper.d.ts +2 -1
  67. package/dist/plugins/generative-ui/ui/input.d.ts +1 -1
  68. package/dist/plugins/generative-ui/ui/label.d.ts +1 -1
  69. package/dist/plugins/generative-ui/ui/list.d.ts +2 -1
  70. package/dist/plugins/generative-ui/ui/metric.d.ts +1 -1
  71. package/dist/plugins/generative-ui/ui/pagination.d.ts +7 -7
  72. package/dist/plugins/generative-ui/ui/popover.d.ts +7 -7
  73. package/dist/plugins/generative-ui/ui/progress.d.ts +1 -1
  74. package/dist/plugins/generative-ui/ui/radio-group.d.ts +2 -2
  75. package/dist/plugins/generative-ui/ui/select-wrapper.d.ts +2 -1
  76. package/dist/plugins/generative-ui/ui/select.d.ts +10 -10
  77. package/dist/plugins/generative-ui/ui/separator.d.ts +1 -1
  78. package/dist/plugins/generative-ui/ui/skeleton-wrapper.d.ts +2 -1
  79. package/dist/plugins/generative-ui/ui/skeleton.d.ts +1 -1
  80. package/dist/plugins/generative-ui/ui/stack.d.ts +1 -1
  81. package/dist/plugins/generative-ui/ui/switch.d.ts +1 -1
  82. package/dist/plugins/generative-ui/ui/table.d.ts +8 -8
  83. package/dist/plugins/generative-ui/ui/tabs-wrapper.d.ts +2 -2
  84. package/dist/plugins/generative-ui/ui/tabs.d.ts +4 -4
  85. package/dist/plugins/generative-ui/ui/text.d.ts +1 -1
  86. package/dist/plugins/generative-ui/ui/textarea.d.ts +1 -1
  87. package/dist/plugins/generative-ui/ui/tooltip.d.ts +4 -4
  88. package/dist/plugins.cjs +1 -1
  89. package/dist/plugins.js +1 -1
  90. package/dist/{profiler-KLSTpp6I.js → profiler-CtGKTWWP.js} +2 -2
  91. package/dist/{profiler-KLSTpp6I.js.map → profiler-CtGKTWWP.js.map} +1 -1
  92. package/dist/{profiler-BRnyr1GA.cjs → profiler-l7_HjTyw.cjs} +2 -2
  93. package/dist/{profiler-BRnyr1GA.cjs.map → profiler-l7_HjTyw.cjs.map} +1 -1
  94. package/dist/react-shim.cjs.map +1 -1
  95. package/dist/react-shim.d.ts +1 -1
  96. package/dist/react-shim.js +1 -4
  97. package/dist/react-shim.js.map +1 -1
  98. package/dist/server/bun.cjs.map +1 -1
  99. package/dist/server/bun.js.map +1 -1
  100. package/dist/server/express.cjs.map +1 -1
  101. package/dist/server/express.js.map +1 -1
  102. package/dist/server/fastify.cjs.map +1 -1
  103. package/dist/server/fastify.js.map +1 -1
  104. package/dist/server/hono.cjs.map +1 -1
  105. package/dist/server/hono.js.map +1 -1
  106. package/dist/server/nextjs.cjs.map +1 -1
  107. package/dist/server/nextjs.js.map +1 -1
  108. package/dist/server/tanstack-start.cjs.map +1 -1
  109. package/dist/server/tanstack-start.js.map +1 -1
  110. package/dist/{startRecording-CKx-YWbq.cjs → startRecording-DEw2Aeq4.cjs} +2 -2
  111. package/dist/{startRecording-CKx-YWbq.cjs.map → startRecording-DEw2Aeq4.cjs.map} +1 -1
  112. package/dist/{startRecording-BfxB1xxR.js → startRecording-iYEL0-vr.js} +2 -2
  113. package/dist/{startRecording-BfxB1xxR.js.map → startRecording-iYEL0-vr.js.map} +1 -1
  114. package/dist/types/index.d.ts +29 -3
  115. package/package.json +7 -10
  116. package/src/compat-shims.ts +16 -2
  117. package/src/components/Chat/index.tsx +4 -1
  118. package/src/components/Chat/stories/FrontendTools.stories.tsx +1 -1
  119. package/src/components/Chat/stories/ToolApproval.stories.tsx +2 -2
  120. package/src/components/Chat/stories/Tools.stories.tsx +13 -5
  121. package/src/components/ChatHistory.tsx +3 -1
  122. package/src/components/FrontendTools/index.tsx +1 -1
  123. package/src/components/MessageContent.tsx +1 -0
  124. package/src/components/Replay.stories.tsx +2 -3
  125. package/src/components/Replay.tsx +17 -10
  126. package/src/components/ShadowRoot.tsx +2 -2
  127. package/src/components/ShareButton/index.tsx +4 -2
  128. package/src/components/assistant-ui/assistant-modal.tsx +5 -3
  129. package/src/components/assistant-ui/attachment.tsx +1 -1
  130. package/src/components/assistant-ui/error-boundary.tsx +1 -1
  131. package/src/components/assistant-ui/markdown-text.tsx +1 -1
  132. package/src/components/assistant-ui/thread.tsx +249 -11
  133. package/src/components/assistant-ui/tool-mention-autocomplete.tsx +1 -1
  134. package/src/components/ui/avatar.tsx +3 -3
  135. package/src/components/ui/calendar.tsx +1 -1
  136. package/src/components/ui/collapsible.tsx +7 -3
  137. package/src/components/ui/dialog.tsx +18 -10
  138. package/src/components/ui/generative-ui.tsx +9 -4
  139. package/src/components/ui/popover.tsx +4 -4
  140. package/src/components/ui/skeleton.tsx +4 -1
  141. package/src/components/ui/time-range-picker.stories.tsx +164 -154
  142. package/src/components/ui/time-range-picker.tsx +11 -5
  143. package/src/components/ui/tool-ui.tsx +18 -9
  144. package/src/components/ui/tooltip.tsx +4 -4
  145. package/src/contexts/ChatIdContext.tsx +1 -1
  146. package/src/contexts/ConnectionStatusContext.tsx +6 -5
  147. package/src/contexts/ElementsProvider.tsx +64 -41
  148. package/src/contexts/ReplayContext.ts +1 -1
  149. package/src/contexts/ToolApprovalContext.tsx +5 -1
  150. package/src/contexts/ToolExecutionContext.tsx +1 -1
  151. package/src/contexts/portal-container.tsx +1 -1
  152. package/src/hooks/useAuth.ts +2 -1
  153. package/src/hooks/useDensity.ts +1 -1
  154. package/src/hooks/useElements.ts +2 -1
  155. package/src/hooks/useFollowOnSuggestions.ts +3 -6
  156. package/src/hooks/useGramThreadListAdapter.tsx +50 -3
  157. package/src/hooks/useMCPTools.ts +2 -2
  158. package/src/hooks/useModel.ts +1 -3
  159. package/src/hooks/usePluginComponents.ts +3 -1
  160. package/src/hooks/useRadius.ts +1 -1
  161. package/src/hooks/useSession.ts +3 -1
  162. package/src/hooks/useThemeProps.ts +5 -5
  163. package/src/hooks/useToolApproval.ts +2 -1
  164. package/src/lib/cassette.ts +20 -8
  165. package/src/lib/errorTracking.ts +1 -4
  166. package/src/lib/messageConverter.test.ts +11 -13
  167. package/src/lib/messageConverter.ts +13 -4
  168. package/src/lib/token.ts +2 -5
  169. package/src/lib/tool-mentions.ts +5 -2
  170. package/src/lib/tools.byte-cap.test.ts +1 -1
  171. package/src/lib/tools.test.ts +1 -1
  172. package/src/lib/tools.ts +15 -5
  173. package/src/lib/utils.ts +2 -2
  174. package/src/lib.d.ts +8 -1
  175. package/src/plugins/chart/chart.test.ts +3 -4
  176. package/src/plugins/chart/component.tsx +7 -6
  177. package/src/plugins/chart/ui/area-chart.tsx +1 -1
  178. package/src/plugins/chart/ui/line-chart.tsx +1 -1
  179. package/src/plugins/generative-ui/ui/accordion-wrapper.tsx +2 -2
  180. package/src/plugins/generative-ui/ui/accordion.tsx +4 -4
  181. package/src/plugins/generative-ui/ui/action-button.tsx +4 -2
  182. package/src/plugins/generative-ui/ui/alert-wrapper.tsx +1 -1
  183. package/src/plugins/generative-ui/ui/alert.tsx +7 -3
  184. package/src/plugins/generative-ui/ui/avatar-wrapper.tsx +5 -1
  185. package/src/plugins/generative-ui/ui/avatar.tsx +12 -6
  186. package/src/plugins/generative-ui/ui/badge.tsx +1 -1
  187. package/src/plugins/generative-ui/ui/button-wrapper.tsx +1 -1
  188. package/src/plugins/generative-ui/ui/button.tsx +1 -1
  189. package/src/plugins/generative-ui/ui/card-wrapper.tsx +1 -1
  190. package/src/plugins/generative-ui/ui/card.tsx +28 -7
  191. package/src/plugins/generative-ui/ui/checkbox-wrapper.tsx +1 -1
  192. package/src/plugins/generative-ui/ui/checkbox.tsx +1 -1
  193. package/src/plugins/generative-ui/ui/data-table.tsx +1 -1
  194. package/src/plugins/generative-ui/ui/dialog.tsx +15 -10
  195. package/src/plugins/generative-ui/ui/dropdown-menu.tsx +33 -15
  196. package/src/plugins/generative-ui/ui/grid.tsx +1 -1
  197. package/src/plugins/generative-ui/ui/index.ts +154 -40
  198. package/src/plugins/generative-ui/ui/input-wrapper.tsx +1 -1
  199. package/src/plugins/generative-ui/ui/input.tsx +5 -1
  200. package/src/plugins/generative-ui/ui/label.tsx +1 -1
  201. package/src/plugins/generative-ui/ui/list.tsx +5 -1
  202. package/src/plugins/generative-ui/ui/metric.tsx +2 -1
  203. package/src/plugins/generative-ui/ui/pagination.tsx +12 -7
  204. package/src/plugins/generative-ui/ui/popover.tsx +13 -7
  205. package/src/plugins/generative-ui/ui/progress.tsx +1 -1
  206. package/src/plugins/generative-ui/ui/radio-group.tsx +2 -2
  207. package/src/plugins/generative-ui/ui/select-wrapper.tsx +1 -1
  208. package/src/plugins/generative-ui/ui/select.tsx +14 -10
  209. package/src/plugins/generative-ui/ui/separator.tsx +1 -1
  210. package/src/plugins/generative-ui/ui/skeleton-wrapper.tsx +1 -1
  211. package/src/plugins/generative-ui/ui/skeleton.tsx +4 -1
  212. package/src/plugins/generative-ui/ui/stack.tsx +1 -1
  213. package/src/plugins/generative-ui/ui/switch.tsx +1 -1
  214. package/src/plugins/generative-ui/ui/table.tsx +29 -8
  215. package/src/plugins/generative-ui/ui/tabs-wrapper.tsx +5 -2
  216. package/src/plugins/generative-ui/ui/tabs.tsx +4 -4
  217. package/src/plugins/generative-ui/ui/text.tsx +1 -1
  218. package/src/plugins/generative-ui/ui/textarea.tsx +4 -1
  219. package/src/plugins/generative-ui/ui/tooltip.tsx +4 -4
  220. package/src/react-shim.ts +9 -4
  221. package/src/server/bun.ts +1 -1
  222. package/src/server/express.ts +1 -1
  223. package/src/server/fastify.ts +1 -1
  224. package/src/server/hono.ts +1 -1
  225. package/src/server/nextjs.ts +1 -1
  226. package/src/server/tanstack-start.ts +1 -1
  227. package/src/storybook.d.ts +5 -0
  228. package/src/types/index.ts +39 -3
  229. package/dist/index-B5lZrrO2.js.map +0 -1
  230. package/dist/index-BFU6NvbL.js.map +0 -1
  231. package/dist/index-C08dvTEo.cjs.map +0 -1
  232. package/dist/index-DzZ1-jQY.cjs +0 -194
  233. package/dist/index-DzZ1-jQY.cjs.map +0 -1
@@ -6,7 +6,7 @@ import { cn } from "@/lib/utils";
6
6
  function Avatar({
7
7
  className,
8
8
  ...props
9
- }: React.ComponentProps<typeof AvatarPrimitive.Root>) {
9
+ }: React.ComponentProps<typeof AvatarPrimitive.Root>): React.JSX.Element {
10
10
  return (
11
11
  <AvatarPrimitive.Root
12
12
  data-slot="avatar"
@@ -22,7 +22,7 @@ function Avatar({
22
22
  function AvatarImage({
23
23
  className,
24
24
  ...props
25
- }: React.ComponentProps<typeof AvatarPrimitive.Image>) {
25
+ }: React.ComponentProps<typeof AvatarPrimitive.Image>): React.JSX.Element {
26
26
  return (
27
27
  <AvatarPrimitive.Image
28
28
  data-slot="avatar-image"
@@ -35,7 +35,7 @@ function AvatarImage({
35
35
  function AvatarFallback({
36
36
  className,
37
37
  ...props
38
- }: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
38
+ }: React.ComponentProps<typeof AvatarPrimitive.Fallback>): React.JSX.Element {
39
39
  return (
40
40
  <AvatarPrimitive.Fallback
41
41
  data-slot="avatar-fallback"
@@ -130,7 +130,7 @@ function Calendar({
130
130
  minDate,
131
131
  maxDate,
132
132
  className,
133
- }: CalendarProps) {
133
+ }: CalendarProps): React.JSX.Element {
134
134
  const [viewDate, setViewDate] = React.useState(() => {
135
135
  if (selected.start) return new Date(selected.start);
136
136
  return new Date();
@@ -2,13 +2,15 @@ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
2
2
 
3
3
  function Collapsible({
4
4
  ...props
5
- }: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {
5
+ }: React.ComponentProps<typeof CollapsiblePrimitive.Root>): React.JSX.Element {
6
6
  return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />;
7
7
  }
8
8
 
9
9
  function CollapsibleTrigger({
10
10
  ...props
11
- }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {
11
+ }: React.ComponentProps<
12
+ typeof CollapsiblePrimitive.CollapsibleTrigger
13
+ >): React.JSX.Element {
12
14
  return (
13
15
  <CollapsiblePrimitive.CollapsibleTrigger
14
16
  data-slot="collapsible-trigger"
@@ -19,7 +21,9 @@ function CollapsibleTrigger({
19
21
 
20
22
  function CollapsibleContent({
21
23
  ...props
22
- }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {
24
+ }: React.ComponentProps<
25
+ typeof CollapsiblePrimitive.CollapsibleContent
26
+ >): React.JSX.Element {
23
27
  return (
24
28
  <CollapsiblePrimitive.CollapsibleContent
25
29
  data-slot="collapsible-content"
@@ -7,20 +7,20 @@ import { usePortalContainer } from "@/hooks/usePortalContainer";
7
7
 
8
8
  function Dialog({
9
9
  ...props
10
- }: React.ComponentProps<typeof DialogPrimitive.Root>) {
10
+ }: React.ComponentProps<typeof DialogPrimitive.Root>): React.JSX.Element {
11
11
  return <DialogPrimitive.Root data-slot="dialog" {...props} />;
12
12
  }
13
13
 
14
14
  function DialogTrigger({
15
15
  ...props
16
- }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
16
+ }: React.ComponentProps<typeof DialogPrimitive.Trigger>): React.JSX.Element {
17
17
  return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
18
18
  }
19
19
 
20
20
  function DialogPortal({
21
21
  container,
22
22
  ...props
23
- }: React.ComponentProps<typeof DialogPrimitive.Portal>) {
23
+ }: React.ComponentProps<typeof DialogPrimitive.Portal>): React.JSX.Element {
24
24
  const portalContainer = usePortalContainer();
25
25
  return (
26
26
  <DialogPrimitive.Portal
@@ -33,14 +33,14 @@ function DialogPortal({
33
33
 
34
34
  function DialogClose({
35
35
  ...props
36
- }: React.ComponentProps<typeof DialogPrimitive.Close>) {
36
+ }: React.ComponentProps<typeof DialogPrimitive.Close>): React.JSX.Element {
37
37
  return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
38
38
  }
39
39
 
40
40
  function DialogOverlay({
41
41
  className,
42
42
  ...props
43
- }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
43
+ }: React.ComponentProps<typeof DialogPrimitive.Overlay>): React.JSX.Element {
44
44
  return (
45
45
  <DialogPrimitive.Overlay
46
46
  data-slot="dialog-overlay"
@@ -60,7 +60,7 @@ function DialogContent({
60
60
  ...props
61
61
  }: React.ComponentProps<typeof DialogPrimitive.Content> & {
62
62
  showCloseButton?: boolean;
63
- }) {
63
+ }): React.JSX.Element {
64
64
  return (
65
65
  <DialogPortal data-slot="dialog-portal">
66
66
  <DialogOverlay />
@@ -87,7 +87,10 @@ function DialogContent({
87
87
  );
88
88
  }
89
89
 
90
- function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
90
+ function DialogHeader({
91
+ className,
92
+ ...props
93
+ }: React.ComponentProps<"div">): React.JSX.Element {
91
94
  return (
92
95
  <div
93
96
  data-slot="dialog-header"
@@ -97,7 +100,10 @@ function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
97
100
  );
98
101
  }
99
102
 
100
- function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
103
+ function DialogFooter({
104
+ className,
105
+ ...props
106
+ }: React.ComponentProps<"div">): React.JSX.Element {
101
107
  return (
102
108
  <div
103
109
  data-slot="dialog-footer"
@@ -113,7 +119,7 @@ function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
113
119
  function DialogTitle({
114
120
  className,
115
121
  ...props
116
- }: React.ComponentProps<typeof DialogPrimitive.Title>) {
122
+ }: React.ComponentProps<typeof DialogPrimitive.Title>): React.JSX.Element {
117
123
  return (
118
124
  <DialogPrimitive.Title
119
125
  data-slot="dialog-title"
@@ -126,7 +132,9 @@ function DialogTitle({
126
132
  function DialogDescription({
127
133
  className,
128
134
  ...props
129
- }: React.ComponentProps<typeof DialogPrimitive.Description>) {
135
+ }: React.ComponentProps<
136
+ typeof DialogPrimitive.Description
137
+ >): React.JSX.Element {
130
138
  return (
131
139
  <DialogPrimitive.Description
132
140
  data-slot="dialog-description"
@@ -4,7 +4,7 @@ import { useDensity } from "@/hooks/useDensity";
4
4
  import { cn } from "@/lib/utils";
5
5
  import { isJsonRenderTree, type JsonRenderNode } from "@/lib/generative-ui";
6
6
  import { AlertCircleIcon } from "lucide-react";
7
- import { FC, useMemo } from "react";
7
+ import { ElementType, FC, useMemo } from "react";
8
8
 
9
9
  // Import all components from the generative-ui plugin ui directory
10
10
  import {
@@ -42,9 +42,10 @@ interface GenerativeUIProps {
42
42
  /**
43
43
  * Built-in components for rendering json-render trees.
44
44
  * These provide a default set of UI primitives for tool results.
45
+ * Each entry has its own prop shape; the registry erases those generics via
46
+ * `ElementType` so heterogeneous components can coexist under one map.
45
47
  */
46
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
47
- const components: Record<string, FC<any>> = {
48
+ const components: Record<string, ElementType> = {
48
49
  // Layout
49
50
  Card: CardWrapper,
50
51
  Grid,
@@ -98,7 +99,11 @@ function renderNode(node: JsonRenderNode, key?: number): React.ReactNode {
98
99
  ? node.children.map((child, i) => renderNode(child, i))
99
100
  : undefined;
100
101
 
101
- return <Component key={key} {...(node.props ?? {})} children={children} />;
102
+ return (
103
+ <Component key={key} {...(node.props ?? {})}>
104
+ {children}
105
+ </Component>
106
+ );
102
107
  }
103
108
 
104
109
  /**
@@ -6,13 +6,13 @@ import { usePortalContainer } from "@/hooks/usePortalContainer";
6
6
 
7
7
  function Popover({
8
8
  ...props
9
- }: React.ComponentProps<typeof PopoverPrimitive.Root>) {
9
+ }: React.ComponentProps<typeof PopoverPrimitive.Root>): React.JSX.Element {
10
10
  return <PopoverPrimitive.Root data-slot="popover" {...props} />;
11
11
  }
12
12
 
13
13
  function PopoverTrigger({
14
14
  ...props
15
- }: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {
15
+ }: React.ComponentProps<typeof PopoverPrimitive.Trigger>): React.JSX.Element {
16
16
  return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />;
17
17
  }
18
18
 
@@ -24,7 +24,7 @@ function PopoverContent({
24
24
  ...props
25
25
  }: React.ComponentProps<typeof PopoverPrimitive.Content> & {
26
26
  container?: HTMLElement | null;
27
- }) {
27
+ }): React.JSX.Element {
28
28
  const portalContainer = usePortalContainer();
29
29
  return (
30
30
  <PopoverPrimitive.Portal container={container ?? portalContainer}>
@@ -44,7 +44,7 @@ function PopoverContent({
44
44
 
45
45
  function PopoverAnchor({
46
46
  ...props
47
- }: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {
47
+ }: React.ComponentProps<typeof PopoverPrimitive.Anchor>): React.JSX.Element {
48
48
  return <PopoverPrimitive.Anchor data-slot="popover-anchor" {...props} />;
49
49
  }
50
50
 
@@ -1,6 +1,9 @@
1
1
  import { cn } from "@/lib/utils";
2
2
 
3
- function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
3
+ function Skeleton({
4
+ className,
5
+ ...props
6
+ }: React.ComponentProps<"div">): React.JSX.Element {
4
7
  return (
5
8
  <div
6
9
  data-slot="skeleton"
@@ -36,171 +36,214 @@ const meta: Meta<typeof TimeRangePicker> = {
36
36
  export default meta;
37
37
  type Story = StoryObj<typeof TimeRangePicker>;
38
38
 
39
+ function DefaultStory() {
40
+ const [preset, setPreset] = useState<DateRangePreset | null>("7d");
41
+ const [customRange, setCustomRange] = useState<TimeRange | null>(null);
42
+
43
+ return (
44
+ <TimeRangePicker
45
+ preset={customRange ? null : preset}
46
+ customRange={customRange}
47
+ onPresetChange={(p) => {
48
+ setPreset(p);
49
+ setCustomRange(null);
50
+ }}
51
+ onCustomRangeChange={(from, to, label) => {
52
+ setCustomRange({ from, to });
53
+ setPreset(null);
54
+ console.log("Custom range:", { from, to, label });
55
+ }}
56
+ onClearCustomRange={() => {
57
+ setCustomRange(null);
58
+ setPreset("7d");
59
+ }}
60
+ />
61
+ );
62
+ }
63
+
39
64
  /**
40
65
  * Default time range picker with preset badges and calendar.
41
66
  * Supports natural language input with AI parsing.
42
67
  */
43
68
  export const Default: Story = {
44
- render: () => {
45
- const [preset, setPreset] = useState<DateRangePreset | null>("7d");
46
- const [customRange, setCustomRange] = useState<TimeRange | null>(null);
47
-
48
- return (
49
- <TimeRangePicker
50
- preset={customRange ? null : preset}
51
- customRange={customRange}
52
- onPresetChange={(p) => {
53
- setPreset(p);
54
- setCustomRange(null);
55
- }}
56
- onCustomRangeChange={(from, to, label) => {
57
- setCustomRange({ from, to });
58
- setPreset(null);
59
- console.log("Custom range:", { from, to, label });
60
- }}
61
- onClearCustomRange={() => {
62
- setCustomRange(null);
63
- setPreset("7d");
64
- }}
65
- />
66
- );
67
- },
69
+ render: () => <DefaultStory />,
68
70
  };
69
71
 
72
+ function WithTimezoneStory() {
73
+ const [preset, setPreset] = useState<DateRangePreset | null>("30d");
74
+ const [customRange, setCustomRange] = useState<TimeRange | null>(null);
75
+
76
+ return (
77
+ <TimeRangePicker
78
+ preset={customRange ? null : preset}
79
+ customRange={customRange}
80
+ onPresetChange={(p) => {
81
+ setPreset(p);
82
+ setCustomRange(null);
83
+ }}
84
+ onCustomRangeChange={(from, to) => {
85
+ setCustomRange({ from, to });
86
+ setPreset(null);
87
+ }}
88
+ onClearCustomRange={() => {
89
+ setCustomRange(null);
90
+ setPreset("30d");
91
+ }}
92
+ timezone="UTC-08:00"
93
+ />
94
+ );
95
+ }
96
+
70
97
  /**
71
98
  * Time range picker with timezone indicator.
72
99
  */
73
100
  export const WithTimezone: Story = {
74
- render: () => {
75
- const [preset, setPreset] = useState<DateRangePreset | null>("30d");
76
- const [customRange, setCustomRange] = useState<TimeRange | null>(null);
101
+ render: () => <WithTimezoneStory />,
102
+ };
103
+
104
+ function WithLiveModeStory() {
105
+ const [preset, setPreset] = useState<DateRangePreset | null>("15m");
106
+ const [customRange, setCustomRange] = useState<TimeRange | null>(null);
107
+ const [isLive, setIsLive] = useState(true);
108
+
109
+ return (
110
+ <TimeRangePicker
111
+ preset={customRange ? null : preset}
112
+ customRange={customRange}
113
+ onPresetChange={(p) => {
114
+ setPreset(p);
115
+ setCustomRange(null);
116
+ }}
117
+ onCustomRangeChange={(from, to) => {
118
+ setCustomRange({ from, to });
119
+ setPreset(null);
120
+ }}
121
+ onClearCustomRange={() => {
122
+ setCustomRange(null);
123
+ setPreset("15m");
124
+ }}
125
+ showLive
126
+ isLive={isLive}
127
+ onLiveChange={setIsLive}
128
+ />
129
+ );
130
+ }
77
131
 
78
- return (
132
+ /**
133
+ * With LIVE mode toggle enabled.
134
+ */
135
+ export const WithLiveMode: Story = {
136
+ render: () => <WithLiveModeStory />,
137
+ };
138
+
139
+ /**
140
+ * Disabled state.
141
+ */
142
+ export const Disabled: Story = {
143
+ args: {
144
+ preset: "7d",
145
+ disabled: true,
146
+ },
147
+ };
148
+
149
+ function DatadogStyleStory() {
150
+ const [preset, setPreset] = useState<DateRangePreset | null>("7d");
151
+ const [customRange, setCustomRange] = useState<TimeRange | null>(null);
152
+ const [customLabel, setCustomLabel] = useState<string | null>(null);
153
+ const [isLive, setIsLive] = useState(false);
154
+
155
+ return (
156
+ <div className="space-y-4">
79
157
  <TimeRangePicker
80
158
  preset={customRange ? null : preset}
81
159
  customRange={customRange}
160
+ customRangeLabel={customLabel}
82
161
  onPresetChange={(p) => {
83
162
  setPreset(p);
84
163
  setCustomRange(null);
164
+ setCustomLabel(null);
85
165
  }}
86
- onCustomRangeChange={(from, to) => {
166
+ onCustomRangeChange={(from, to, label) => {
87
167
  setCustomRange({ from, to });
88
168
  setPreset(null);
169
+ setCustomLabel(label || null);
89
170
  }}
90
171
  onClearCustomRange={() => {
91
172
  setCustomRange(null);
92
- setPreset("30d");
173
+ setPreset("7d");
174
+ setCustomLabel(null);
93
175
  }}
176
+ showLive
177
+ isLive={isLive}
178
+ onLiveChange={setIsLive}
94
179
  timezone="UTC-08:00"
95
180
  />
96
- );
97
- },
98
- };
181
+ <div className="rounded-md bg-muted p-3 text-xs text-muted-foreground">
182
+ <strong>Current state:</strong>
183
+ <pre className="mt-1 overflow-auto">
184
+ {JSON.stringify(
185
+ {
186
+ preset,
187
+ customRange: customRange
188
+ ? {
189
+ from: customRange.from.toISOString(),
190
+ to: customRange.to.toISOString(),
191
+ }
192
+ : null,
193
+ customLabel,
194
+ isLive,
195
+ },
196
+ null,
197
+ 2,
198
+ )}
199
+ </pre>
200
+ </div>
201
+ </div>
202
+ );
203
+ }
99
204
 
100
205
  /**
101
- * With LIVE mode toggle enabled.
206
+ * Full Datadog-style configuration with all features.
207
+ * Type natural language like "3 days ago", "last Wednesday", "past 2 weeks".
102
208
  */
103
- export const WithLiveMode: Story = {
104
- render: () => {
105
- const [preset, setPreset] = useState<DateRangePreset | null>("15m");
106
- const [customRange, setCustomRange] = useState<TimeRange | null>(null);
107
- const [isLive, setIsLive] = useState(true);
209
+ export const DatadogStyle: Story = {
210
+ render: () => <DatadogStyleStory />,
211
+ };
108
212
 
109
- return (
213
+ function NaturalLanguageParsingStory() {
214
+ const [preset, setPreset] = useState<DateRangePreset | null>("30d");
215
+ const [customRange, setCustomRange] = useState<TimeRange | null>(null);
216
+ const [customLabel, setCustomLabel] = useState<string | null>(null);
217
+
218
+ return (
219
+ <div className="space-y-4">
220
+ <p className="text-sm text-muted-foreground">
221
+ Try typing: "yesterday", "3 days ago", "last Wednesday", "January"
222
+ </p>
110
223
  <TimeRangePicker
111
224
  preset={customRange ? null : preset}
112
225
  customRange={customRange}
226
+ customRangeLabel={customLabel}
113
227
  onPresetChange={(p) => {
114
228
  setPreset(p);
115
229
  setCustomRange(null);
230
+ setCustomLabel(null);
116
231
  }}
117
- onCustomRangeChange={(from, to) => {
232
+ onCustomRangeChange={(from, to, label) => {
118
233
  setCustomRange({ from, to });
119
234
  setPreset(null);
235
+ setCustomLabel(label || null);
236
+ console.log("AI parsed:", { from, to, label });
120
237
  }}
121
238
  onClearCustomRange={() => {
122
239
  setCustomRange(null);
123
- setPreset("15m");
240
+ setPreset("30d");
241
+ setCustomLabel(null);
124
242
  }}
125
- showLive
126
- isLive={isLive}
127
- onLiveChange={setIsLive}
128
243
  />
129
- );
130
- },
131
- };
132
-
133
- /**
134
- * Disabled state.
135
- */
136
- export const Disabled: Story = {
137
- args: {
138
- preset: "7d",
139
- disabled: true,
140
- },
141
- };
142
-
143
- /**
144
- * Full Datadog-style configuration with all features.
145
- * Type natural language like "3 days ago", "last Wednesday", "past 2 weeks".
146
- */
147
- export const DatadogStyle: Story = {
148
- render: () => {
149
- const [preset, setPreset] = useState<DateRangePreset | null>("7d");
150
- const [customRange, setCustomRange] = useState<TimeRange | null>(null);
151
- const [customLabel, setCustomLabel] = useState<string | null>(null);
152
- const [isLive, setIsLive] = useState(false);
153
-
154
- return (
155
- <div className="space-y-4">
156
- <TimeRangePicker
157
- preset={customRange ? null : preset}
158
- customRange={customRange}
159
- customRangeLabel={customLabel}
160
- onPresetChange={(p) => {
161
- setPreset(p);
162
- setCustomRange(null);
163
- setCustomLabel(null);
164
- }}
165
- onCustomRangeChange={(from, to, label) => {
166
- setCustomRange({ from, to });
167
- setPreset(null);
168
- setCustomLabel(label || null);
169
- }}
170
- onClearCustomRange={() => {
171
- setCustomRange(null);
172
- setPreset("7d");
173
- setCustomLabel(null);
174
- }}
175
- showLive
176
- isLive={isLive}
177
- onLiveChange={setIsLive}
178
- timezone="UTC-08:00"
179
- />
180
- <div className="rounded-md bg-muted p-3 text-xs text-muted-foreground">
181
- <strong>Current state:</strong>
182
- <pre className="mt-1 overflow-auto">
183
- {JSON.stringify(
184
- {
185
- preset,
186
- customRange: customRange
187
- ? {
188
- from: customRange.from.toISOString(),
189
- to: customRange.to.toISOString(),
190
- }
191
- : null,
192
- customLabel,
193
- isLive,
194
- },
195
- null,
196
- 2,
197
- )}
198
- </pre>
199
- </div>
200
- </div>
201
- );
202
- },
203
- };
244
+ </div>
245
+ );
246
+ }
204
247
 
205
248
  /**
206
249
  * Natural language parsing demo.
@@ -212,38 +255,5 @@ export const DatadogStyle: Story = {
212
255
  * - "January 2024"
213
256
  */
214
257
  export const NaturalLanguageParsing: Story = {
215
- render: () => {
216
- const [preset, setPreset] = useState<DateRangePreset | null>("30d");
217
- const [customRange, setCustomRange] = useState<TimeRange | null>(null);
218
- const [customLabel, setCustomLabel] = useState<string | null>(null);
219
-
220
- return (
221
- <div className="space-y-4">
222
- <p className="text-sm text-muted-foreground">
223
- Try typing: "yesterday", "3 days ago", "last Wednesday", "January"
224
- </p>
225
- <TimeRangePicker
226
- preset={customRange ? null : preset}
227
- customRange={customRange}
228
- customRangeLabel={customLabel}
229
- onPresetChange={(p) => {
230
- setPreset(p);
231
- setCustomRange(null);
232
- setCustomLabel(null);
233
- }}
234
- onCustomRangeChange={(from, to, label) => {
235
- setCustomRange({ from, to });
236
- setPreset(null);
237
- setCustomLabel(label || null);
238
- console.log("AI parsed:", { from, to, label });
239
- }}
240
- onClearCustomRange={() => {
241
- setCustomRange(null);
242
- setPreset("30d");
243
- setCustomLabel(null);
244
- }}
245
- />
246
- </div>
247
- );
248
- },
258
+ render: () => <NaturalLanguageParsingStory />,
249
259
  };
@@ -155,7 +155,7 @@ const BADGE_WIDTH = "min-w-10";
155
155
 
156
156
  export function getPresetRange(preset: DateRangePreset): TimeRange {
157
157
  const p = PRESETS.find((p) => p.value === preset);
158
- return p ? p.getRange() : PRESETS[5].getRange(); // Default to 3d
158
+ return p ? p.getRange() : PRESETS[5]!.getRange(); // Default to 3d
159
159
  }
160
160
 
161
161
  function getPresetByValue(value: DateRangePreset): TimeRangePreset | undefined {
@@ -188,11 +188,15 @@ function parseAsLocalDate(isoString: string): Date {
188
188
  // Try to extract just the date part and create a local date
189
189
  const dateMatch = isoString.match(/^(\d{4})-(\d{2})-(\d{2})/);
190
190
  if (dateMatch) {
191
- const [, year, month, day] = dateMatch;
191
+ const year = dateMatch[1]!;
192
+ const month = dateMatch[2]!;
193
+ const day = dateMatch[3]!;
192
194
  // Check if there's a time component
193
195
  const timeMatch = isoString.match(/T(\d{2}):(\d{2}):?(\d{2})?/);
194
196
  if (timeMatch) {
195
- const [, hours, minutes, seconds = "0"] = timeMatch;
197
+ const hours = timeMatch[1]!;
198
+ const minutes = timeMatch[2]!;
199
+ const seconds = timeMatch[3] ?? "0";
196
200
  return new Date(
197
201
  parseInt(year),
198
202
  parseInt(month) - 1,
@@ -372,7 +376,7 @@ function TimeRangePicker({
372
376
  projectSlug,
373
377
  authHeaders,
374
378
  className,
375
- }: TimeRangePickerProps) {
379
+ }: TimeRangePickerProps): React.JSX.Element {
376
380
  const [isOpen, setIsOpen] = React.useState(false);
377
381
  const [showCalendar, setShowCalendar] = React.useState(false);
378
382
  const [inputValue, setInputValue] = React.useState("");
@@ -585,7 +589,9 @@ function TimeRangePicker({
585
589
  onClick={handleInputClick}
586
590
  onFocus={handleInputFocus}
587
591
  onBlur={handleInputBlur}
588
- onKeyDown={handleInputKeyDown}
592
+ onKeyDown={(e) => {
593
+ void handleInputKeyDown(e);
594
+ }}
589
595
  placeholder="e.g., 3 days ago, last week..."
590
596
  disabled={disabled}
591
597
  className={cn(