@gram-ai/elements 1.25.2 → 1.26.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 (160) hide show
  1. package/dist/components/Chat/stories/Charts.stories.d.ts +37 -0
  2. package/dist/components/Chat/stories/GenerativeUI.stories.d.ts +17 -0
  3. package/dist/components/ui/button.d.ts +1 -1
  4. package/dist/components/ui/buttonVariants.d.ts +1 -1
  5. package/dist/components/ui/charts.stories.d.ts +43 -0
  6. package/dist/components/ui/generative-ui.stories.d.ts +53 -0
  7. package/dist/elements.cjs +1 -1
  8. package/dist/elements.css +1 -1
  9. package/dist/elements.js +6 -6
  10. package/dist/index-BJnv49-A.js +37057 -0
  11. package/dist/index-BJnv49-A.js.map +1 -0
  12. package/dist/index-BpJstUh1.cjs +280 -0
  13. package/dist/index-BpJstUh1.cjs.map +1 -0
  14. package/dist/index-CUitXazZ.js +30426 -0
  15. package/dist/index-CUitXazZ.js.map +1 -0
  16. package/dist/index-ChW-CSuu.cjs +147 -0
  17. package/dist/index-ChW-CSuu.cjs.map +1 -0
  18. package/dist/plugins/chart/catalog.d.ts +123 -0
  19. package/dist/plugins/chart/index.d.ts +1 -1
  20. package/dist/plugins/chart/ui/area-chart.d.ts +16 -0
  21. package/dist/plugins/chart/ui/bar-chart.d.ts +16 -0
  22. package/dist/plugins/chart/ui/donut-chart.d.ts +17 -0
  23. package/dist/plugins/chart/ui/index.d.ts +7 -0
  24. package/dist/plugins/chart/ui/line-chart.d.ts +17 -0
  25. package/dist/plugins/chart/ui/pie-chart.d.ts +15 -0
  26. package/dist/plugins/chart/ui/radar-chart.d.ts +14 -0
  27. package/dist/plugins/chart/ui/scatter-chart.d.ts +18 -0
  28. package/dist/plugins/components/MacOSWindowFrame.d.ts +13 -0
  29. package/dist/plugins/components/PluginLoadingState.d.ts +1 -1
  30. package/dist/plugins/generative-ui/catalog.d.ts +293 -0
  31. package/dist/plugins/generative-ui/ui/accordion-wrapper.d.ts +18 -0
  32. package/dist/plugins/generative-ui/ui/accordion.d.ts +7 -0
  33. package/dist/plugins/generative-ui/ui/action-button.d.ts +10 -0
  34. package/dist/plugins/generative-ui/ui/alert-wrapper.d.ts +9 -0
  35. package/dist/plugins/generative-ui/ui/alert.d.ts +9 -0
  36. package/dist/plugins/generative-ui/ui/avatar-wrapper.d.ts +9 -0
  37. package/dist/plugins/generative-ui/ui/avatar.d.ts +11 -0
  38. package/dist/plugins/generative-ui/ui/badge.d.ts +12 -0
  39. package/dist/plugins/generative-ui/ui/button-wrapper.d.ts +15 -0
  40. package/dist/plugins/generative-ui/ui/button.d.ts +10 -0
  41. package/dist/plugins/generative-ui/ui/card-wrapper.d.ts +10 -0
  42. package/dist/plugins/generative-ui/ui/card.d.ts +9 -0
  43. package/dist/plugins/generative-ui/ui/checkbox-wrapper.d.ts +10 -0
  44. package/dist/plugins/generative-ui/ui/checkbox.d.ts +4 -0
  45. package/dist/plugins/generative-ui/ui/data-table.d.ts +10 -0
  46. package/dist/plugins/generative-ui/ui/dialog.d.ts +17 -0
  47. package/dist/plugins/generative-ui/ui/dropdown-menu.d.ts +25 -0
  48. package/dist/plugins/generative-ui/ui/grid.d.ts +6 -0
  49. package/dist/plugins/generative-ui/ui/index.d.ts +40 -0
  50. package/dist/plugins/generative-ui/ui/input-wrapper.d.ts +11 -0
  51. package/dist/plugins/generative-ui/ui/input.d.ts +3 -0
  52. package/dist/plugins/generative-ui/ui/label.d.ts +4 -0
  53. package/dist/plugins/generative-ui/ui/list.d.ts +6 -0
  54. package/dist/plugins/generative-ui/ui/metric.d.ts +7 -0
  55. package/dist/plugins/generative-ui/ui/pagination.d.ts +13 -0
  56. package/dist/plugins/generative-ui/ui/popover.d.ts +10 -0
  57. package/dist/plugins/generative-ui/ui/progress.d.ts +10 -0
  58. package/dist/plugins/generative-ui/ui/radio-group.d.ts +5 -0
  59. package/dist/plugins/generative-ui/ui/select-wrapper.d.ts +13 -0
  60. package/dist/plugins/generative-ui/ui/select.d.ts +15 -0
  61. package/dist/plugins/generative-ui/ui/separator.d.ts +4 -0
  62. package/dist/plugins/generative-ui/ui/skeleton-wrapper.d.ts +9 -0
  63. package/dist/plugins/generative-ui/ui/skeleton.d.ts +2 -0
  64. package/dist/plugins/generative-ui/ui/stack.d.ts +8 -0
  65. package/dist/plugins/generative-ui/ui/switch.d.ts +6 -0
  66. package/dist/plugins/generative-ui/ui/table.d.ts +10 -0
  67. package/dist/plugins/generative-ui/ui/tabs-wrapper.d.ts +21 -0
  68. package/dist/plugins/generative-ui/ui/tabs.d.ts +11 -0
  69. package/dist/plugins/generative-ui/ui/text.d.ts +7 -0
  70. package/dist/plugins/generative-ui/ui/textarea.d.ts +3 -0
  71. package/dist/plugins/generative-ui/ui/tooltip.d.ts +7 -0
  72. package/dist/plugins.cjs +1 -1
  73. package/dist/plugins.js +1 -1
  74. package/dist/{profiler-BaG0scxd.js → profiler-D4Tw5ecI.js} +2 -2
  75. package/dist/{profiler-BaG0scxd.js.map → profiler-D4Tw5ecI.js.map} +1 -1
  76. package/dist/{profiler-CuqENACf.cjs → profiler-DCWYDZ1F.cjs} +2 -2
  77. package/dist/{profiler-CuqENACf.cjs.map → profiler-DCWYDZ1F.cjs.map} +1 -1
  78. package/dist/{startRecording-BiLmoqZa.cjs → startRecording-3sTskM3H.cjs} +2 -2
  79. package/dist/{startRecording-BiLmoqZa.cjs.map → startRecording-3sTskM3H.cjs.map} +1 -1
  80. package/dist/{startRecording-86bHmd-l.js → startRecording-BHhcCWQE.js} +2 -2
  81. package/dist/{startRecording-86bHmd-l.js.map → startRecording-BHhcCWQE.js.map} +1 -1
  82. package/package.json +4 -1
  83. package/src/components/Chat/stories/Charts.stories.tsx +260 -0
  84. package/src/components/Chat/stories/ConnectionConfiguration.stories.tsx +6 -6
  85. package/src/components/Chat/stories/GenerativeUI.stories.tsx +113 -0
  86. package/src/components/Replay.stories.tsx +1 -1
  87. package/src/components/Replay.tsx +18 -13
  88. package/src/components/ui/charts.stories.tsx +246 -0
  89. package/src/components/ui/generative-ui.stories.tsx +557 -0
  90. package/src/components/ui/generative-ui.tsx +60 -360
  91. package/src/components/ui/tool-ui.stories.tsx +6 -3
  92. package/src/hooks/useAuth.ts +17 -1
  93. package/src/hooks/useFollowOnSuggestions.ts +6 -1
  94. package/src/plugins/chart/catalog.ts +141 -0
  95. package/src/plugins/chart/component.tsx +79 -125
  96. package/src/plugins/chart/index.ts +141 -89
  97. package/src/plugins/chart/ui/area-chart.tsx +133 -0
  98. package/src/plugins/chart/ui/bar-chart.tsx +137 -0
  99. package/src/plugins/chart/ui/donut-chart.tsx +167 -0
  100. package/src/plugins/chart/ui/index.ts +7 -0
  101. package/src/plugins/chart/ui/line-chart.tsx +135 -0
  102. package/src/plugins/chart/ui/pie-chart.tsx +148 -0
  103. package/src/plugins/chart/ui/radar-chart.tsx +105 -0
  104. package/src/plugins/chart/ui/scatter-chart.tsx +132 -0
  105. package/src/plugins/components/MacOSWindowFrame.tsx +55 -0
  106. package/src/plugins/components/PluginLoadingState.tsx +9 -13
  107. package/src/plugins/generative-ui/catalog.ts +277 -0
  108. package/src/plugins/generative-ui/component.tsx +112 -21
  109. package/src/plugins/generative-ui/index.ts +20 -141
  110. package/src/plugins/generative-ui/ui/accordion-wrapper.tsx +57 -0
  111. package/src/plugins/generative-ui/ui/accordion.tsx +66 -0
  112. package/src/plugins/generative-ui/ui/action-button.tsx +68 -0
  113. package/src/plugins/generative-ui/ui/alert-wrapper.tsx +26 -0
  114. package/src/plugins/generative-ui/ui/alert.tsx +66 -0
  115. package/src/plugins/generative-ui/ui/avatar-wrapper.tsx +22 -0
  116. package/src/plugins/generative-ui/ui/avatar.tsx +109 -0
  117. package/src/plugins/generative-ui/ui/badge.tsx +65 -0
  118. package/src/plugins/generative-ui/ui/button-wrapper.tsx +32 -0
  119. package/src/plugins/generative-ui/ui/button.tsx +65 -0
  120. package/src/plugins/generative-ui/ui/card-wrapper.tsx +36 -0
  121. package/src/plugins/generative-ui/ui/card.tsx +92 -0
  122. package/src/plugins/generative-ui/ui/checkbox-wrapper.tsx +39 -0
  123. package/src/plugins/generative-ui/ui/checkbox.tsx +32 -0
  124. package/src/plugins/generative-ui/ui/data-table.tsx +53 -0
  125. package/src/plugins/generative-ui/ui/dialog.tsx +158 -0
  126. package/src/plugins/generative-ui/ui/dropdown-menu.tsx +257 -0
  127. package/src/plugins/generative-ui/ui/grid.tsx +29 -0
  128. package/src/plugins/generative-ui/ui/index.ts +43 -0
  129. package/src/plugins/generative-ui/ui/input-wrapper.tsx +38 -0
  130. package/src/plugins/generative-ui/ui/input.tsx +21 -0
  131. package/src/plugins/generative-ui/ui/label.tsx +24 -0
  132. package/src/plugins/generative-ui/ui/list.tsx +34 -0
  133. package/src/plugins/generative-ui/ui/metric.tsx +53 -0
  134. package/src/plugins/generative-ui/ui/pagination.tsx +127 -0
  135. package/src/plugins/generative-ui/ui/popover.tsx +89 -0
  136. package/src/plugins/generative-ui/ui/progress.tsx +57 -0
  137. package/src/plugins/generative-ui/ui/radio-group.tsx +45 -0
  138. package/src/plugins/generative-ui/ui/select-wrapper.tsx +41 -0
  139. package/src/plugins/generative-ui/ui/select.tsx +190 -0
  140. package/src/plugins/generative-ui/ui/separator.tsx +28 -0
  141. package/src/plugins/generative-ui/ui/skeleton-wrapper.tsx +30 -0
  142. package/src/plugins/generative-ui/ui/skeleton.tsx +13 -0
  143. package/src/plugins/generative-ui/ui/stack.tsx +54 -0
  144. package/src/plugins/generative-ui/ui/switch.tsx +35 -0
  145. package/src/plugins/generative-ui/ui/table.tsx +116 -0
  146. package/src/plugins/generative-ui/ui/tabs-wrapper.tsx +51 -0
  147. package/src/plugins/generative-ui/ui/tabs.tsx +92 -0
  148. package/src/plugins/generative-ui/ui/text.tsx +33 -0
  149. package/src/plugins/generative-ui/ui/textarea.tsx +18 -0
  150. package/src/plugins/generative-ui/ui/tooltip.tsx +57 -0
  151. package/dist/components/Chat/stories/Plugins.stories.d.ts +0 -12
  152. package/dist/index-B8nSCdu4.cjs +0 -251
  153. package/dist/index-B8nSCdu4.cjs.map +0 -1
  154. package/dist/index-CAtaLV1E.cjs +0 -187
  155. package/dist/index-CAtaLV1E.cjs.map +0 -1
  156. package/dist/index-CJrwma08.js +0 -27232
  157. package/dist/index-CJrwma08.js.map +0 -1
  158. package/dist/index-DLWQ91ow.js +0 -40049
  159. package/dist/index-DLWQ91ow.js.map +0 -1
  160. package/src/components/Chat/stories/Plugins.stories.tsx +0 -158
@@ -0,0 +1,257 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import { CheckIcon, ChevronRightIcon, CircleIcon } from 'lucide-react'
5
+ import { DropdownMenu as DropdownMenuPrimitive } from 'radix-ui'
6
+
7
+ import { cn } from '@/lib/utils'
8
+
9
+ function DropdownMenu({
10
+ ...props
11
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
12
+ return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />
13
+ }
14
+
15
+ function DropdownMenuPortal({
16
+ ...props
17
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
18
+ return (
19
+ <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
20
+ )
21
+ }
22
+
23
+ function DropdownMenuTrigger({
24
+ ...props
25
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
26
+ return (
27
+ <DropdownMenuPrimitive.Trigger
28
+ data-slot="dropdown-menu-trigger"
29
+ {...props}
30
+ />
31
+ )
32
+ }
33
+
34
+ function DropdownMenuContent({
35
+ className,
36
+ sideOffset = 4,
37
+ ...props
38
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
39
+ return (
40
+ <DropdownMenuPrimitive.Portal>
41
+ <DropdownMenuPrimitive.Content
42
+ data-slot="dropdown-menu-content"
43
+ sideOffset={sideOffset}
44
+ className={cn(
45
+ 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md',
46
+ className
47
+ )}
48
+ {...props}
49
+ />
50
+ </DropdownMenuPrimitive.Portal>
51
+ )
52
+ }
53
+
54
+ function DropdownMenuGroup({
55
+ ...props
56
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
57
+ return (
58
+ <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
59
+ )
60
+ }
61
+
62
+ function DropdownMenuItem({
63
+ className,
64
+ inset,
65
+ variant = 'default',
66
+ ...props
67
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
68
+ inset?: boolean
69
+ variant?: 'default' | 'destructive'
70
+ }) {
71
+ return (
72
+ <DropdownMenuPrimitive.Item
73
+ data-slot="dropdown-menu-item"
74
+ data-inset={inset}
75
+ data-variant={variant}
76
+ className={cn(
77
+ "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
78
+ className
79
+ )}
80
+ {...props}
81
+ />
82
+ )
83
+ }
84
+
85
+ function DropdownMenuCheckboxItem({
86
+ className,
87
+ children,
88
+ checked,
89
+ ...props
90
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {
91
+ return (
92
+ <DropdownMenuPrimitive.CheckboxItem
93
+ data-slot="dropdown-menu-checkbox-item"
94
+ className={cn(
95
+ "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
96
+ className
97
+ )}
98
+ checked={checked}
99
+ {...props}
100
+ >
101
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
102
+ <DropdownMenuPrimitive.ItemIndicator>
103
+ <CheckIcon className="size-4" />
104
+ </DropdownMenuPrimitive.ItemIndicator>
105
+ </span>
106
+ {children}
107
+ </DropdownMenuPrimitive.CheckboxItem>
108
+ )
109
+ }
110
+
111
+ function DropdownMenuRadioGroup({
112
+ ...props
113
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
114
+ return (
115
+ <DropdownMenuPrimitive.RadioGroup
116
+ data-slot="dropdown-menu-radio-group"
117
+ {...props}
118
+ />
119
+ )
120
+ }
121
+
122
+ function DropdownMenuRadioItem({
123
+ className,
124
+ children,
125
+ ...props
126
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {
127
+ return (
128
+ <DropdownMenuPrimitive.RadioItem
129
+ data-slot="dropdown-menu-radio-item"
130
+ className={cn(
131
+ "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
132
+ className
133
+ )}
134
+ {...props}
135
+ >
136
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
137
+ <DropdownMenuPrimitive.ItemIndicator>
138
+ <CircleIcon className="size-2 fill-current" />
139
+ </DropdownMenuPrimitive.ItemIndicator>
140
+ </span>
141
+ {children}
142
+ </DropdownMenuPrimitive.RadioItem>
143
+ )
144
+ }
145
+
146
+ function DropdownMenuLabel({
147
+ className,
148
+ inset,
149
+ ...props
150
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
151
+ inset?: boolean
152
+ }) {
153
+ return (
154
+ <DropdownMenuPrimitive.Label
155
+ data-slot="dropdown-menu-label"
156
+ data-inset={inset}
157
+ className={cn(
158
+ 'px-2 py-1.5 text-sm font-medium data-[inset]:pl-8',
159
+ className
160
+ )}
161
+ {...props}
162
+ />
163
+ )
164
+ }
165
+
166
+ function DropdownMenuSeparator({
167
+ className,
168
+ ...props
169
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
170
+ return (
171
+ <DropdownMenuPrimitive.Separator
172
+ data-slot="dropdown-menu-separator"
173
+ className={cn('bg-border -mx-1 my-1 h-px', className)}
174
+ {...props}
175
+ />
176
+ )
177
+ }
178
+
179
+ function DropdownMenuShortcut({
180
+ className,
181
+ ...props
182
+ }: React.ComponentProps<'span'>) {
183
+ return (
184
+ <span
185
+ data-slot="dropdown-menu-shortcut"
186
+ className={cn(
187
+ 'text-muted-foreground ml-auto text-xs tracking-widest',
188
+ className
189
+ )}
190
+ {...props}
191
+ />
192
+ )
193
+ }
194
+
195
+ function DropdownMenuSub({
196
+ ...props
197
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {
198
+ return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />
199
+ }
200
+
201
+ function DropdownMenuSubTrigger({
202
+ className,
203
+ inset,
204
+ children,
205
+ ...props
206
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
207
+ inset?: boolean
208
+ }) {
209
+ return (
210
+ <DropdownMenuPrimitive.SubTrigger
211
+ data-slot="dropdown-menu-sub-trigger"
212
+ data-inset={inset}
213
+ className={cn(
214
+ "focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
215
+ className
216
+ )}
217
+ {...props}
218
+ >
219
+ {children}
220
+ <ChevronRightIcon className="ml-auto size-4" />
221
+ </DropdownMenuPrimitive.SubTrigger>
222
+ )
223
+ }
224
+
225
+ function DropdownMenuSubContent({
226
+ className,
227
+ ...props
228
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
229
+ return (
230
+ <DropdownMenuPrimitive.SubContent
231
+ data-slot="dropdown-menu-sub-content"
232
+ className={cn(
233
+ 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg',
234
+ className
235
+ )}
236
+ {...props}
237
+ />
238
+ )
239
+ }
240
+
241
+ export {
242
+ DropdownMenu,
243
+ DropdownMenuPortal,
244
+ DropdownMenuTrigger,
245
+ DropdownMenuContent,
246
+ DropdownMenuGroup,
247
+ DropdownMenuLabel,
248
+ DropdownMenuItem,
249
+ DropdownMenuCheckboxItem,
250
+ DropdownMenuRadioGroup,
251
+ DropdownMenuRadioItem,
252
+ DropdownMenuSeparator,
253
+ DropdownMenuShortcut,
254
+ DropdownMenuSub,
255
+ DropdownMenuSubTrigger,
256
+ DropdownMenuSubContent,
257
+ }
@@ -0,0 +1,29 @@
1
+ import * as React from 'react'
2
+ import { cn } from '@/lib/utils'
3
+
4
+ export interface GridProps extends React.ComponentProps<'div'> {
5
+ columns?: number
6
+ gap?: 'sm' | 'md' | 'lg'
7
+ }
8
+
9
+ const gapClasses = {
10
+ sm: 'gap-2',
11
+ md: 'gap-4',
12
+ lg: 'gap-6',
13
+ }
14
+
15
+ export function Grid({
16
+ columns = 2,
17
+ gap = 'md',
18
+ className,
19
+ ...props
20
+ }: GridProps) {
21
+ return (
22
+ <div
23
+ data-slot="grid"
24
+ className={cn('grid', gapClasses[gap], className)}
25
+ style={{ gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))` }}
26
+ {...props}
27
+ />
28
+ )
29
+ }
@@ -0,0 +1,43 @@
1
+ // Vercel shadcn primitives
2
+ export * from './accordion'
3
+ export * from './alert'
4
+ export * from './avatar'
5
+ export * from './badge'
6
+ export * from './button'
7
+ export * from './card'
8
+ export * from './checkbox'
9
+ export * from './dialog'
10
+ export * from './dropdown-menu'
11
+ export * from './input'
12
+ export * from './label'
13
+ export * from './pagination'
14
+ export * from './popover'
15
+ export * from './progress'
16
+ export * from './radio-group'
17
+ export * from './select'
18
+ export * from './separator'
19
+ export * from './skeleton'
20
+ export * from './switch'
21
+ export * from './table'
22
+ export * from './tabs'
23
+ export * from './textarea'
24
+ export * from './tooltip'
25
+
26
+ // json-render catalog wrappers
27
+ export * from './accordion-wrapper'
28
+ export * from './action-button'
29
+ export * from './alert-wrapper'
30
+ export * from './avatar-wrapper'
31
+ export * from './button-wrapper'
32
+ export * from './card-wrapper'
33
+ export * from './checkbox-wrapper'
34
+ export * from './data-table'
35
+ export * from './grid'
36
+ export * from './input-wrapper'
37
+ export * from './list'
38
+ export * from './metric'
39
+ export * from './select-wrapper'
40
+ export * from './skeleton-wrapper'
41
+ export * from './stack'
42
+ export * from './tabs-wrapper'
43
+ export * from './text'
@@ -0,0 +1,38 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import { Input } from './input'
5
+ import { Label } from './label'
6
+
7
+ export interface InputWrapperProps {
8
+ label?: string
9
+ placeholder?: string
10
+ type?: 'text' | 'email' | 'password' | 'number' | 'tel'
11
+ /** Path for form state management (future use) */
12
+ valuePath: string
13
+ }
14
+
15
+ /**
16
+ * Input wrapper that adds label support.
17
+ */
18
+ export function InputWrapper({
19
+ label,
20
+ placeholder,
21
+ type = 'text',
22
+ valuePath,
23
+ }: InputWrapperProps) {
24
+ const id = React.useId()
25
+
26
+ return (
27
+ <div className="flex flex-col gap-1.5">
28
+ {label && <Label htmlFor={id}>{label}</Label>}
29
+ <Input
30
+ id={id}
31
+ type={type}
32
+ placeholder={placeholder}
33
+ name={valuePath}
34
+ data-value-path={valuePath}
35
+ />
36
+ </div>
37
+ )
38
+ }
@@ -0,0 +1,21 @@
1
+ import * as React from 'react'
2
+
3
+ import { cn } from '@/lib/utils'
4
+
5
+ function Input({ className, type, ...props }: React.ComponentProps<'input'>) {
6
+ return (
7
+ <input
8
+ type={type}
9
+ data-slot="input"
10
+ className={cn(
11
+ 'file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
12
+ 'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
13
+ 'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
14
+ className
15
+ )}
16
+ {...props}
17
+ />
18
+ )
19
+ }
20
+
21
+ export { Input }
@@ -0,0 +1,24 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import { Label as LabelPrimitive } from 'radix-ui'
5
+
6
+ import { cn } from '@/lib/utils'
7
+
8
+ function Label({
9
+ className,
10
+ ...props
11
+ }: React.ComponentProps<typeof LabelPrimitive.Root>) {
12
+ return (
13
+ <LabelPrimitive.Root
14
+ data-slot="label"
15
+ className={cn(
16
+ 'flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50',
17
+ className
18
+ )}
19
+ {...props}
20
+ />
21
+ )
22
+ }
23
+
24
+ export { Label }
@@ -0,0 +1,34 @@
1
+ import * as React from 'react'
2
+ import { cn } from '@/lib/utils'
3
+
4
+ export interface ListProps {
5
+ items: string[]
6
+ ordered?: boolean
7
+ className?: string
8
+ }
9
+
10
+ export function List({ items, ordered = false, className }: ListProps) {
11
+ const listClasses = cn(
12
+ 'text-foreground space-y-1 pl-4',
13
+ ordered ? 'list-decimal' : 'list-disc',
14
+ className
15
+ )
16
+
17
+ if (ordered) {
18
+ return (
19
+ <ol data-slot="list" className={listClasses}>
20
+ {items.map((item, index) => (
21
+ <li key={index}>{item}</li>
22
+ ))}
23
+ </ol>
24
+ )
25
+ }
26
+
27
+ return (
28
+ <ul data-slot="list" className={listClasses}>
29
+ {items.map((item, index) => (
30
+ <li key={index}>{item}</li>
31
+ ))}
32
+ </ul>
33
+ )
34
+ }
@@ -0,0 +1,53 @@
1
+ import * as React from 'react'
2
+ import { cn } from '@/lib/utils'
3
+
4
+ export interface MetricProps extends React.ComponentProps<'div'> {
5
+ label: string
6
+ value: string | number
7
+ format?: 'number' | 'currency' | 'percent'
8
+ }
9
+
10
+ function formatValue(
11
+ value: string | number,
12
+ format?: 'number' | 'currency' | 'percent'
13
+ ): string {
14
+ if (typeof value === 'string') return value
15
+
16
+ switch (format) {
17
+ case 'currency':
18
+ return new Intl.NumberFormat('en-US', {
19
+ style: 'currency',
20
+ currency: 'USD',
21
+ }).format(value)
22
+ case 'percent':
23
+ return new Intl.NumberFormat('en-US', {
24
+ style: 'percent',
25
+ minimumFractionDigits: 0,
26
+ maximumFractionDigits: 1,
27
+ }).format(value)
28
+ case 'number':
29
+ default:
30
+ return new Intl.NumberFormat('en-US').format(value)
31
+ }
32
+ }
33
+
34
+ export function Metric({
35
+ label,
36
+ value,
37
+ format,
38
+ className,
39
+ ...props
40
+ }: MetricProps) {
41
+ return (
42
+ <div
43
+ data-slot="metric"
44
+ className={cn('flex flex-col', className)}
45
+ {...props}
46
+ >
47
+ <span className="text-muted-foreground text-sm">{label}</span>
48
+ <span className="text-foreground text-2xl font-semibold">
49
+ {formatValue(value, format)}
50
+ </span>
51
+ </div>
52
+ )
53
+ }
@@ -0,0 +1,127 @@
1
+ import * as React from 'react'
2
+ import {
3
+ ChevronLeftIcon,
4
+ ChevronRightIcon,
5
+ MoreHorizontalIcon,
6
+ } from 'lucide-react'
7
+
8
+ import { cn } from '@/lib/utils'
9
+ import { buttonVariants, Button } from './button'
10
+
11
+ function Pagination({ className, ...props }: React.ComponentProps<'nav'>) {
12
+ return (
13
+ <nav
14
+ role="navigation"
15
+ aria-label="pagination"
16
+ data-slot="pagination"
17
+ className={cn('mx-auto flex w-full justify-center', className)}
18
+ {...props}
19
+ />
20
+ )
21
+ }
22
+
23
+ function PaginationContent({
24
+ className,
25
+ ...props
26
+ }: React.ComponentProps<'ul'>) {
27
+ return (
28
+ <ul
29
+ data-slot="pagination-content"
30
+ className={cn('flex flex-row items-center gap-1', className)}
31
+ {...props}
32
+ />
33
+ )
34
+ }
35
+
36
+ function PaginationItem({ ...props }: React.ComponentProps<'li'>) {
37
+ return <li data-slot="pagination-item" {...props} />
38
+ }
39
+
40
+ type PaginationLinkProps = {
41
+ isActive?: boolean
42
+ } & Pick<React.ComponentProps<typeof Button>, 'size'> &
43
+ React.ComponentProps<'a'>
44
+
45
+ function PaginationLink({
46
+ className,
47
+ isActive,
48
+ size = 'icon',
49
+ ...props
50
+ }: PaginationLinkProps) {
51
+ return (
52
+ <a
53
+ aria-current={isActive ? 'page' : undefined}
54
+ data-slot="pagination-link"
55
+ data-active={isActive}
56
+ className={cn(
57
+ buttonVariants({
58
+ variant: isActive ? 'outline' : 'ghost',
59
+ size,
60
+ }),
61
+ className
62
+ )}
63
+ {...props}
64
+ />
65
+ )
66
+ }
67
+
68
+ function PaginationPrevious({
69
+ className,
70
+ ...props
71
+ }: React.ComponentProps<typeof PaginationLink>) {
72
+ return (
73
+ <PaginationLink
74
+ aria-label="Go to previous page"
75
+ size="default"
76
+ className={cn('gap-1 px-2.5 sm:pl-2.5', className)}
77
+ {...props}
78
+ >
79
+ <ChevronLeftIcon />
80
+ <span className="hidden sm:block">Previous</span>
81
+ </PaginationLink>
82
+ )
83
+ }
84
+
85
+ function PaginationNext({
86
+ className,
87
+ ...props
88
+ }: React.ComponentProps<typeof PaginationLink>) {
89
+ return (
90
+ <PaginationLink
91
+ aria-label="Go to next page"
92
+ size="default"
93
+ className={cn('gap-1 px-2.5 sm:pr-2.5', className)}
94
+ {...props}
95
+ >
96
+ <span className="hidden sm:block">Next</span>
97
+ <ChevronRightIcon />
98
+ </PaginationLink>
99
+ )
100
+ }
101
+
102
+ function PaginationEllipsis({
103
+ className,
104
+ ...props
105
+ }: React.ComponentProps<'span'>) {
106
+ return (
107
+ <span
108
+ aria-hidden
109
+ data-slot="pagination-ellipsis"
110
+ className={cn('flex size-9 items-center justify-center', className)}
111
+ {...props}
112
+ >
113
+ <MoreHorizontalIcon className="size-4" />
114
+ <span className="sr-only">More pages</span>
115
+ </span>
116
+ )
117
+ }
118
+
119
+ export {
120
+ Pagination,
121
+ PaginationContent,
122
+ PaginationLink,
123
+ PaginationItem,
124
+ PaginationPrevious,
125
+ PaginationNext,
126
+ PaginationEllipsis,
127
+ }