@thesage/mcp 0.3.0 → 0.5.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.
- package/dist/index.js +969 -109
- package/dist/index.mjs +969 -109
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -80,7 +80,14 @@ var COMPONENT_REGISTRY = {
|
|
|
80
80
|
"Call-to-action elements"
|
|
81
81
|
],
|
|
82
82
|
dependencies: ["@radix-ui/react-slot"],
|
|
83
|
-
radixPrimitive: "@radix-ui/react-slot"
|
|
83
|
+
radixPrimitive: "@radix-ui/react-slot",
|
|
84
|
+
props: {
|
|
85
|
+
variant: { type: "'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'", default: "'default'", description: "Visual style variant" },
|
|
86
|
+
size: { type: "'sm' | 'default' | 'lg' | 'icon'", default: "'default'", description: "Size variant" },
|
|
87
|
+
disabled: { type: "boolean", default: "false", description: "Disable interaction" },
|
|
88
|
+
asChild: { type: "boolean", default: "false", description: "Render as child element via Radix Slot" }
|
|
89
|
+
},
|
|
90
|
+
example: `<Button variant="outline" size="sm" onClick={handleClick}>Click Me</Button>`
|
|
84
91
|
},
|
|
85
92
|
toggle: {
|
|
86
93
|
name: "Toggle",
|
|
@@ -94,7 +101,15 @@ var COMPONENT_REGISTRY = {
|
|
|
94
101
|
"Filter activation"
|
|
95
102
|
],
|
|
96
103
|
dependencies: ["@radix-ui/react-toggle"],
|
|
97
|
-
radixPrimitive: "@radix-ui/react-toggle"
|
|
104
|
+
radixPrimitive: "@radix-ui/react-toggle",
|
|
105
|
+
props: {
|
|
106
|
+
pressed: { type: "boolean", description: "Controlled pressed state" },
|
|
107
|
+
onPressedChange: { type: "(pressed: boolean) => void", description: "Callback on press change" },
|
|
108
|
+
variant: { type: "'default' | 'outline'", default: "'default'", description: "Visual variant" },
|
|
109
|
+
size: { type: "'sm' | 'default' | 'lg'", default: "'default'", description: "Size variant" },
|
|
110
|
+
disabled: { type: "boolean", default: "false", description: "Disable interaction" }
|
|
111
|
+
},
|
|
112
|
+
example: `<Toggle pressed={isBold} onPressedChange={setIsBold}><Bold className="h-4 w-4" /></Toggle>`
|
|
98
113
|
},
|
|
99
114
|
"toggle-group": {
|
|
100
115
|
name: "ToggleGroup",
|
|
@@ -108,7 +123,19 @@ var COMPONENT_REGISTRY = {
|
|
|
108
123
|
"Option selection"
|
|
109
124
|
],
|
|
110
125
|
dependencies: ["@radix-ui/react-toggle-group"],
|
|
111
|
-
radixPrimitive: "@radix-ui/react-toggle-group"
|
|
126
|
+
radixPrimitive: "@radix-ui/react-toggle-group",
|
|
127
|
+
props: {
|
|
128
|
+
type: { type: "'single' | 'multiple'", description: "Selection mode", required: true },
|
|
129
|
+
value: { type: "string | string[]", description: "Selected value(s)" },
|
|
130
|
+
onValueChange: { type: "(value) => void", description: "Callback on value change" },
|
|
131
|
+
variant: { type: "'default' | 'outline'", default: "'default'", description: "Visual variant" },
|
|
132
|
+
size: { type: "'sm' | 'default' | 'lg'", default: "'default'", description: "Size variant" }
|
|
133
|
+
},
|
|
134
|
+
subComponents: ["ToggleGroupItem"],
|
|
135
|
+
example: `<ToggleGroup type="single" value={align} onValueChange={setAlign}>
|
|
136
|
+
<ToggleGroupItem value="left">Left</ToggleGroupItem>
|
|
137
|
+
<ToggleGroupItem value="center">Center</ToggleGroupItem>
|
|
138
|
+
</ToggleGroup>`
|
|
112
139
|
},
|
|
113
140
|
// ============================================================================
|
|
114
141
|
// FORMS (11)
|
|
@@ -125,7 +152,16 @@ var COMPONENT_REGISTRY = {
|
|
|
125
152
|
"Bulk actions"
|
|
126
153
|
],
|
|
127
154
|
dependencies: ["@radix-ui/react-checkbox"],
|
|
128
|
-
radixPrimitive: "@radix-ui/react-checkbox"
|
|
155
|
+
radixPrimitive: "@radix-ui/react-checkbox",
|
|
156
|
+
props: {
|
|
157
|
+
checked: { type: "boolean | 'indeterminate'", description: "Checked state" },
|
|
158
|
+
onCheckedChange: { type: "(checked: boolean) => void", description: "Callback on check change" },
|
|
159
|
+
disabled: { type: "boolean", default: "false", description: "Disable interaction" }
|
|
160
|
+
},
|
|
161
|
+
example: `<div className="flex items-center gap-2">
|
|
162
|
+
<Checkbox id="terms" checked={accepted} onCheckedChange={setAccepted} />
|
|
163
|
+
<Label htmlFor="terms">Accept terms</Label>
|
|
164
|
+
</div>`
|
|
129
165
|
},
|
|
130
166
|
combobox: {
|
|
131
167
|
name: "Combobox",
|
|
@@ -139,7 +175,21 @@ var COMPONENT_REGISTRY = {
|
|
|
139
175
|
"Large option lists"
|
|
140
176
|
],
|
|
141
177
|
dependencies: ["cmdk", "@radix-ui/react-popover"],
|
|
142
|
-
radixPrimitive: "@radix-ui/react-popover"
|
|
178
|
+
radixPrimitive: "@radix-ui/react-popover",
|
|
179
|
+
props: {
|
|
180
|
+
options: { type: "{ value: string; label: string }[]", description: "List of options", required: true },
|
|
181
|
+
value: { type: "string", description: "Selected value" },
|
|
182
|
+
onValueChange: { type: "(value: string) => void", description: "Callback on selection" },
|
|
183
|
+
placeholder: { type: "string", description: "Trigger placeholder text" },
|
|
184
|
+
searchPlaceholder: { type: "string", description: "Search input placeholder" },
|
|
185
|
+
emptyText: { type: "string", description: "Text when no results found" }
|
|
186
|
+
},
|
|
187
|
+
example: `<Combobox
|
|
188
|
+
options={[{ value: 'react', label: 'React' }, { value: 'vue', label: 'Vue' }]}
|
|
189
|
+
value={framework}
|
|
190
|
+
onValueChange={setFramework}
|
|
191
|
+
placeholder="Select framework"
|
|
192
|
+
/>`
|
|
143
193
|
},
|
|
144
194
|
form: {
|
|
145
195
|
name: "Form",
|
|
@@ -152,7 +202,23 @@ var COMPONENT_REGISTRY = {
|
|
|
152
202
|
"Data entry",
|
|
153
203
|
"Multi-step forms"
|
|
154
204
|
],
|
|
155
|
-
dependencies: ["react-hook-form", "@hookform/resolvers", "zod"]
|
|
205
|
+
dependencies: ["react-hook-form", "@hookform/resolvers", "zod"],
|
|
206
|
+
props: {
|
|
207
|
+
"...form": { type: "UseFormReturn", description: "Spread react-hook-form useForm() return value", required: true }
|
|
208
|
+
},
|
|
209
|
+
subComponents: ["FormControl", "FormDescription", "FormField", "FormItem", "FormLabel", "FormMessage"],
|
|
210
|
+
example: `<Form {...form}>
|
|
211
|
+
<form onSubmit={form.handleSubmit(onSubmit)}>
|
|
212
|
+
<FormField control={form.control} name="email" render={({ field }) => (
|
|
213
|
+
<FormItem>
|
|
214
|
+
<FormLabel>Email</FormLabel>
|
|
215
|
+
<FormControl><Input {...field} /></FormControl>
|
|
216
|
+
<FormMessage />
|
|
217
|
+
</FormItem>
|
|
218
|
+
)} />
|
|
219
|
+
<Button type="submit">Submit</Button>
|
|
220
|
+
</form>
|
|
221
|
+
</Form>`
|
|
156
222
|
},
|
|
157
223
|
input: {
|
|
158
224
|
name: "Input",
|
|
@@ -165,7 +231,13 @@ var COMPONENT_REGISTRY = {
|
|
|
165
231
|
"Passwords",
|
|
166
232
|
"Numeric input"
|
|
167
233
|
],
|
|
168
|
-
dependencies: []
|
|
234
|
+
dependencies: [],
|
|
235
|
+
props: {
|
|
236
|
+
type: { type: "string", default: "'text'", description: "HTML input type" },
|
|
237
|
+
placeholder: { type: "string", description: "Placeholder text" },
|
|
238
|
+
disabled: { type: "boolean", default: "false", description: "Disable interaction" }
|
|
239
|
+
},
|
|
240
|
+
example: `<Input type="email" placeholder="Enter email" />`
|
|
169
241
|
},
|
|
170
242
|
"input-otp": {
|
|
171
243
|
name: "InputOTP",
|
|
@@ -178,7 +250,26 @@ var COMPONENT_REGISTRY = {
|
|
|
178
250
|
"Phone verification",
|
|
179
251
|
"Security codes"
|
|
180
252
|
],
|
|
181
|
-
dependencies: ["input-otp"]
|
|
253
|
+
dependencies: ["input-otp"],
|
|
254
|
+
props: {
|
|
255
|
+
maxLength: { type: "number", default: "6", description: "Maximum number of characters" },
|
|
256
|
+
value: { type: "string", description: "Controlled input value" },
|
|
257
|
+
onChange: { type: "(value: string) => void", description: "Callback on value change" }
|
|
258
|
+
},
|
|
259
|
+
subComponents: ["InputOTPGroup", "InputOTPSlot", "InputOTPSeparator"],
|
|
260
|
+
example: `<InputOTP maxLength={6}>
|
|
261
|
+
<InputOTPGroup>
|
|
262
|
+
<InputOTPSlot index={0} />
|
|
263
|
+
<InputOTPSlot index={1} />
|
|
264
|
+
<InputOTPSlot index={2} />
|
|
265
|
+
</InputOTPGroup>
|
|
266
|
+
<InputOTPSeparator />
|
|
267
|
+
<InputOTPGroup>
|
|
268
|
+
<InputOTPSlot index={3} />
|
|
269
|
+
<InputOTPSlot index={4} />
|
|
270
|
+
<InputOTPSlot index={5} />
|
|
271
|
+
</InputOTPGroup>
|
|
272
|
+
</InputOTP>`
|
|
182
273
|
},
|
|
183
274
|
label: {
|
|
184
275
|
name: "Label",
|
|
@@ -191,7 +282,12 @@ var COMPONENT_REGISTRY = {
|
|
|
191
282
|
"Accessible forms"
|
|
192
283
|
],
|
|
193
284
|
dependencies: ["@radix-ui/react-label"],
|
|
194
|
-
radixPrimitive: "@radix-ui/react-label"
|
|
285
|
+
radixPrimitive: "@radix-ui/react-label",
|
|
286
|
+
props: {
|
|
287
|
+
htmlFor: { type: "string", description: "ID of the associated form control" }
|
|
288
|
+
},
|
|
289
|
+
example: `<Label htmlFor="email">Email Address</Label>
|
|
290
|
+
<Input id="email" type="email" />`
|
|
195
291
|
},
|
|
196
292
|
"radio-group": {
|
|
197
293
|
name: "RadioGroup",
|
|
@@ -205,7 +301,19 @@ var COMPONENT_REGISTRY = {
|
|
|
205
301
|
"Shipping options"
|
|
206
302
|
],
|
|
207
303
|
dependencies: ["@radix-ui/react-radio-group"],
|
|
208
|
-
radixPrimitive: "@radix-ui/react-radio-group"
|
|
304
|
+
radixPrimitive: "@radix-ui/react-radio-group",
|
|
305
|
+
props: {
|
|
306
|
+
value: { type: "string", description: "Controlled selected value" },
|
|
307
|
+
onValueChange: { type: "(value: string) => void", description: "Callback on selection" },
|
|
308
|
+
disabled: { type: "boolean", default: "false", description: "Disable interaction" }
|
|
309
|
+
},
|
|
310
|
+
subComponents: ["RadioGroupItem"],
|
|
311
|
+
example: `<RadioGroup value={plan} onValueChange={setPlan}>
|
|
312
|
+
<div className="flex items-center gap-2">
|
|
313
|
+
<RadioGroupItem value="free" id="free" />
|
|
314
|
+
<Label htmlFor="free">Free</Label>
|
|
315
|
+
</div>
|
|
316
|
+
</RadioGroup>`
|
|
209
317
|
},
|
|
210
318
|
select: {
|
|
211
319
|
name: "Select",
|
|
@@ -219,7 +327,22 @@ var COMPONENT_REGISTRY = {
|
|
|
219
327
|
"Data sorting"
|
|
220
328
|
],
|
|
221
329
|
dependencies: ["@radix-ui/react-select"],
|
|
222
|
-
radixPrimitive: "@radix-ui/react-select"
|
|
330
|
+
radixPrimitive: "@radix-ui/react-select",
|
|
331
|
+
props: {
|
|
332
|
+
value: { type: "string", description: "Controlled selected value" },
|
|
333
|
+
onValueChange: { type: "(value: string) => void", description: "Callback on selection" },
|
|
334
|
+
defaultValue: { type: "string", description: "Default selected value" }
|
|
335
|
+
},
|
|
336
|
+
subComponents: ["SelectTrigger", "SelectValue", "SelectContent", "SelectItem", "SelectGroup", "SelectLabel", "SelectSeparator"],
|
|
337
|
+
example: `<Select value={theme} onValueChange={setTheme}>
|
|
338
|
+
<SelectTrigger className="w-[180px]">
|
|
339
|
+
<SelectValue placeholder="Select theme" />
|
|
340
|
+
</SelectTrigger>
|
|
341
|
+
<SelectContent>
|
|
342
|
+
<SelectItem value="light">Light</SelectItem>
|
|
343
|
+
<SelectItem value="dark">Dark</SelectItem>
|
|
344
|
+
</SelectContent>
|
|
345
|
+
</Select>`
|
|
223
346
|
},
|
|
224
347
|
slider: {
|
|
225
348
|
name: "Slider",
|
|
@@ -233,7 +356,16 @@ var COMPONENT_REGISTRY = {
|
|
|
233
356
|
"Zoom level"
|
|
234
357
|
],
|
|
235
358
|
dependencies: ["@radix-ui/react-slider"],
|
|
236
|
-
radixPrimitive: "@radix-ui/react-slider"
|
|
359
|
+
radixPrimitive: "@radix-ui/react-slider",
|
|
360
|
+
props: {
|
|
361
|
+
value: { type: "number[]", description: "Current value(s)" },
|
|
362
|
+
onValueChange: { type: "(value: number[]) => void", description: "Callback on value change" },
|
|
363
|
+
min: { type: "number", default: "0", description: "Minimum value" },
|
|
364
|
+
max: { type: "number", default: "100", description: "Maximum value" },
|
|
365
|
+
step: { type: "number", default: "1", description: "Step increment" },
|
|
366
|
+
disabled: { type: "boolean", default: "false", description: "Disable interaction" }
|
|
367
|
+
},
|
|
368
|
+
example: `<Slider value={[volume]} onValueChange={(v) => setVolume(v[0])} max={100} step={1} />`
|
|
237
369
|
},
|
|
238
370
|
switch: {
|
|
239
371
|
name: "Switch",
|
|
@@ -247,7 +379,15 @@ var COMPONENT_REGISTRY = {
|
|
|
247
379
|
"Mode switches"
|
|
248
380
|
],
|
|
249
381
|
dependencies: ["@radix-ui/react-switch"],
|
|
250
|
-
radixPrimitive: "@radix-ui/react-switch"
|
|
382
|
+
radixPrimitive: "@radix-ui/react-switch",
|
|
383
|
+
props: {
|
|
384
|
+
checked: { type: "boolean", description: "Controlled checked state" },
|
|
385
|
+
onCheckedChange: { type: "(checked: boolean) => void", description: "Callback on toggle" },
|
|
386
|
+
size: { type: "'sm' | 'md' | 'lg'", default: "'md'", description: "Size variant" },
|
|
387
|
+
disabled: { type: "boolean", default: "false", description: "Disable interaction" },
|
|
388
|
+
label: { type: "string", description: "Optional label text" }
|
|
389
|
+
},
|
|
390
|
+
example: `<Switch checked={enabled} onCheckedChange={setEnabled} size="md" />`
|
|
251
391
|
},
|
|
252
392
|
textarea: {
|
|
253
393
|
name: "Textarea",
|
|
@@ -260,7 +400,13 @@ var COMPONENT_REGISTRY = {
|
|
|
260
400
|
"Descriptions",
|
|
261
401
|
"Long-form text"
|
|
262
402
|
],
|
|
263
|
-
dependencies: []
|
|
403
|
+
dependencies: [],
|
|
404
|
+
props: {
|
|
405
|
+
placeholder: { type: "string", description: "Placeholder text" },
|
|
406
|
+
disabled: { type: "boolean", default: "false", description: "Disable interaction" },
|
|
407
|
+
rows: { type: "number", description: "Number of visible rows" }
|
|
408
|
+
},
|
|
409
|
+
example: `<Textarea placeholder="Write your message..." rows={4} />`
|
|
264
410
|
},
|
|
265
411
|
// ============================================================================
|
|
266
412
|
// NAVIGATION (6)
|
|
@@ -276,7 +422,17 @@ var COMPONENT_REGISTRY = {
|
|
|
276
422
|
"Location context",
|
|
277
423
|
"Back navigation"
|
|
278
424
|
],
|
|
279
|
-
dependencies: []
|
|
425
|
+
dependencies: [],
|
|
426
|
+
subComponents: ["BreadcrumbList", "BreadcrumbItem", "BreadcrumbLink", "BreadcrumbPage", "BreadcrumbSeparator", "BreadcrumbEllipsis"],
|
|
427
|
+
example: `<Breadcrumb>
|
|
428
|
+
<BreadcrumbList>
|
|
429
|
+
<BreadcrumbItem><BreadcrumbLink href="/">Home</BreadcrumbLink></BreadcrumbItem>
|
|
430
|
+
<BreadcrumbSeparator />
|
|
431
|
+
<BreadcrumbItem><BreadcrumbLink href="/docs">Docs</BreadcrumbLink></BreadcrumbItem>
|
|
432
|
+
<BreadcrumbSeparator />
|
|
433
|
+
<BreadcrumbItem><BreadcrumbPage>Current</BreadcrumbPage></BreadcrumbItem>
|
|
434
|
+
</BreadcrumbList>
|
|
435
|
+
</Breadcrumb>`
|
|
280
436
|
},
|
|
281
437
|
command: {
|
|
282
438
|
name: "Command",
|
|
@@ -289,7 +445,18 @@ var COMPONENT_REGISTRY = {
|
|
|
289
445
|
"Keyboard shortcuts",
|
|
290
446
|
"Power user features"
|
|
291
447
|
],
|
|
292
|
-
dependencies: ["cmdk"]
|
|
448
|
+
dependencies: ["cmdk"],
|
|
449
|
+
subComponents: ["CommandInput", "CommandList", "CommandEmpty", "CommandGroup", "CommandItem", "CommandSeparator", "CommandShortcut", "CommandDialog"],
|
|
450
|
+
example: `<Command>
|
|
451
|
+
<CommandInput placeholder="Type a command..." />
|
|
452
|
+
<CommandList>
|
|
453
|
+
<CommandEmpty>No results found.</CommandEmpty>
|
|
454
|
+
<CommandGroup heading="Actions">
|
|
455
|
+
<CommandItem>Search</CommandItem>
|
|
456
|
+
<CommandItem>Settings</CommandItem>
|
|
457
|
+
</CommandGroup>
|
|
458
|
+
</CommandList>
|
|
459
|
+
</Command>`
|
|
293
460
|
},
|
|
294
461
|
menubar: {
|
|
295
462
|
name: "Menubar",
|
|
@@ -303,7 +470,19 @@ var COMPONENT_REGISTRY = {
|
|
|
303
470
|
"Editor toolbars"
|
|
304
471
|
],
|
|
305
472
|
dependencies: ["@radix-ui/react-menubar"],
|
|
306
|
-
radixPrimitive: "@radix-ui/react-menubar"
|
|
473
|
+
radixPrimitive: "@radix-ui/react-menubar",
|
|
474
|
+
subComponents: ["MenubarMenu", "MenubarTrigger", "MenubarContent", "MenubarItem", "MenubarSeparator", "MenubarLabel", "MenubarCheckboxItem", "MenubarRadioGroup", "MenubarRadioItem", "MenubarSub", "MenubarSubTrigger", "MenubarSubContent", "MenubarShortcut"],
|
|
475
|
+
example: `<Menubar>
|
|
476
|
+
<MenubarMenu>
|
|
477
|
+
<MenubarTrigger>File</MenubarTrigger>
|
|
478
|
+
<MenubarContent>
|
|
479
|
+
<MenubarItem>New <MenubarShortcut>\u2318N</MenubarShortcut></MenubarItem>
|
|
480
|
+
<MenubarItem>Open <MenubarShortcut>\u2318O</MenubarShortcut></MenubarItem>
|
|
481
|
+
<MenubarSeparator />
|
|
482
|
+
<MenubarItem>Exit</MenubarItem>
|
|
483
|
+
</MenubarContent>
|
|
484
|
+
</MenubarMenu>
|
|
485
|
+
</Menubar>`
|
|
307
486
|
},
|
|
308
487
|
"navigation-menu": {
|
|
309
488
|
name: "NavigationMenu",
|
|
@@ -317,7 +496,18 @@ var COMPONENT_REGISTRY = {
|
|
|
317
496
|
"Multi-level navigation"
|
|
318
497
|
],
|
|
319
498
|
dependencies: ["@radix-ui/react-navigation-menu"],
|
|
320
|
-
radixPrimitive: "@radix-ui/react-navigation-menu"
|
|
499
|
+
radixPrimitive: "@radix-ui/react-navigation-menu",
|
|
500
|
+
subComponents: ["NavigationMenuList", "NavigationMenuItem", "NavigationMenuTrigger", "NavigationMenuContent", "NavigationMenuLink", "NavigationMenuIndicator", "NavigationMenuViewport"],
|
|
501
|
+
example: `<NavigationMenu>
|
|
502
|
+
<NavigationMenuList>
|
|
503
|
+
<NavigationMenuItem>
|
|
504
|
+
<NavigationMenuTrigger>Getting Started</NavigationMenuTrigger>
|
|
505
|
+
<NavigationMenuContent>
|
|
506
|
+
<NavigationMenuLink href="/docs">Documentation</NavigationMenuLink>
|
|
507
|
+
</NavigationMenuContent>
|
|
508
|
+
</NavigationMenuItem>
|
|
509
|
+
</NavigationMenuList>
|
|
510
|
+
</NavigationMenu>`
|
|
321
511
|
},
|
|
322
512
|
pagination: {
|
|
323
513
|
name: "Pagination",
|
|
@@ -330,7 +520,17 @@ var COMPONENT_REGISTRY = {
|
|
|
330
520
|
"Content lists",
|
|
331
521
|
"Multi-page forms"
|
|
332
522
|
],
|
|
333
|
-
dependencies: []
|
|
523
|
+
dependencies: [],
|
|
524
|
+
subComponents: ["PaginationContent", "PaginationItem", "PaginationLink", "PaginationPrevious", "PaginationNext", "PaginationEllipsis"],
|
|
525
|
+
example: `<Pagination>
|
|
526
|
+
<PaginationContent>
|
|
527
|
+
<PaginationItem><PaginationPrevious href="#" /></PaginationItem>
|
|
528
|
+
<PaginationItem><PaginationLink href="#">1</PaginationLink></PaginationItem>
|
|
529
|
+
<PaginationItem><PaginationLink href="#" isActive>2</PaginationLink></PaginationItem>
|
|
530
|
+
<PaginationItem><PaginationLink href="#">3</PaginationLink></PaginationItem>
|
|
531
|
+
<PaginationItem><PaginationNext href="#" /></PaginationItem>
|
|
532
|
+
</PaginationContent>
|
|
533
|
+
</Pagination>`
|
|
334
534
|
},
|
|
335
535
|
tabs: {
|
|
336
536
|
name: "Tabs",
|
|
@@ -344,7 +544,21 @@ var COMPONENT_REGISTRY = {
|
|
|
344
544
|
"Dashboard sections"
|
|
345
545
|
],
|
|
346
546
|
dependencies: ["@radix-ui/react-tabs"],
|
|
347
|
-
radixPrimitive: "@radix-ui/react-tabs"
|
|
547
|
+
radixPrimitive: "@radix-ui/react-tabs",
|
|
548
|
+
props: {
|
|
549
|
+
defaultValue: { type: "string", description: "Default active tab value" },
|
|
550
|
+
value: { type: "string", description: "Controlled active tab value" },
|
|
551
|
+
onValueChange: { type: "(value: string) => void", description: "Callback on tab change" }
|
|
552
|
+
},
|
|
553
|
+
subComponents: ["TabsList", "TabsTrigger", "TabsContent"],
|
|
554
|
+
example: `<Tabs defaultValue="account">
|
|
555
|
+
<TabsList>
|
|
556
|
+
<TabsTrigger value="account">Account</TabsTrigger>
|
|
557
|
+
<TabsTrigger value="password">Password</TabsTrigger>
|
|
558
|
+
</TabsList>
|
|
559
|
+
<TabsContent value="account">Account settings here.</TabsContent>
|
|
560
|
+
<TabsContent value="password">Password settings here.</TabsContent>
|
|
561
|
+
</Tabs>`
|
|
348
562
|
},
|
|
349
563
|
// ============================================================================
|
|
350
564
|
// OVERLAYS (9)
|
|
@@ -361,7 +575,25 @@ var COMPONENT_REGISTRY = {
|
|
|
361
575
|
"Irreversible operations"
|
|
362
576
|
],
|
|
363
577
|
dependencies: ["@radix-ui/react-alert-dialog"],
|
|
364
|
-
radixPrimitive: "@radix-ui/react-alert-dialog"
|
|
578
|
+
radixPrimitive: "@radix-ui/react-alert-dialog",
|
|
579
|
+
props: {
|
|
580
|
+
open: { type: "boolean", description: "Controlled open state" },
|
|
581
|
+
onOpenChange: { type: "(open: boolean) => void", description: "Callback on open/close" }
|
|
582
|
+
},
|
|
583
|
+
subComponents: ["AlertDialogTrigger", "AlertDialogContent", "AlertDialogHeader", "AlertDialogTitle", "AlertDialogDescription", "AlertDialogFooter", "AlertDialogAction", "AlertDialogCancel"],
|
|
584
|
+
example: `<AlertDialog>
|
|
585
|
+
<AlertDialogTrigger asChild><Button variant="destructive">Delete</Button></AlertDialogTrigger>
|
|
586
|
+
<AlertDialogContent>
|
|
587
|
+
<AlertDialogHeader>
|
|
588
|
+
<AlertDialogTitle>Are you sure?</AlertDialogTitle>
|
|
589
|
+
<AlertDialogDescription>This cannot be undone.</AlertDialogDescription>
|
|
590
|
+
</AlertDialogHeader>
|
|
591
|
+
<AlertDialogFooter>
|
|
592
|
+
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
|
593
|
+
<AlertDialogAction>Delete</AlertDialogAction>
|
|
594
|
+
</AlertDialogFooter>
|
|
595
|
+
</AlertDialogContent>
|
|
596
|
+
</AlertDialog>`
|
|
365
597
|
},
|
|
366
598
|
"context-menu": {
|
|
367
599
|
name: "ContextMenu",
|
|
@@ -375,7 +607,17 @@ var COMPONENT_REGISTRY = {
|
|
|
375
607
|
"Item actions"
|
|
376
608
|
],
|
|
377
609
|
dependencies: ["@radix-ui/react-context-menu"],
|
|
378
|
-
radixPrimitive: "@radix-ui/react-context-menu"
|
|
610
|
+
radixPrimitive: "@radix-ui/react-context-menu",
|
|
611
|
+
subComponents: ["ContextMenuTrigger", "ContextMenuContent", "ContextMenuItem", "ContextMenuCheckboxItem", "ContextMenuRadioItem", "ContextMenuLabel", "ContextMenuSeparator", "ContextMenuShortcut", "ContextMenuSub", "ContextMenuSubTrigger", "ContextMenuSubContent", "ContextMenuRadioGroup"],
|
|
612
|
+
example: `<ContextMenu>
|
|
613
|
+
<ContextMenuTrigger>Right click here</ContextMenuTrigger>
|
|
614
|
+
<ContextMenuContent>
|
|
615
|
+
<ContextMenuItem>Edit</ContextMenuItem>
|
|
616
|
+
<ContextMenuItem>Duplicate</ContextMenuItem>
|
|
617
|
+
<ContextMenuSeparator />
|
|
618
|
+
<ContextMenuItem>Delete</ContextMenuItem>
|
|
619
|
+
</ContextMenuContent>
|
|
620
|
+
</ContextMenu>`
|
|
379
621
|
},
|
|
380
622
|
dialog: {
|
|
381
623
|
name: "Dialog",
|
|
@@ -389,7 +631,25 @@ var COMPONENT_REGISTRY = {
|
|
|
389
631
|
"User input"
|
|
390
632
|
],
|
|
391
633
|
dependencies: ["@radix-ui/react-dialog"],
|
|
392
|
-
radixPrimitive: "@radix-ui/react-dialog"
|
|
634
|
+
radixPrimitive: "@radix-ui/react-dialog",
|
|
635
|
+
props: {
|
|
636
|
+
open: { type: "boolean", description: "Controlled open state" },
|
|
637
|
+
onOpenChange: { type: "(open: boolean) => void", description: "Callback on open/close" }
|
|
638
|
+
},
|
|
639
|
+
subComponents: ["DialogTrigger", "DialogContent", "DialogHeader", "DialogTitle", "DialogDescription", "DialogFooter", "DialogClose"],
|
|
640
|
+
example: `<Dialog>
|
|
641
|
+
<DialogTrigger asChild><Button>Open</Button></DialogTrigger>
|
|
642
|
+
<DialogContent>
|
|
643
|
+
<DialogHeader>
|
|
644
|
+
<DialogTitle>Title</DialogTitle>
|
|
645
|
+
<DialogDescription>Description here.</DialogDescription>
|
|
646
|
+
</DialogHeader>
|
|
647
|
+
<DialogFooter>
|
|
648
|
+
<Button variant="outline">Cancel</Button>
|
|
649
|
+
<Button>Confirm</Button>
|
|
650
|
+
</DialogFooter>
|
|
651
|
+
</DialogContent>
|
|
652
|
+
</Dialog>`
|
|
393
653
|
},
|
|
394
654
|
drawer: {
|
|
395
655
|
name: "Drawer",
|
|
@@ -402,7 +662,26 @@ var COMPONENT_REGISTRY = {
|
|
|
402
662
|
"Bottom sheets",
|
|
403
663
|
"Mobile menus"
|
|
404
664
|
],
|
|
405
|
-
dependencies: ["vaul"]
|
|
665
|
+
dependencies: ["vaul"],
|
|
666
|
+
props: {
|
|
667
|
+
open: { type: "boolean", description: "Controlled open state" },
|
|
668
|
+
onOpenChange: { type: "(open: boolean) => void", description: "Callback on open/close" }
|
|
669
|
+
},
|
|
670
|
+
subComponents: ["DrawerTrigger", "DrawerContent", "DrawerHeader", "DrawerTitle", "DrawerDescription", "DrawerFooter", "DrawerClose"],
|
|
671
|
+
example: `<Drawer>
|
|
672
|
+
<DrawerTrigger asChild><Button>Open Drawer</Button></DrawerTrigger>
|
|
673
|
+
<DrawerContent>
|
|
674
|
+
<DrawerHeader>
|
|
675
|
+
<DrawerTitle>Settings</DrawerTitle>
|
|
676
|
+
<DrawerDescription>Adjust preferences.</DrawerDescription>
|
|
677
|
+
</DrawerHeader>
|
|
678
|
+
<div className="p-4">Content here.</div>
|
|
679
|
+
<DrawerFooter>
|
|
680
|
+
<Button>Save</Button>
|
|
681
|
+
<DrawerClose asChild><Button variant="outline">Cancel</Button></DrawerClose>
|
|
682
|
+
</DrawerFooter>
|
|
683
|
+
</DrawerContent>
|
|
684
|
+
</Drawer>`
|
|
406
685
|
},
|
|
407
686
|
"dropdown-menu": {
|
|
408
687
|
name: "DropdownMenu",
|
|
@@ -416,7 +695,21 @@ var COMPONENT_REGISTRY = {
|
|
|
416
695
|
"Overflow menus"
|
|
417
696
|
],
|
|
418
697
|
dependencies: ["@radix-ui/react-dropdown-menu"],
|
|
419
|
-
radixPrimitive: "@radix-ui/react-dropdown-menu"
|
|
698
|
+
radixPrimitive: "@radix-ui/react-dropdown-menu",
|
|
699
|
+
props: {
|
|
700
|
+
open: { type: "boolean", description: "Controlled open state" },
|
|
701
|
+
onOpenChange: { type: "(open: boolean) => void", description: "Callback on open/close" }
|
|
702
|
+
},
|
|
703
|
+
subComponents: ["DropdownMenuTrigger", "DropdownMenuContent", "DropdownMenuItem", "DropdownMenuLabel", "DropdownMenuSeparator", "DropdownMenuCheckboxItem", "DropdownMenuRadioGroup", "DropdownMenuRadioItem", "DropdownMenuSub", "DropdownMenuSubTrigger", "DropdownMenuSubContent"],
|
|
704
|
+
example: `<DropdownMenu>
|
|
705
|
+
<DropdownMenuTrigger asChild><Button variant="ghost">Options</Button></DropdownMenuTrigger>
|
|
706
|
+
<DropdownMenuContent>
|
|
707
|
+
<DropdownMenuLabel>Actions</DropdownMenuLabel>
|
|
708
|
+
<DropdownMenuSeparator />
|
|
709
|
+
<DropdownMenuItem>Edit</DropdownMenuItem>
|
|
710
|
+
<DropdownMenuItem>Delete</DropdownMenuItem>
|
|
711
|
+
</DropdownMenuContent>
|
|
712
|
+
</DropdownMenu>`
|
|
420
713
|
},
|
|
421
714
|
"hover-card": {
|
|
422
715
|
name: "HoverCard",
|
|
@@ -430,7 +723,21 @@ var COMPONENT_REGISTRY = {
|
|
|
430
723
|
"Additional context"
|
|
431
724
|
],
|
|
432
725
|
dependencies: ["@radix-ui/react-hover-card"],
|
|
433
|
-
radixPrimitive: "@radix-ui/react-hover-card"
|
|
726
|
+
radixPrimitive: "@radix-ui/react-hover-card",
|
|
727
|
+
props: {
|
|
728
|
+
openDelay: { type: "number", default: "700", description: "Delay in ms before opening" },
|
|
729
|
+
closeDelay: { type: "number", default: "300", description: "Delay in ms before closing" }
|
|
730
|
+
},
|
|
731
|
+
subComponents: ["HoverCardTrigger", "HoverCardContent"],
|
|
732
|
+
example: `<HoverCard>
|
|
733
|
+
<HoverCardTrigger asChild><Link href="#">@username</Link></HoverCardTrigger>
|
|
734
|
+
<HoverCardContent className="w-80">
|
|
735
|
+
<div className="flex gap-4">
|
|
736
|
+
<Avatar />
|
|
737
|
+
<div><p className="text-sm font-semibold">Username</p><p className="text-sm text-muted-foreground">Bio here.</p></div>
|
|
738
|
+
</div>
|
|
739
|
+
</HoverCardContent>
|
|
740
|
+
</HoverCard>`
|
|
434
741
|
},
|
|
435
742
|
popover: {
|
|
436
743
|
name: "Popover",
|
|
@@ -444,7 +751,16 @@ var COMPONENT_REGISTRY = {
|
|
|
444
751
|
"Inline editors"
|
|
445
752
|
],
|
|
446
753
|
dependencies: ["@radix-ui/react-popover"],
|
|
447
|
-
radixPrimitive: "@radix-ui/react-popover"
|
|
754
|
+
radixPrimitive: "@radix-ui/react-popover",
|
|
755
|
+
props: {
|
|
756
|
+
open: { type: "boolean", description: "Controlled open state" },
|
|
757
|
+
onOpenChange: { type: "(open: boolean) => void", description: "Callback on open/close" }
|
|
758
|
+
},
|
|
759
|
+
subComponents: ["PopoverTrigger", "PopoverContent", "PopoverAnchor"],
|
|
760
|
+
example: `<Popover>
|
|
761
|
+
<PopoverTrigger asChild><Button variant="outline">Open</Button></PopoverTrigger>
|
|
762
|
+
<PopoverContent className="w-80">Content here.</PopoverContent>
|
|
763
|
+
</Popover>`
|
|
448
764
|
},
|
|
449
765
|
sheet: {
|
|
450
766
|
name: "Sheet",
|
|
@@ -458,7 +774,19 @@ var COMPONENT_REGISTRY = {
|
|
|
458
774
|
"Detail views"
|
|
459
775
|
],
|
|
460
776
|
dependencies: ["@radix-ui/react-dialog"],
|
|
461
|
-
radixPrimitive: "@radix-ui/react-dialog"
|
|
777
|
+
radixPrimitive: "@radix-ui/react-dialog",
|
|
778
|
+
props: {
|
|
779
|
+
open: { type: "boolean", description: "Controlled open state" },
|
|
780
|
+
onOpenChange: { type: "(open: boolean) => void", description: "Callback on open/close" }
|
|
781
|
+
},
|
|
782
|
+
subComponents: ["SheetTrigger", "SheetContent", "SheetHeader", "SheetTitle", "SheetDescription", "SheetClose"],
|
|
783
|
+
example: `<Sheet>
|
|
784
|
+
<SheetTrigger asChild><Button>Open</Button></SheetTrigger>
|
|
785
|
+
<SheetContent side="right">
|
|
786
|
+
<SheetHeader><SheetTitle>Settings</SheetTitle></SheetHeader>
|
|
787
|
+
<div className="p-4">Content here.</div>
|
|
788
|
+
</SheetContent>
|
|
789
|
+
</Sheet>`
|
|
462
790
|
},
|
|
463
791
|
tooltip: {
|
|
464
792
|
name: "Tooltip",
|
|
@@ -472,7 +800,12 @@ var COMPONENT_REGISTRY = {
|
|
|
472
800
|
"Keyboard shortcuts"
|
|
473
801
|
],
|
|
474
802
|
dependencies: ["@radix-ui/react-tooltip"],
|
|
475
|
-
radixPrimitive: "@radix-ui/react-tooltip"
|
|
803
|
+
radixPrimitive: "@radix-ui/react-tooltip",
|
|
804
|
+
subComponents: ["TooltipTrigger", "TooltipContent", "TooltipProvider"],
|
|
805
|
+
example: `<Tooltip>
|
|
806
|
+
<TooltipTrigger asChild><Button variant="ghost" size="icon"><Info /></Button></TooltipTrigger>
|
|
807
|
+
<TooltipContent><p>Helpful information</p></TooltipContent>
|
|
808
|
+
</Tooltip>`
|
|
476
809
|
},
|
|
477
810
|
// ============================================================================
|
|
478
811
|
// FEEDBACK (5)
|
|
@@ -488,7 +821,15 @@ var COMPONENT_REGISTRY = {
|
|
|
488
821
|
"Errors",
|
|
489
822
|
"Success confirmations"
|
|
490
823
|
],
|
|
491
|
-
dependencies: []
|
|
824
|
+
dependencies: [],
|
|
825
|
+
props: {
|
|
826
|
+
variant: { type: "'default' | 'destructive'", default: "'default'", description: "Visual variant" }
|
|
827
|
+
},
|
|
828
|
+
subComponents: ["AlertTitle", "AlertDescription"],
|
|
829
|
+
example: `<Alert variant="destructive">
|
|
830
|
+
<AlertTitle>Error</AlertTitle>
|
|
831
|
+
<AlertDescription>Your session has expired.</AlertDescription>
|
|
832
|
+
</Alert>`
|
|
492
833
|
},
|
|
493
834
|
progress: {
|
|
494
835
|
name: "Progress",
|
|
@@ -502,7 +843,12 @@ var COMPONENT_REGISTRY = {
|
|
|
502
843
|
"Multi-step forms"
|
|
503
844
|
],
|
|
504
845
|
dependencies: ["@radix-ui/react-progress"],
|
|
505
|
-
radixPrimitive: "@radix-ui/react-progress"
|
|
846
|
+
radixPrimitive: "@radix-ui/react-progress",
|
|
847
|
+
props: {
|
|
848
|
+
value: { type: "number", default: "0", description: "Progress value (0-100)" },
|
|
849
|
+
max: { type: "number", default: "100", description: "Maximum value" }
|
|
850
|
+
},
|
|
851
|
+
example: `<Progress value={60} />`
|
|
506
852
|
},
|
|
507
853
|
skeleton: {
|
|
508
854
|
name: "Skeleton",
|
|
@@ -515,12 +861,22 @@ var COMPONENT_REGISTRY = {
|
|
|
515
861
|
"Initial load",
|
|
516
862
|
"Lazy loading"
|
|
517
863
|
],
|
|
518
|
-
dependencies: []
|
|
864
|
+
dependencies: [],
|
|
865
|
+
props: {
|
|
866
|
+
variant: { type: "'default' | 'circular' | 'rectangular' | 'text'", default: "'default'", description: "Shape variant" },
|
|
867
|
+
width: { type: "string", default: "'100%'", description: "Width (CSS value)" },
|
|
868
|
+
height: { type: "string", default: "'20px'", description: "Height (CSS value)" }
|
|
869
|
+
},
|
|
870
|
+
example: `<div className="space-y-2">
|
|
871
|
+
<Skeleton className="h-12 w-12 rounded-full" />
|
|
872
|
+
<Skeleton className="h-4 w-[250px]" />
|
|
873
|
+
<Skeleton className="h-4 w-[200px]" />
|
|
874
|
+
</div>`
|
|
519
875
|
},
|
|
520
876
|
sonner: {
|
|
521
877
|
name: "Sonner",
|
|
522
878
|
category: "feedback",
|
|
523
|
-
description: "Toast notification system with queuing and positioning",
|
|
879
|
+
description: "Toast notification system with queuing and positioning. Use Toaster component in layout, call toast() to trigger.",
|
|
524
880
|
keywords: ["toast", "notification", "sonner", "message", "alert"],
|
|
525
881
|
useCases: [
|
|
526
882
|
"Success messages",
|
|
@@ -528,7 +884,14 @@ var COMPONENT_REGISTRY = {
|
|
|
528
884
|
"Action feedback",
|
|
529
885
|
"System messages"
|
|
530
886
|
],
|
|
531
|
-
dependencies: ["sonner"]
|
|
887
|
+
dependencies: ["sonner"],
|
|
888
|
+
subComponents: ["Toaster"],
|
|
889
|
+
example: `// In layout: <Toaster />
|
|
890
|
+
// To trigger:
|
|
891
|
+
import { toast } from 'sonner'
|
|
892
|
+
toast.success('Saved successfully')
|
|
893
|
+
toast.error('Something went wrong')
|
|
894
|
+
toast('Default notification')`
|
|
532
895
|
},
|
|
533
896
|
toast: {
|
|
534
897
|
name: "Toast",
|
|
@@ -542,7 +905,13 @@ var COMPONENT_REGISTRY = {
|
|
|
542
905
|
"Confirmation messages"
|
|
543
906
|
],
|
|
544
907
|
dependencies: ["@radix-ui/react-toast"],
|
|
545
|
-
radixPrimitive: "@radix-ui/react-toast"
|
|
908
|
+
radixPrimitive: "@radix-ui/react-toast",
|
|
909
|
+
subComponents: ["ToastAction", "ToastClose", "ToastDescription", "ToastProvider", "ToastTitle", "ToastViewport"],
|
|
910
|
+
example: `// Prefer using Sonner (Toaster + toast()) for new projects.
|
|
911
|
+
// This is the Radix-based alternative.
|
|
912
|
+
import { useToast } from '@thesage/ui'
|
|
913
|
+
const { toast } = useToast()
|
|
914
|
+
toast({ title: 'Success', description: 'Item saved.' })`
|
|
546
915
|
},
|
|
547
916
|
// ============================================================================
|
|
548
917
|
// DATA DISPLAY (6)
|
|
@@ -559,7 +928,12 @@ var COMPONENT_REGISTRY = {
|
|
|
559
928
|
"Chat participants"
|
|
560
929
|
],
|
|
561
930
|
dependencies: ["@radix-ui/react-avatar"],
|
|
562
|
-
radixPrimitive: "@radix-ui/react-avatar"
|
|
931
|
+
radixPrimitive: "@radix-ui/react-avatar",
|
|
932
|
+
subComponents: ["AvatarImage", "AvatarFallback"],
|
|
933
|
+
example: `<Avatar>
|
|
934
|
+
<AvatarImage src="/avatar.jpg" alt="User" />
|
|
935
|
+
<AvatarFallback>JD</AvatarFallback>
|
|
936
|
+
</Avatar>`
|
|
563
937
|
},
|
|
564
938
|
badge: {
|
|
565
939
|
name: "Badge",
|
|
@@ -572,7 +946,13 @@ var COMPONENT_REGISTRY = {
|
|
|
572
946
|
"Categories",
|
|
573
947
|
"Notification counts"
|
|
574
948
|
],
|
|
575
|
-
dependencies: []
|
|
949
|
+
dependencies: [],
|
|
950
|
+
props: {
|
|
951
|
+
variant: { type: "'default' | 'secondary' | 'destructive' | 'outline' | 'success' | 'warning' | 'error' | 'info'", default: "'default'", description: "Visual variant" },
|
|
952
|
+
size: { type: "'sm' | 'md' | 'lg'", default: "'md'", description: "Size variant" },
|
|
953
|
+
dot: { type: "boolean", default: "false", description: "Show animated indicator dot" }
|
|
954
|
+
},
|
|
955
|
+
example: `<Badge variant="success" dot>Active</Badge>`
|
|
576
956
|
},
|
|
577
957
|
calendar: {
|
|
578
958
|
name: "Calendar",
|
|
@@ -585,7 +965,15 @@ var COMPONENT_REGISTRY = {
|
|
|
585
965
|
"Booking systems",
|
|
586
966
|
"Date ranges"
|
|
587
967
|
],
|
|
588
|
-
dependencies: ["react-day-picker", "date-fns"]
|
|
968
|
+
dependencies: ["react-day-picker", "date-fns"],
|
|
969
|
+
props: {
|
|
970
|
+
mode: { type: "'single' | 'multiple' | 'range'", default: "'single'", description: "Selection mode" },
|
|
971
|
+
selected: { type: "Date | Date[] | DateRange", description: "Selected date(s)" },
|
|
972
|
+
onSelect: { type: "(date) => void", description: "Callback on date selection" },
|
|
973
|
+
showOutsideDays: { type: "boolean", default: "true", description: "Show days from adjacent months" },
|
|
974
|
+
disabled: { type: "Matcher | Matcher[]", description: "Dates to disable" }
|
|
975
|
+
},
|
|
976
|
+
example: `<Calendar mode="single" selected={date} onSelect={setDate} />`
|
|
589
977
|
},
|
|
590
978
|
card: {
|
|
591
979
|
name: "Card",
|
|
@@ -598,7 +986,20 @@ var COMPONENT_REGISTRY = {
|
|
|
598
986
|
"Information panels",
|
|
599
987
|
"Dashboard widgets"
|
|
600
988
|
],
|
|
601
|
-
dependencies: []
|
|
989
|
+
dependencies: [],
|
|
990
|
+
props: {
|
|
991
|
+
variant: { type: "'default' | 'glass' | 'outline'", default: "'default'", description: "Visual variant" },
|
|
992
|
+
hoverEffect: { type: "boolean", default: "false", description: "Enable hover lift and shadow" }
|
|
993
|
+
},
|
|
994
|
+
subComponents: ["CardHeader", "CardTitle", "CardDescription", "CardContent", "CardFooter"],
|
|
995
|
+
example: `<Card>
|
|
996
|
+
<CardHeader>
|
|
997
|
+
<CardTitle>Notifications</CardTitle>
|
|
998
|
+
<CardDescription>You have 3 unread messages.</CardDescription>
|
|
999
|
+
</CardHeader>
|
|
1000
|
+
<CardContent><p>Content here.</p></CardContent>
|
|
1001
|
+
<CardFooter><Button>View All</Button></CardFooter>
|
|
1002
|
+
</Card>`
|
|
602
1003
|
},
|
|
603
1004
|
"data-table": {
|
|
604
1005
|
name: "DataTable",
|
|
@@ -611,7 +1012,17 @@ var COMPONENT_REGISTRY = {
|
|
|
611
1012
|
"Reports",
|
|
612
1013
|
"List management"
|
|
613
1014
|
],
|
|
614
|
-
dependencies: ["@tanstack/react-table"]
|
|
1015
|
+
dependencies: ["@tanstack/react-table"],
|
|
1016
|
+
props: {
|
|
1017
|
+
columns: { type: "ColumnDef<TData, TValue>[]", description: "Column definitions from @tanstack/react-table", required: true },
|
|
1018
|
+
data: { type: "TData[]", description: "Array of row data", required: true }
|
|
1019
|
+
},
|
|
1020
|
+
example: `import { DataTable } from '@thesage/ui/tables'
|
|
1021
|
+
const columns = [
|
|
1022
|
+
{ accessorKey: 'name', header: 'Name' },
|
|
1023
|
+
{ accessorKey: 'email', header: 'Email' },
|
|
1024
|
+
]
|
|
1025
|
+
<DataTable columns={columns} data={users} />`
|
|
615
1026
|
},
|
|
616
1027
|
table: {
|
|
617
1028
|
name: "Table",
|
|
@@ -624,7 +1035,22 @@ var COMPONENT_REGISTRY = {
|
|
|
624
1035
|
"Comparison tables",
|
|
625
1036
|
"Pricing tables"
|
|
626
1037
|
],
|
|
627
|
-
dependencies: []
|
|
1038
|
+
dependencies: [],
|
|
1039
|
+
subComponents: ["TableHeader", "TableBody", "TableFooter", "TableRow", "TableHead", "TableCell", "TableCaption"],
|
|
1040
|
+
example: `<Table>
|
|
1041
|
+
<TableHeader>
|
|
1042
|
+
<TableRow>
|
|
1043
|
+
<TableHead>Name</TableHead>
|
|
1044
|
+
<TableHead>Status</TableHead>
|
|
1045
|
+
</TableRow>
|
|
1046
|
+
</TableHeader>
|
|
1047
|
+
<TableBody>
|
|
1048
|
+
<TableRow>
|
|
1049
|
+
<TableCell>John</TableCell>
|
|
1050
|
+
<TableCell>Active</TableCell>
|
|
1051
|
+
</TableRow>
|
|
1052
|
+
</TableBody>
|
|
1053
|
+
</Table>`
|
|
628
1054
|
},
|
|
629
1055
|
heading: {
|
|
630
1056
|
name: "Heading",
|
|
@@ -637,7 +1063,13 @@ var COMPONENT_REGISTRY = {
|
|
|
637
1063
|
"Content hierarchy",
|
|
638
1064
|
"Semantic HTML structure"
|
|
639
1065
|
],
|
|
640
|
-
dependencies: []
|
|
1066
|
+
dependencies: [],
|
|
1067
|
+
props: {
|
|
1068
|
+
level: { type: "1 | 2 | 3 | 4 | 5 | 6", default: "2", description: "Heading level (renders h1-h6)" },
|
|
1069
|
+
as: { type: "'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'", description: "Override rendered HTML element" }
|
|
1070
|
+
},
|
|
1071
|
+
example: `<Heading level={1}>Page Title</Heading>
|
|
1072
|
+
<Heading level={2}>Section Title</Heading>`
|
|
641
1073
|
},
|
|
642
1074
|
text: {
|
|
643
1075
|
name: "Text",
|
|
@@ -650,7 +1082,14 @@ var COMPONENT_REGISTRY = {
|
|
|
650
1082
|
"Helper text",
|
|
651
1083
|
"Labels and captions"
|
|
652
1084
|
],
|
|
653
|
-
dependencies: []
|
|
1085
|
+
dependencies: [],
|
|
1086
|
+
props: {
|
|
1087
|
+
variant: { type: "'default' | 'secondary' | 'muted' | 'lead'", default: "'default'", description: "Text style variant" },
|
|
1088
|
+
as: { type: "'p' | 'span' | 'div'", default: "'p'", description: "HTML element to render" },
|
|
1089
|
+
size: { type: "'sm' | 'base' | 'lg'", default: "'base'", description: "Font size" }
|
|
1090
|
+
},
|
|
1091
|
+
example: `<Text variant="lead">Important introductory text.</Text>
|
|
1092
|
+
<Text variant="muted" size="sm">Helper text below an input.</Text>`
|
|
654
1093
|
},
|
|
655
1094
|
code: {
|
|
656
1095
|
name: "Code",
|
|
@@ -663,7 +1102,17 @@ var COMPONENT_REGISTRY = {
|
|
|
663
1102
|
"Technical content",
|
|
664
1103
|
"Inline code references"
|
|
665
1104
|
],
|
|
666
|
-
dependencies: []
|
|
1105
|
+
dependencies: [],
|
|
1106
|
+
props: {
|
|
1107
|
+
inline: { type: "boolean", default: "false", description: "Render as inline code (true) or block (false)" },
|
|
1108
|
+
showCopy: { type: "boolean", default: "true", description: "Show copy button for block code" }
|
|
1109
|
+
},
|
|
1110
|
+
example: `// Inline
|
|
1111
|
+
<Code inline>npm install @thesage/ui</Code>
|
|
1112
|
+
|
|
1113
|
+
// Block
|
|
1114
|
+
<Code>{\`const x = 1;
|
|
1115
|
+
const y = 2;\`}</Code>`
|
|
667
1116
|
},
|
|
668
1117
|
"collapsible-code-block": {
|
|
669
1118
|
name: "CollapsibleCodeBlock",
|
|
@@ -676,7 +1125,20 @@ var COMPONENT_REGISTRY = {
|
|
|
676
1125
|
"Tutorial code snippets",
|
|
677
1126
|
"API examples"
|
|
678
1127
|
],
|
|
679
|
-
dependencies: ["@thesage/tokens"]
|
|
1128
|
+
dependencies: ["@thesage/tokens"],
|
|
1129
|
+
props: {
|
|
1130
|
+
code: { type: "string", description: "Source code string", required: true },
|
|
1131
|
+
language: { type: "'tsx' | 'typescript' | 'javascript' | 'jsx' | 'css' | 'html' | 'json' | 'bash'", default: "'tsx'", description: "Language for syntax highlighting" },
|
|
1132
|
+
title: { type: "string", description: "Optional title above the code block" },
|
|
1133
|
+
maxLines: { type: "number", default: "10", description: "Lines to show before collapsing" },
|
|
1134
|
+
defaultExpanded: { type: "boolean", default: "false", description: "Start in expanded state" }
|
|
1135
|
+
},
|
|
1136
|
+
example: `<CollapsibleCodeBlock
|
|
1137
|
+
code="const Button = () => <button>Click</button>"
|
|
1138
|
+
language="tsx"
|
|
1139
|
+
title="Button.tsx"
|
|
1140
|
+
maxLines={5}
|
|
1141
|
+
/>`
|
|
680
1142
|
},
|
|
681
1143
|
"description-list": {
|
|
682
1144
|
name: "DescriptionList",
|
|
@@ -689,7 +1151,16 @@ var COMPONENT_REGISTRY = {
|
|
|
689
1151
|
"Metadata display",
|
|
690
1152
|
"Settings summaries"
|
|
691
1153
|
],
|
|
692
|
-
dependencies: []
|
|
1154
|
+
dependencies: [],
|
|
1155
|
+
props: {
|
|
1156
|
+
items: { type: "{ label: string; value: ReactNode }[]", description: "Array of label-value pairs", required: true },
|
|
1157
|
+
layout: { type: "'row' | 'column'", default: "'row'", description: "Layout direction for label/value pairs" }
|
|
1158
|
+
},
|
|
1159
|
+
example: `<DescriptionList items={[
|
|
1160
|
+
{ label: 'Name', value: 'John Doe' },
|
|
1161
|
+
{ label: 'Email', value: 'john@example.com' },
|
|
1162
|
+
{ label: 'Role', value: <Badge>Admin</Badge> },
|
|
1163
|
+
]} />`
|
|
693
1164
|
},
|
|
694
1165
|
// ============================================================================
|
|
695
1166
|
// LAYOUT (8)
|
|
@@ -706,7 +1177,18 @@ var COMPONENT_REGISTRY = {
|
|
|
706
1177
|
"Information disclosure"
|
|
707
1178
|
],
|
|
708
1179
|
dependencies: ["@radix-ui/react-accordion"],
|
|
709
|
-
radixPrimitive: "@radix-ui/react-accordion"
|
|
1180
|
+
radixPrimitive: "@radix-ui/react-accordion",
|
|
1181
|
+
props: {
|
|
1182
|
+
type: { type: "'single' | 'multiple'", description: "Allow single or multiple open items", required: true },
|
|
1183
|
+
collapsible: { type: "boolean", default: "false", description: 'Allow closing all items (type="single" only)' }
|
|
1184
|
+
},
|
|
1185
|
+
subComponents: ["AccordionItem", "AccordionTrigger", "AccordionContent"],
|
|
1186
|
+
example: `<Accordion type="single" collapsible>
|
|
1187
|
+
<AccordionItem value="item-1">
|
|
1188
|
+
<AccordionTrigger>Is it accessible?</AccordionTrigger>
|
|
1189
|
+
<AccordionContent>Yes. It follows WAI-ARIA patterns.</AccordionContent>
|
|
1190
|
+
</AccordionItem>
|
|
1191
|
+
</Accordion>`
|
|
710
1192
|
},
|
|
711
1193
|
"aspect-ratio": {
|
|
712
1194
|
name: "AspectRatio",
|
|
@@ -720,7 +1202,13 @@ var COMPONENT_REGISTRY = {
|
|
|
720
1202
|
"Card images"
|
|
721
1203
|
],
|
|
722
1204
|
dependencies: ["@radix-ui/react-aspect-ratio"],
|
|
723
|
-
radixPrimitive: "@radix-ui/react-aspect-ratio"
|
|
1205
|
+
radixPrimitive: "@radix-ui/react-aspect-ratio",
|
|
1206
|
+
props: {
|
|
1207
|
+
ratio: { type: "number", default: "1", description: "Aspect ratio as a number (e.g. 16/9)" }
|
|
1208
|
+
},
|
|
1209
|
+
example: `<AspectRatio ratio={16 / 9}>
|
|
1210
|
+
<img src="/image.jpg" alt="Photo" className="rounded-md object-cover w-full h-full" />
|
|
1211
|
+
</AspectRatio>`
|
|
724
1212
|
},
|
|
725
1213
|
carousel: {
|
|
726
1214
|
name: "Carousel",
|
|
@@ -733,7 +1221,23 @@ var COMPONENT_REGISTRY = {
|
|
|
733
1221
|
"Content sliders",
|
|
734
1222
|
"Testimonials"
|
|
735
1223
|
],
|
|
736
|
-
dependencies: ["embla-carousel-react"]
|
|
1224
|
+
dependencies: ["embla-carousel-react"],
|
|
1225
|
+
props: {
|
|
1226
|
+
orientation: { type: "'horizontal' | 'vertical'", default: "'horizontal'", description: "Scroll direction" },
|
|
1227
|
+
opts: { type: "CarouselOptions", description: "Embla Carousel options (loop, align, etc.)" },
|
|
1228
|
+
plugins: { type: "CarouselPlugin", description: "Embla Carousel plugins (autoplay, etc.)" },
|
|
1229
|
+
setApi: { type: "(api: CarouselApi) => void", description: "Callback to get carousel API ref" }
|
|
1230
|
+
},
|
|
1231
|
+
subComponents: ["CarouselContent", "CarouselItem", "CarouselPrevious", "CarouselNext"],
|
|
1232
|
+
example: `<Carousel>
|
|
1233
|
+
<CarouselContent>
|
|
1234
|
+
<CarouselItem>Slide 1</CarouselItem>
|
|
1235
|
+
<CarouselItem>Slide 2</CarouselItem>
|
|
1236
|
+
<CarouselItem>Slide 3</CarouselItem>
|
|
1237
|
+
</CarouselContent>
|
|
1238
|
+
<CarouselPrevious />
|
|
1239
|
+
<CarouselNext />
|
|
1240
|
+
</Carousel>`
|
|
737
1241
|
},
|
|
738
1242
|
collapsible: {
|
|
739
1243
|
name: "Collapsible",
|
|
@@ -747,7 +1251,19 @@ var COMPONENT_REGISTRY = {
|
|
|
747
1251
|
"Details disclosure"
|
|
748
1252
|
],
|
|
749
1253
|
dependencies: ["@radix-ui/react-collapsible"],
|
|
750
|
-
radixPrimitive: "@radix-ui/react-collapsible"
|
|
1254
|
+
radixPrimitive: "@radix-ui/react-collapsible",
|
|
1255
|
+
props: {
|
|
1256
|
+
open: { type: "boolean", description: "Controlled open state" },
|
|
1257
|
+
onOpenChange: { type: "(open: boolean) => void", description: "Callback on open/close" },
|
|
1258
|
+
defaultOpen: { type: "boolean", default: "false", description: "Default open state" }
|
|
1259
|
+
},
|
|
1260
|
+
subComponents: ["CollapsibleTrigger", "CollapsibleContent"],
|
|
1261
|
+
example: `<Collapsible>
|
|
1262
|
+
<CollapsibleTrigger asChild><Button variant="ghost">Toggle</Button></CollapsibleTrigger>
|
|
1263
|
+
<CollapsibleContent>
|
|
1264
|
+
<p>Hidden content revealed on click.</p>
|
|
1265
|
+
</CollapsibleContent>
|
|
1266
|
+
</Collapsible>`
|
|
751
1267
|
},
|
|
752
1268
|
"date-picker": {
|
|
753
1269
|
name: "DatePicker",
|
|
@@ -760,7 +1276,14 @@ var COMPONENT_REGISTRY = {
|
|
|
760
1276
|
"Scheduling",
|
|
761
1277
|
"Filters"
|
|
762
1278
|
],
|
|
763
|
-
dependencies: ["react-day-picker", "date-fns", "@radix-ui/react-popover"]
|
|
1279
|
+
dependencies: ["react-day-picker", "date-fns", "@radix-ui/react-popover"],
|
|
1280
|
+
props: {
|
|
1281
|
+
date: { type: "Date", description: "Selected date" },
|
|
1282
|
+
onDateChange: { type: "(date: Date | undefined) => void", description: "Callback on date change" },
|
|
1283
|
+
placeholder: { type: "string", default: "'Pick a date'", description: "Placeholder text" },
|
|
1284
|
+
disabled: { type: "boolean", default: "false", description: "Disable the date picker" }
|
|
1285
|
+
},
|
|
1286
|
+
example: `<DatePicker date={date} onDateChange={setDate} placeholder="Select date" />`
|
|
764
1287
|
},
|
|
765
1288
|
resizable: {
|
|
766
1289
|
name: "Resizable",
|
|
@@ -773,7 +1296,16 @@ var COMPONENT_REGISTRY = {
|
|
|
773
1296
|
"Dashboard layouts",
|
|
774
1297
|
"Adjustable sidebars"
|
|
775
1298
|
],
|
|
776
|
-
dependencies: ["react-resizable-panels"]
|
|
1299
|
+
dependencies: ["react-resizable-panels"],
|
|
1300
|
+
props: {
|
|
1301
|
+
direction: { type: "'horizontal' | 'vertical'", default: "'horizontal'", description: "Panel layout direction" }
|
|
1302
|
+
},
|
|
1303
|
+
subComponents: ["ResizablePanelGroup", "ResizablePanel", "ResizableHandle"],
|
|
1304
|
+
example: `<ResizablePanelGroup direction="horizontal">
|
|
1305
|
+
<ResizablePanel defaultSize={50}>Left panel</ResizablePanel>
|
|
1306
|
+
<ResizableHandle />
|
|
1307
|
+
<ResizablePanel defaultSize={50}>Right panel</ResizablePanel>
|
|
1308
|
+
</ResizablePanelGroup>`
|
|
777
1309
|
},
|
|
778
1310
|
"scroll-area": {
|
|
779
1311
|
name: "ScrollArea",
|
|
@@ -787,7 +1319,11 @@ var COMPONENT_REGISTRY = {
|
|
|
787
1319
|
"Code displays"
|
|
788
1320
|
],
|
|
789
1321
|
dependencies: ["@radix-ui/react-scroll-area"],
|
|
790
|
-
radixPrimitive: "@radix-ui/react-scroll-area"
|
|
1322
|
+
radixPrimitive: "@radix-ui/react-scroll-area",
|
|
1323
|
+
subComponents: ["ScrollBar"],
|
|
1324
|
+
example: `<ScrollArea className="h-[200px] w-full rounded-md border p-4">
|
|
1325
|
+
<div>Long scrollable content here...</div>
|
|
1326
|
+
</ScrollArea>`
|
|
791
1327
|
},
|
|
792
1328
|
separator: {
|
|
793
1329
|
name: "Separator",
|
|
@@ -801,7 +1337,11 @@ var COMPONENT_REGISTRY = {
|
|
|
801
1337
|
"Visual hierarchy"
|
|
802
1338
|
],
|
|
803
1339
|
dependencies: ["@radix-ui/react-separator"],
|
|
804
|
-
radixPrimitive: "@radix-ui/react-separator"
|
|
1340
|
+
radixPrimitive: "@radix-ui/react-separator",
|
|
1341
|
+
props: {
|
|
1342
|
+
orientation: { type: "'horizontal' | 'vertical'", default: "'horizontal'", description: "Orientation" }
|
|
1343
|
+
},
|
|
1344
|
+
example: `<Separator orientation="horizontal" />`
|
|
805
1345
|
},
|
|
806
1346
|
grid: {
|
|
807
1347
|
name: "Grid",
|
|
@@ -814,7 +1354,16 @@ var COMPONENT_REGISTRY = {
|
|
|
814
1354
|
"Dashboard layouts",
|
|
815
1355
|
"Responsive content grids"
|
|
816
1356
|
],
|
|
817
|
-
dependencies: []
|
|
1357
|
+
dependencies: [],
|
|
1358
|
+
props: {
|
|
1359
|
+
columns: { type: "number | { sm?: number; md?: number; lg?: number }", default: "3", description: "Number of grid columns (responsive object supported)" },
|
|
1360
|
+
gap: { type: "number | string", default: "4", description: "Gap between grid items (Tailwind spacing scale)" }
|
|
1361
|
+
},
|
|
1362
|
+
example: `<Grid columns={{ sm: 1, md: 2, lg: 3 }} gap={4}>
|
|
1363
|
+
<Card>Item 1</Card>
|
|
1364
|
+
<Card>Item 2</Card>
|
|
1365
|
+
<Card>Item 3</Card>
|
|
1366
|
+
</Grid>`
|
|
818
1367
|
},
|
|
819
1368
|
container: {
|
|
820
1369
|
name: "Container",
|
|
@@ -827,7 +1376,15 @@ var COMPONENT_REGISTRY = {
|
|
|
827
1376
|
"Responsive widths",
|
|
828
1377
|
"Content alignment"
|
|
829
1378
|
],
|
|
830
|
-
dependencies: []
|
|
1379
|
+
dependencies: [],
|
|
1380
|
+
props: {
|
|
1381
|
+
size: { type: "'sm' | 'md' | 'lg' | 'xl' | 'full'", default: "'lg'", description: "Max-width variant" },
|
|
1382
|
+
padding: { type: "boolean", default: "true", description: "Apply horizontal padding" }
|
|
1383
|
+
},
|
|
1384
|
+
example: `<Container size="lg">
|
|
1385
|
+
<Heading level={1}>Page Title</Heading>
|
|
1386
|
+
<Text>Content within max-width container.</Text>
|
|
1387
|
+
</Container>`
|
|
831
1388
|
},
|
|
832
1389
|
stack: {
|
|
833
1390
|
name: "Stack",
|
|
@@ -840,7 +1397,17 @@ var COMPONENT_REGISTRY = {
|
|
|
840
1397
|
"Form layouts",
|
|
841
1398
|
"Button groups"
|
|
842
1399
|
],
|
|
843
|
-
dependencies: []
|
|
1400
|
+
dependencies: [],
|
|
1401
|
+
props: {
|
|
1402
|
+
direction: { type: "'vertical' | 'horizontal'", default: "'vertical'", description: "Stack direction" },
|
|
1403
|
+
gap: { type: "number | string", default: "4", description: "Gap between items (Tailwind spacing scale)" },
|
|
1404
|
+
align: { type: "'start' | 'center' | 'end' | 'stretch'", default: "'stretch'", description: "Cross-axis alignment" },
|
|
1405
|
+
justify: { type: "'start' | 'center' | 'end' | 'between'", description: "Main-axis alignment" }
|
|
1406
|
+
},
|
|
1407
|
+
example: `<Stack direction="horizontal" gap={2} align="center">
|
|
1408
|
+
<Button>Save</Button>
|
|
1409
|
+
<Button variant="outline">Cancel</Button>
|
|
1410
|
+
</Stack>`
|
|
844
1411
|
},
|
|
845
1412
|
sidebar: {
|
|
846
1413
|
name: "Sidebar",
|
|
@@ -854,7 +1421,21 @@ var COMPONENT_REGISTRY = {
|
|
|
854
1421
|
"Mobile menus"
|
|
855
1422
|
],
|
|
856
1423
|
dependencies: ["@radix-ui/react-slot"],
|
|
857
|
-
radixPrimitive: "@radix-ui/react-slot"
|
|
1424
|
+
radixPrimitive: "@radix-ui/react-slot",
|
|
1425
|
+
props: {
|
|
1426
|
+
isOpen: { type: "boolean", default: "true", description: "Whether sidebar is visible/expanded" }
|
|
1427
|
+
},
|
|
1428
|
+
subComponents: ["SidebarHeader", "SidebarContent", "SidebarFooter", "SidebarItem"],
|
|
1429
|
+
example: `<Sidebar>
|
|
1430
|
+
<SidebarHeader><h2>My App</h2></SidebarHeader>
|
|
1431
|
+
<SidebarContent>
|
|
1432
|
+
<SidebarItem icon={<Home />} isActive>Dashboard</SidebarItem>
|
|
1433
|
+
<SidebarItem icon={<Settings />}>Settings</SidebarItem>
|
|
1434
|
+
</SidebarContent>
|
|
1435
|
+
<SidebarFooter>
|
|
1436
|
+
<SidebarItem icon={<LogOut />}>Logout</SidebarItem>
|
|
1437
|
+
</SidebarFooter>
|
|
1438
|
+
</Sidebar>`
|
|
858
1439
|
},
|
|
859
1440
|
header: {
|
|
860
1441
|
name: "Header",
|
|
@@ -867,7 +1448,20 @@ var COMPONENT_REGISTRY = {
|
|
|
867
1448
|
"Sticky headers",
|
|
868
1449
|
"Mobile-friendly navigation"
|
|
869
1450
|
],
|
|
870
|
-
dependencies: ["lucide-react"]
|
|
1451
|
+
dependencies: ["lucide-react"],
|
|
1452
|
+
props: {
|
|
1453
|
+
logo: { type: "ReactNode", description: "Logo element for header" },
|
|
1454
|
+
links: { type: "{ label: string; href: string }[]", description: "Navigation links" },
|
|
1455
|
+
sticky: { type: "boolean", default: "true", description: "Stick to top on scroll" },
|
|
1456
|
+
transparent: { type: "boolean", default: "false", description: "Transparent background (for hero sections)" }
|
|
1457
|
+
},
|
|
1458
|
+
example: `<Header
|
|
1459
|
+
logo={<Brand />}
|
|
1460
|
+
links={[
|
|
1461
|
+
{ label: 'Home', href: '/' },
|
|
1462
|
+
{ label: 'About', href: '/about' },
|
|
1463
|
+
]}
|
|
1464
|
+
/>`
|
|
871
1465
|
},
|
|
872
1466
|
footer: {
|
|
873
1467
|
name: "Footer",
|
|
@@ -880,12 +1474,21 @@ var COMPONENT_REGISTRY = {
|
|
|
880
1474
|
"Contact information",
|
|
881
1475
|
"Copyright notices"
|
|
882
1476
|
],
|
|
883
|
-
dependencies: []
|
|
1477
|
+
dependencies: [],
|
|
1478
|
+
props: {
|
|
1479
|
+
columns: { type: "{ title: string; links: { label: string; href: string }[] }[]", description: "Footer navigation columns" },
|
|
1480
|
+
copyright: { type: "string", description: "Copyright text" },
|
|
1481
|
+
socialLinks: { type: "{ icon: ReactNode; href: string }[]", description: "Social media links" }
|
|
1482
|
+
},
|
|
1483
|
+
example: `<Footer
|
|
1484
|
+
columns={[{ title: 'Product', links: [{ label: 'Docs', href: '/docs' }] }]}
|
|
1485
|
+
copyright="\xA9 2026 My Company"
|
|
1486
|
+
/>`
|
|
884
1487
|
},
|
|
885
1488
|
"customizer-panel": {
|
|
886
1489
|
name: "CustomizerPanel",
|
|
887
1490
|
category: "layout",
|
|
888
|
-
description: "Floating panel for theme, mode, and motion customization",
|
|
1491
|
+
description: "Floating panel for theme, mode, and motion customization. Reads from ThemeProvider context.",
|
|
889
1492
|
keywords: ["customizer", "theme", "settings", "preferences", "dark-mode"],
|
|
890
1493
|
useCases: [
|
|
891
1494
|
"Theme selection",
|
|
@@ -893,7 +1496,9 @@ var COMPONENT_REGISTRY = {
|
|
|
893
1496
|
"Motion preferences",
|
|
894
1497
|
"User experience customization"
|
|
895
1498
|
],
|
|
896
|
-
dependencies: ["lucide-react", "@thesage/tokens"]
|
|
1499
|
+
dependencies: ["lucide-react", "@thesage/tokens"],
|
|
1500
|
+
example: `// Place in your layout. It reads theme state from ThemeProvider.
|
|
1501
|
+
<CustomizerPanel />`
|
|
897
1502
|
},
|
|
898
1503
|
"page-layout": {
|
|
899
1504
|
name: "PageLayout",
|
|
@@ -906,7 +1511,19 @@ var COMPONENT_REGISTRY = {
|
|
|
906
1511
|
"Documentation pages",
|
|
907
1512
|
"Dashboard layouts"
|
|
908
1513
|
],
|
|
909
|
-
dependencies: []
|
|
1514
|
+
dependencies: [],
|
|
1515
|
+
props: {
|
|
1516
|
+
header: { type: "ReactNode", description: "Header element" },
|
|
1517
|
+
footer: { type: "ReactNode", description: "Footer element" },
|
|
1518
|
+
sidebar: { type: "ReactNode", description: "Optional sidebar" },
|
|
1519
|
+
breadcrumbs: { type: "ReactNode", description: "Breadcrumb navigation" }
|
|
1520
|
+
},
|
|
1521
|
+
example: `<PageLayout
|
|
1522
|
+
header={<Header />}
|
|
1523
|
+
footer={<Footer />}
|
|
1524
|
+
>
|
|
1525
|
+
<main>Page content</main>
|
|
1526
|
+
</PageLayout>`
|
|
910
1527
|
},
|
|
911
1528
|
"page-template": {
|
|
912
1529
|
name: "PageTemplate",
|
|
@@ -919,7 +1536,15 @@ var COMPONENT_REGISTRY = {
|
|
|
919
1536
|
"Standard app pages",
|
|
920
1537
|
"Content-focused layouts"
|
|
921
1538
|
],
|
|
922
|
-
dependencies: []
|
|
1539
|
+
dependencies: [],
|
|
1540
|
+
props: {
|
|
1541
|
+
title: { type: "string", description: "Page title" },
|
|
1542
|
+
description: { type: "string", description: "Page description" },
|
|
1543
|
+
showCustomizer: { type: "boolean", default: "true", description: "Show customizer panel" }
|
|
1544
|
+
},
|
|
1545
|
+
example: `<PageTemplate title="Documentation" description="Learn the design system.">
|
|
1546
|
+
<div>Content here.</div>
|
|
1547
|
+
</PageTemplate>`
|
|
923
1548
|
},
|
|
924
1549
|
// ============================================================================
|
|
925
1550
|
// ACTIONS - Additional (2 more)
|
|
@@ -935,7 +1560,13 @@ var COMPONENT_REGISTRY = {
|
|
|
935
1560
|
"External references",
|
|
936
1561
|
"Inline actions"
|
|
937
1562
|
],
|
|
938
|
-
dependencies: []
|
|
1563
|
+
dependencies: [],
|
|
1564
|
+
props: {
|
|
1565
|
+
href: { type: "string", description: "Link URL", required: true },
|
|
1566
|
+
variant: { type: "'default' | 'inline'", default: "'default'", description: "Default for standalone links, inline for text links" },
|
|
1567
|
+
hoverEffect: { type: "boolean", default: "true", description: "Enable hover effect" }
|
|
1568
|
+
},
|
|
1569
|
+
example: `<Link href="/about" variant="inline">Learn More</Link>`
|
|
939
1570
|
},
|
|
940
1571
|
magnetic: {
|
|
941
1572
|
name: "Magnetic",
|
|
@@ -948,7 +1579,14 @@ var COMPONENT_REGISTRY = {
|
|
|
948
1579
|
"Playful interactions",
|
|
949
1580
|
"Cursor attraction"
|
|
950
1581
|
],
|
|
951
|
-
dependencies: ["framer-motion"]
|
|
1582
|
+
dependencies: ["framer-motion"],
|
|
1583
|
+
props: {
|
|
1584
|
+
children: { type: "ReactNode", description: "Element to apply magnetic effect to", required: true },
|
|
1585
|
+
strength: { type: "number", default: "0.5", description: "Magnetic pull strength (0-1)" }
|
|
1586
|
+
},
|
|
1587
|
+
example: `<Magnetic strength={0.5}>
|
|
1588
|
+
<Button>Hover me</Button>
|
|
1589
|
+
</Magnetic>`
|
|
952
1590
|
},
|
|
953
1591
|
// ============================================================================
|
|
954
1592
|
// FORMS - Additional (7 more)
|
|
@@ -964,7 +1602,14 @@ var COMPONENT_REGISTRY = {
|
|
|
964
1602
|
"Command palette trigger",
|
|
965
1603
|
"Data filtering"
|
|
966
1604
|
],
|
|
967
|
-
dependencies: ["lucide-react"]
|
|
1605
|
+
dependencies: ["lucide-react"],
|
|
1606
|
+
props: {
|
|
1607
|
+
value: { type: "string", description: "Controlled search value" },
|
|
1608
|
+
onChange: { type: "(value: string) => void", description: "Callback on value change" },
|
|
1609
|
+
placeholder: { type: "string", default: "'Search...'", description: "Placeholder text" },
|
|
1610
|
+
onClear: { type: "() => void", description: "Callback on clear button click" }
|
|
1611
|
+
},
|
|
1612
|
+
example: `<SearchBar value={query} onChange={setQuery} placeholder="Search components..." />`
|
|
968
1613
|
},
|
|
969
1614
|
"filter-button": {
|
|
970
1615
|
name: "FilterButton",
|
|
@@ -977,12 +1622,18 @@ var COMPONENT_REGISTRY = {
|
|
|
977
1622
|
"Content filtering",
|
|
978
1623
|
"Quick filters"
|
|
979
1624
|
],
|
|
980
|
-
dependencies: []
|
|
1625
|
+
dependencies: [],
|
|
1626
|
+
props: {
|
|
1627
|
+
active: { type: "boolean", default: "false", description: "Whether filter is active" },
|
|
1628
|
+
onClick: { type: "() => void", description: "Click handler" },
|
|
1629
|
+
children: { type: "ReactNode", description: "Filter label", required: true }
|
|
1630
|
+
},
|
|
1631
|
+
example: `<FilterButton active={category === 'all'} onClick={() => setCategory('all')}>All</FilterButton>`
|
|
981
1632
|
},
|
|
982
1633
|
"theme-switcher": {
|
|
983
1634
|
name: "ThemeSwitcher",
|
|
984
1635
|
category: "forms",
|
|
985
|
-
description: "Multi-theme selector for switching between Studio, Terra, and Volt",
|
|
1636
|
+
description: "Multi-theme selector for switching between Studio, Terra, and Volt. Reads/writes to ThemeProvider context.",
|
|
986
1637
|
keywords: ["theme", "switcher", "selector", "studio", "terra", "volt"],
|
|
987
1638
|
useCases: [
|
|
988
1639
|
"Theme selection",
|
|
@@ -990,12 +1641,14 @@ var COMPONENT_REGISTRY = {
|
|
|
990
1641
|
"User preferences",
|
|
991
1642
|
"Design switching"
|
|
992
1643
|
],
|
|
993
|
-
dependencies: []
|
|
1644
|
+
dependencies: [],
|
|
1645
|
+
example: `// Reads from ThemeProvider context, no props needed.
|
|
1646
|
+
<ThemeSwitcher />`
|
|
994
1647
|
},
|
|
995
1648
|
"theme-toggle": {
|
|
996
1649
|
name: "ThemeToggle",
|
|
997
1650
|
category: "forms",
|
|
998
|
-
description: "Light/dark mode toggle with smooth transitions",
|
|
1651
|
+
description: "Light/dark mode toggle with smooth transitions. Reads/writes to ThemeProvider context.",
|
|
999
1652
|
keywords: ["theme", "toggle", "dark-mode", "light-mode", "mode"],
|
|
1000
1653
|
useCases: [
|
|
1001
1654
|
"Dark mode switch",
|
|
@@ -1003,7 +1656,9 @@ var COMPONENT_REGISTRY = {
|
|
|
1003
1656
|
"Theme mode control",
|
|
1004
1657
|
"Accessibility preference"
|
|
1005
1658
|
],
|
|
1006
|
-
dependencies: ["lucide-react"]
|
|
1659
|
+
dependencies: ["lucide-react"],
|
|
1660
|
+
example: `// Reads from ThemeProvider context, no props needed.
|
|
1661
|
+
<ThemeToggle />`
|
|
1007
1662
|
},
|
|
1008
1663
|
"color-picker": {
|
|
1009
1664
|
name: "ColorPicker",
|
|
@@ -1016,7 +1671,13 @@ var COMPONENT_REGISTRY = {
|
|
|
1016
1671
|
"Design tools",
|
|
1017
1672
|
"User preferences"
|
|
1018
1673
|
],
|
|
1019
|
-
dependencies: []
|
|
1674
|
+
dependencies: [],
|
|
1675
|
+
props: {
|
|
1676
|
+
value: { type: "string", description: "Selected color (hex string)" },
|
|
1677
|
+
onChange: { type: "(color: string) => void", description: "Callback on color change" },
|
|
1678
|
+
presets: { type: "string[]", description: "Preset color swatches (hex values)" }
|
|
1679
|
+
},
|
|
1680
|
+
example: `<ColorPicker value={color} onChange={setColor} presets={['#ef4444', '#3b82f6', '#22c55e']} />`
|
|
1020
1681
|
},
|
|
1021
1682
|
"drag-drop": {
|
|
1022
1683
|
name: "DragDrop",
|
|
@@ -1029,7 +1690,14 @@ var COMPONENT_REGISTRY = {
|
|
|
1029
1690
|
"Document uploads",
|
|
1030
1691
|
"Bulk imports"
|
|
1031
1692
|
],
|
|
1032
|
-
dependencies: []
|
|
1693
|
+
dependencies: [],
|
|
1694
|
+
props: {
|
|
1695
|
+
onDrop: { type: "(files: File[]) => void", description: "Callback when files are dropped", required: true },
|
|
1696
|
+
accept: { type: "string", description: 'Accepted file types (e.g. "image/*")' },
|
|
1697
|
+
maxSize: { type: "number", description: "Max file size in bytes" },
|
|
1698
|
+
multiple: { type: "boolean", default: "true", description: "Allow multiple files" }
|
|
1699
|
+
},
|
|
1700
|
+
example: `<DragDrop onDrop={(files) => handleUpload(files)} accept="image/*" maxSize={5242880} />`
|
|
1033
1701
|
},
|
|
1034
1702
|
"text-field": {
|
|
1035
1703
|
name: "TextField",
|
|
@@ -1042,7 +1710,14 @@ var COMPONENT_REGISTRY = {
|
|
|
1042
1710
|
"Validated inputs",
|
|
1043
1711
|
"Complete form controls"
|
|
1044
1712
|
],
|
|
1045
|
-
dependencies: []
|
|
1713
|
+
dependencies: [],
|
|
1714
|
+
props: {
|
|
1715
|
+
label: { type: "string", description: "Field label text" },
|
|
1716
|
+
helperText: { type: "string", description: "Helper text below input" },
|
|
1717
|
+
error: { type: "string", description: "Error message (shows error state when set)" },
|
|
1718
|
+
required: { type: "boolean", default: "false", description: "Mark as required" }
|
|
1719
|
+
},
|
|
1720
|
+
example: `<TextField label="Email" helperText="We'll never share your email." error={errors.email} required />`
|
|
1046
1721
|
},
|
|
1047
1722
|
// ============================================================================
|
|
1048
1723
|
// NAVIGATION - Additional (4 more)
|
|
@@ -1058,7 +1733,13 @@ var COMPONENT_REGISTRY = {
|
|
|
1058
1733
|
"Header navigation",
|
|
1059
1734
|
"Active page indicators"
|
|
1060
1735
|
],
|
|
1061
|
-
dependencies: []
|
|
1736
|
+
dependencies: [],
|
|
1737
|
+
props: {
|
|
1738
|
+
href: { type: "string", description: "Link URL", required: true },
|
|
1739
|
+
isActive: { type: "boolean", default: "false", description: "Active state indicator" },
|
|
1740
|
+
variant: { type: "'default' | 'subtle'", default: "'default'", description: "Visual variant" }
|
|
1741
|
+
},
|
|
1742
|
+
example: `<NavLink href="/dashboard" isActive>Dashboard</NavLink>`
|
|
1062
1743
|
},
|
|
1063
1744
|
"secondary-nav": {
|
|
1064
1745
|
name: "SecondaryNav",
|
|
@@ -1071,7 +1752,14 @@ var COMPONENT_REGISTRY = {
|
|
|
1071
1752
|
"Tab-like navigation",
|
|
1072
1753
|
"Category switching"
|
|
1073
1754
|
],
|
|
1074
|
-
dependencies: []
|
|
1755
|
+
dependencies: [],
|
|
1756
|
+
props: {
|
|
1757
|
+
items: { type: "{ label: string; href: string; isActive?: boolean }[]", description: "Navigation items", required: true }
|
|
1758
|
+
},
|
|
1759
|
+
example: `<SecondaryNav items={[
|
|
1760
|
+
{ label: 'Overview', href: '/overview', isActive: true },
|
|
1761
|
+
{ label: 'Settings', href: '/settings' },
|
|
1762
|
+
]} />`
|
|
1075
1763
|
},
|
|
1076
1764
|
"tertiary-nav": {
|
|
1077
1765
|
name: "TertiaryNav",
|
|
@@ -1084,7 +1772,14 @@ var COMPONENT_REGISTRY = {
|
|
|
1084
1772
|
"Multi-level content",
|
|
1085
1773
|
"Nested categories"
|
|
1086
1774
|
],
|
|
1087
|
-
dependencies: []
|
|
1775
|
+
dependencies: [],
|
|
1776
|
+
props: {
|
|
1777
|
+
items: { type: "{ label: string; href: string; isActive?: boolean }[]", description: "Navigation items", required: true }
|
|
1778
|
+
},
|
|
1779
|
+
example: `<TertiaryNav items={[
|
|
1780
|
+
{ label: 'Props', href: '#props', isActive: true },
|
|
1781
|
+
{ label: 'Examples', href: '#examples' },
|
|
1782
|
+
]} />`
|
|
1088
1783
|
},
|
|
1089
1784
|
breadcrumbs: {
|
|
1090
1785
|
name: "Breadcrumbs",
|
|
@@ -1097,7 +1792,16 @@ var COMPONENT_REGISTRY = {
|
|
|
1097
1792
|
"Hierarchical navigation",
|
|
1098
1793
|
"Back navigation"
|
|
1099
1794
|
],
|
|
1100
|
-
dependencies: ["lucide-react"]
|
|
1795
|
+
dependencies: ["lucide-react"],
|
|
1796
|
+
props: {
|
|
1797
|
+
items: { type: "{ label: string; href?: string }[]", description: "Breadcrumb trail items (last item is current page)", required: true },
|
|
1798
|
+
showHome: { type: "boolean", default: "true", description: "Show home icon as first item" }
|
|
1799
|
+
},
|
|
1800
|
+
example: `<Breadcrumbs items={[
|
|
1801
|
+
{ label: 'Home', href: '/' },
|
|
1802
|
+
{ label: 'Components', href: '/components' },
|
|
1803
|
+
{ label: 'Button' },
|
|
1804
|
+
]} />`
|
|
1101
1805
|
},
|
|
1102
1806
|
// ============================================================================
|
|
1103
1807
|
// OVERLAYS - Additional (2 more)
|
|
@@ -1114,7 +1818,19 @@ var COMPONENT_REGISTRY = {
|
|
|
1114
1818
|
"Content overlays"
|
|
1115
1819
|
],
|
|
1116
1820
|
dependencies: ["@radix-ui/react-dialog"],
|
|
1117
|
-
radixPrimitive: "@radix-ui/react-dialog"
|
|
1821
|
+
radixPrimitive: "@radix-ui/react-dialog",
|
|
1822
|
+
props: {
|
|
1823
|
+
open: { type: "boolean", description: "Controlled open state" },
|
|
1824
|
+
onOpenChange: { type: "(open: boolean) => void", description: "Callback on open/close" },
|
|
1825
|
+
title: { type: "string", description: "Modal title" },
|
|
1826
|
+
description: { type: "string", description: "Modal description" }
|
|
1827
|
+
},
|
|
1828
|
+
example: `<Modal open={isOpen} onOpenChange={setIsOpen} title="Confirm" description="Are you sure?">
|
|
1829
|
+
<div className="flex gap-2 justify-end">
|
|
1830
|
+
<Button variant="outline" onClick={() => setIsOpen(false)}>Cancel</Button>
|
|
1831
|
+
<Button onClick={handleConfirm}>Confirm</Button>
|
|
1832
|
+
</div>
|
|
1833
|
+
</Modal>`
|
|
1118
1834
|
},
|
|
1119
1835
|
dropdown: {
|
|
1120
1836
|
name: "Dropdown",
|
|
@@ -1128,7 +1844,12 @@ var COMPONENT_REGISTRY = {
|
|
|
1128
1844
|
"Option lists"
|
|
1129
1845
|
],
|
|
1130
1846
|
dependencies: ["@radix-ui/react-dropdown-menu"],
|
|
1131
|
-
radixPrimitive: "@radix-ui/react-dropdown-menu"
|
|
1847
|
+
radixPrimitive: "@radix-ui/react-dropdown-menu",
|
|
1848
|
+
props: {
|
|
1849
|
+
open: { type: "boolean", description: "Controlled open state" },
|
|
1850
|
+
onOpenChange: { type: "(open: boolean) => void", description: "Callback on open/close" }
|
|
1851
|
+
},
|
|
1852
|
+
example: `// For most cases, use DropdownMenu directly. This is a simplified wrapper.`
|
|
1132
1853
|
},
|
|
1133
1854
|
// ============================================================================
|
|
1134
1855
|
// FEEDBACK - Additional (2 more)
|
|
@@ -1144,7 +1865,13 @@ var COMPONENT_REGISTRY = {
|
|
|
1144
1865
|
"Data fetching",
|
|
1145
1866
|
"Async operations"
|
|
1146
1867
|
],
|
|
1147
|
-
dependencies: []
|
|
1868
|
+
dependencies: [],
|
|
1869
|
+
props: {
|
|
1870
|
+
size: { type: "'xs' | 'sm' | 'md' | 'lg' | 'xl'", default: "'md'", description: "Spinner size" },
|
|
1871
|
+
variant: { type: "'primary' | 'secondary' | 'inherit'", default: "'primary'", description: "Color variant" }
|
|
1872
|
+
},
|
|
1873
|
+
example: `<Spinner size="md" />
|
|
1874
|
+
<Button disabled><Spinner size="xs" variant="inherit" /> Loading...</Button>`
|
|
1148
1875
|
},
|
|
1149
1876
|
"progress-bar": {
|
|
1150
1877
|
name: "ProgressBar",
|
|
@@ -1157,7 +1884,14 @@ var COMPONENT_REGISTRY = {
|
|
|
1157
1884
|
"Loading indicators",
|
|
1158
1885
|
"Step completion"
|
|
1159
1886
|
],
|
|
1160
|
-
dependencies: []
|
|
1887
|
+
dependencies: [],
|
|
1888
|
+
props: {
|
|
1889
|
+
value: { type: "number", default: "0", description: "Progress value (0-100)" },
|
|
1890
|
+
variant: { type: "'primary' | 'success' | 'warning' | 'error' | 'info'", default: "'primary'", description: "Color variant" },
|
|
1891
|
+
size: { type: "'sm' | 'md' | 'lg'", default: "'md'", description: "Bar height" },
|
|
1892
|
+
showLabel: { type: "boolean", default: "false", description: "Show percentage label" }
|
|
1893
|
+
},
|
|
1894
|
+
example: `<ProgressBar value={75} variant="success" showLabel />`
|
|
1161
1895
|
},
|
|
1162
1896
|
// ============================================================================
|
|
1163
1897
|
// DATA DISPLAY - Additional (5 more)
|
|
@@ -1173,7 +1907,13 @@ var COMPONENT_REGISTRY = {
|
|
|
1173
1907
|
"Footer branding",
|
|
1174
1908
|
"App identity"
|
|
1175
1909
|
],
|
|
1176
|
-
dependencies: []
|
|
1910
|
+
dependencies: [],
|
|
1911
|
+
props: {
|
|
1912
|
+
variant: { type: "'default' | 'mark'", default: "'default'", description: "Full logo or mark only" },
|
|
1913
|
+
size: { type: "'sm' | 'md' | 'lg'", default: "'md'", description: "Logo size" },
|
|
1914
|
+
href: { type: "string", description: "Optional link URL (wraps in anchor)" }
|
|
1915
|
+
},
|
|
1916
|
+
example: `<Brand size="md" href="/" />`
|
|
1177
1917
|
},
|
|
1178
1918
|
"aspect-image": {
|
|
1179
1919
|
name: "AspectImage",
|
|
@@ -1186,7 +1926,15 @@ var COMPONENT_REGISTRY = {
|
|
|
1186
1926
|
"Product images",
|
|
1187
1927
|
"Thumbnails with captions"
|
|
1188
1928
|
],
|
|
1189
|
-
dependencies: []
|
|
1929
|
+
dependencies: [],
|
|
1930
|
+
props: {
|
|
1931
|
+
src: { type: "string", description: "Image source URL", required: true },
|
|
1932
|
+
alt: { type: "string", description: "Alt text for accessibility", required: true },
|
|
1933
|
+
ratio: { type: "number", default: "16/9", description: "Aspect ratio" },
|
|
1934
|
+
rounded: { type: "'none' | 'sm' | 'md' | 'lg' | 'full'", default: "'md'", description: "Border radius" },
|
|
1935
|
+
caption: { type: "string", description: "Optional caption text below image" }
|
|
1936
|
+
},
|
|
1937
|
+
example: `<AspectImage src="/photo.jpg" alt="Team photo" ratio={4/3} caption="Our team" />`
|
|
1190
1938
|
},
|
|
1191
1939
|
"variable-weight-text": {
|
|
1192
1940
|
name: "VariableWeightText",
|
|
@@ -1199,7 +1947,14 @@ var COMPONENT_REGISTRY = {
|
|
|
1199
1947
|
"Attention grabbing",
|
|
1200
1948
|
"Variable font showcase"
|
|
1201
1949
|
],
|
|
1202
|
-
dependencies: ["framer-motion"]
|
|
1950
|
+
dependencies: ["framer-motion"],
|
|
1951
|
+
props: {
|
|
1952
|
+
children: { type: "string", description: "Text content", required: true },
|
|
1953
|
+
speed: { type: "number", default: "2", description: "Animation speed in seconds" },
|
|
1954
|
+
minWeight: { type: "number", default: "100", description: "Minimum font weight" },
|
|
1955
|
+
maxWeight: { type: "number", default: "900", description: "Maximum font weight" }
|
|
1956
|
+
},
|
|
1957
|
+
example: `<VariableWeightText speed={2} minWeight={200} maxWeight={800}>Design</VariableWeightText>`
|
|
1203
1958
|
},
|
|
1204
1959
|
typewriter: {
|
|
1205
1960
|
name: "Typewriter",
|
|
@@ -1212,7 +1967,14 @@ var COMPONENT_REGISTRY = {
|
|
|
1212
1967
|
"Dynamic headings",
|
|
1213
1968
|
"Attention text"
|
|
1214
1969
|
],
|
|
1215
|
-
dependencies: ["framer-motion"]
|
|
1970
|
+
dependencies: ["framer-motion"],
|
|
1971
|
+
props: {
|
|
1972
|
+
words: { type: "string[]", description: "Words to cycle through", required: true },
|
|
1973
|
+
speed: { type: "number", default: "100", description: "Typing speed in ms per character" },
|
|
1974
|
+
loop: { type: "boolean", default: "true", description: "Loop through words continuously" },
|
|
1975
|
+
cursor: { type: "boolean", default: "true", description: "Show blinking cursor" }
|
|
1976
|
+
},
|
|
1977
|
+
example: `<Typewriter words={['Developer', 'Designer', 'Creator']} speed={80} />`
|
|
1216
1978
|
},
|
|
1217
1979
|
"github-icon": {
|
|
1218
1980
|
name: "GitHubIcon",
|
|
@@ -1225,7 +1987,11 @@ var COMPONENT_REGISTRY = {
|
|
|
1225
1987
|
"Repository links",
|
|
1226
1988
|
"Open source badges"
|
|
1227
1989
|
],
|
|
1228
|
-
dependencies: []
|
|
1990
|
+
dependencies: [],
|
|
1991
|
+
props: {
|
|
1992
|
+
size: { type: "number", default: "24", description: "Icon size in pixels" }
|
|
1993
|
+
},
|
|
1994
|
+
example: `<a href="https://github.com/you"><GitHubIcon size={20} /></a>`
|
|
1229
1995
|
},
|
|
1230
1996
|
// ============================================================================
|
|
1231
1997
|
// SPECIALTY - Backgrounds (3)
|
|
@@ -1241,7 +2007,15 @@ var COMPONENT_REGISTRY = {
|
|
|
1241
2007
|
"Loading screens",
|
|
1242
2008
|
"Sci-fi themes"
|
|
1243
2009
|
],
|
|
1244
|
-
dependencies: ["framer-motion"]
|
|
2010
|
+
dependencies: ["framer-motion"],
|
|
2011
|
+
props: {
|
|
2012
|
+
speed: { type: "number", default: "1", description: "Warp speed multiplier" },
|
|
2013
|
+
density: { type: "number", default: "200", description: "Number of stars" },
|
|
2014
|
+
color: { type: "string", default: "'white'", description: "Star color" }
|
|
2015
|
+
},
|
|
2016
|
+
example: `<WarpBackground speed={1.5} density={300}>
|
|
2017
|
+
<div className="relative z-10">Content over stars</div>
|
|
2018
|
+
</WarpBackground>`
|
|
1245
2019
|
},
|
|
1246
2020
|
"faulty-terminal": {
|
|
1247
2021
|
name: "FaultyTerminal",
|
|
@@ -1254,7 +2028,13 @@ var COMPONENT_REGISTRY = {
|
|
|
1254
2028
|
"Error pages",
|
|
1255
2029
|
"Terminal UIs"
|
|
1256
2030
|
],
|
|
1257
|
-
dependencies: []
|
|
2031
|
+
dependencies: [],
|
|
2032
|
+
props: {
|
|
2033
|
+
children: { type: "ReactNode", description: "Content to render inside terminal" }
|
|
2034
|
+
},
|
|
2035
|
+
example: `<FaultyTerminal>
|
|
2036
|
+
<p>$ system initializing...</p>
|
|
2037
|
+
</FaultyTerminal>`
|
|
1258
2038
|
},
|
|
1259
2039
|
"orb-background": {
|
|
1260
2040
|
name: "OrbBackground",
|
|
@@ -1267,7 +2047,14 @@ var COMPONENT_REGISTRY = {
|
|
|
1267
2047
|
"Ambient backgrounds",
|
|
1268
2048
|
"Modern aesthetics"
|
|
1269
2049
|
],
|
|
1270
|
-
dependencies: ["framer-motion"]
|
|
2050
|
+
dependencies: ["framer-motion"],
|
|
2051
|
+
props: {
|
|
2052
|
+
color: { type: "string", description: "Primary orb color" },
|
|
2053
|
+
size: { type: "number", default: "400", description: "Orb diameter in pixels" }
|
|
2054
|
+
},
|
|
2055
|
+
example: `<OrbBackground color="var(--color-primary)" size={500}>
|
|
2056
|
+
<div className="relative z-10">Content</div>
|
|
2057
|
+
</OrbBackground>`
|
|
1271
2058
|
},
|
|
1272
2059
|
// ============================================================================
|
|
1273
2060
|
// SPECIALTY - Cursor (2)
|
|
@@ -1275,7 +2062,7 @@ var COMPONENT_REGISTRY = {
|
|
|
1275
2062
|
"splash-cursor": {
|
|
1276
2063
|
name: "SplashCursor",
|
|
1277
2064
|
category: "cursor",
|
|
1278
|
-
description: "Custom cursor with splash/ripple effect on click",
|
|
2065
|
+
description: "Custom cursor with splash/ripple effect on click. WebGL-based fluid simulation.",
|
|
1279
2066
|
keywords: ["cursor", "splash", "ripple", "click", "effect", "interactive"],
|
|
1280
2067
|
useCases: [
|
|
1281
2068
|
"Interactive experiences",
|
|
@@ -1283,7 +2070,9 @@ var COMPONENT_REGISTRY = {
|
|
|
1283
2070
|
"Playful interfaces",
|
|
1284
2071
|
"Click feedback"
|
|
1285
2072
|
],
|
|
1286
|
-
dependencies: []
|
|
2073
|
+
dependencies: [],
|
|
2074
|
+
example: `// Place once in layout. Replaces default cursor globally.
|
|
2075
|
+
<SplashCursor />`
|
|
1287
2076
|
},
|
|
1288
2077
|
"target-cursor": {
|
|
1289
2078
|
name: "TargetCursor",
|
|
@@ -1296,7 +2085,9 @@ var COMPONENT_REGISTRY = {
|
|
|
1296
2085
|
"Interactive elements",
|
|
1297
2086
|
"Custom pointers"
|
|
1298
2087
|
],
|
|
1299
|
-
dependencies: []
|
|
2088
|
+
dependencies: [],
|
|
2089
|
+
example: `// Place once in layout. Replaces default cursor globally.
|
|
2090
|
+
<TargetCursor />`
|
|
1300
2091
|
},
|
|
1301
2092
|
// ============================================================================
|
|
1302
2093
|
// SPECIALTY - Motion (1)
|
|
@@ -1312,7 +2103,17 @@ var COMPONENT_REGISTRY = {
|
|
|
1312
2103
|
"Architecture diagrams",
|
|
1313
2104
|
"Interactive connections"
|
|
1314
2105
|
],
|
|
1315
|
-
dependencies: ["framer-motion"]
|
|
2106
|
+
dependencies: ["framer-motion"],
|
|
2107
|
+
props: {
|
|
2108
|
+
fromRef: { type: "RefObject<HTMLElement>", description: "Ref to source element", required: true },
|
|
2109
|
+
toRef: { type: "RefObject<HTMLElement>", description: "Ref to target element", required: true },
|
|
2110
|
+
duration: { type: "number", default: "3", description: "Animation duration in seconds" }
|
|
2111
|
+
},
|
|
2112
|
+
example: `const fromRef = useRef(null)
|
|
2113
|
+
const toRef = useRef(null)
|
|
2114
|
+
<div ref={fromRef}>Source</div>
|
|
2115
|
+
<div ref={toRef}>Target</div>
|
|
2116
|
+
<AnimatedBeam fromRef={fromRef} toRef={toRef} />`
|
|
1316
2117
|
},
|
|
1317
2118
|
// ============================================================================
|
|
1318
2119
|
// SPECIALTY - Blocks (2)
|
|
@@ -1328,12 +2129,23 @@ var COMPONENT_REGISTRY = {
|
|
|
1328
2129
|
"Marketing sections",
|
|
1329
2130
|
"Feature highlights"
|
|
1330
2131
|
],
|
|
1331
|
-
dependencies: []
|
|
2132
|
+
dependencies: [],
|
|
2133
|
+
props: {
|
|
2134
|
+
title: { type: "string", description: "Main heading text", required: true },
|
|
2135
|
+
subtitle: { type: "string", description: "Subtitle or tagline" },
|
|
2136
|
+
cta: { type: "ReactNode", description: "Call-to-action element (Button, etc.)" },
|
|
2137
|
+
background: { type: "ReactNode", description: "Optional background element (WarpBackground, OrbBackground, etc.)" }
|
|
2138
|
+
},
|
|
2139
|
+
example: `<Hero
|
|
2140
|
+
title="Build Something Beautiful"
|
|
2141
|
+
subtitle="A design system that brings joy."
|
|
2142
|
+
cta={<Button size="lg">Get Started</Button>}
|
|
2143
|
+
/>`
|
|
1332
2144
|
},
|
|
1333
2145
|
"open-graph-card": {
|
|
1334
2146
|
name: "OpenGraphCard",
|
|
1335
2147
|
category: "blocks",
|
|
1336
|
-
description: "Social media preview card for Open Graph metadata",
|
|
2148
|
+
description: "Social media preview card for Open Graph metadata. Use in opengraph-image.tsx.",
|
|
1337
2149
|
keywords: ["open-graph", "social", "preview", "card", "meta", "share"],
|
|
1338
2150
|
useCases: [
|
|
1339
2151
|
"Social sharing previews",
|
|
@@ -1341,7 +2153,21 @@ var COMPONENT_REGISTRY = {
|
|
|
1341
2153
|
"Meta card generation",
|
|
1342
2154
|
"Marketing previews"
|
|
1343
2155
|
],
|
|
1344
|
-
dependencies: []
|
|
2156
|
+
dependencies: [],
|
|
2157
|
+
props: {
|
|
2158
|
+
title: { type: "string", default: "'Sage Design Engine'", description: "Main title text" },
|
|
2159
|
+
description: { type: "string", description: "Subtitle text" },
|
|
2160
|
+
variant: { type: "'primary' | 'secondary' | 'accent' | 'sage' | 'emerald' | 'gradient'", default: "'sage'", description: "Visual style variant" },
|
|
2161
|
+
icon: { type: "ReactNode", description: "Custom logo or icon element" },
|
|
2162
|
+
gradient: { type: "{ type: string; angle: number; colors: string[] }", description: 'Custom gradient config (variant="gradient")' },
|
|
2163
|
+
primaryColor: { type: "string", description: "Override primary color (hex)" },
|
|
2164
|
+
secondaryColor: { type: "string", description: "Override secondary color (hex)" },
|
|
2165
|
+
accentColor: { type: "string", description: "Override accent color (hex)" }
|
|
2166
|
+
},
|
|
2167
|
+
example: `// In opengraph-image.tsx:
|
|
2168
|
+
export default function OGImage() {
|
|
2169
|
+
return <OpenGraphCard title="My Page" description="A great description" variant="primary" />
|
|
2170
|
+
}`
|
|
1345
2171
|
}
|
|
1346
2172
|
};
|
|
1347
2173
|
function getComponentsByCategory(category) {
|
|
@@ -1491,6 +2317,47 @@ function formatComponentDetails(component) {
|
|
|
1491
2317
|
${component.description}
|
|
1492
2318
|
|
|
1493
2319
|
`;
|
|
2320
|
+
const importParts = [component.name];
|
|
2321
|
+
if (component.subComponents) {
|
|
2322
|
+
importParts.push(...component.subComponents);
|
|
2323
|
+
}
|
|
2324
|
+
output += `## Import
|
|
2325
|
+
`;
|
|
2326
|
+
output += `\`\`\`typescript
|
|
2327
|
+
import { ${importParts.join(", ")} } from '@thesage/ui';
|
|
2328
|
+
\`\`\`
|
|
2329
|
+
|
|
2330
|
+
`;
|
|
2331
|
+
if (component.props && Object.keys(component.props).length > 0) {
|
|
2332
|
+
output += `## Props
|
|
2333
|
+
|
|
2334
|
+
`;
|
|
2335
|
+
output += `| Prop | Type | Default | Description |
|
|
2336
|
+
`;
|
|
2337
|
+
output += `|------|------|---------|-------------|
|
|
2338
|
+
`;
|
|
2339
|
+
Object.entries(component.props).forEach(([name, prop]) => {
|
|
2340
|
+
const required = prop.required ? " **(required)**" : "";
|
|
2341
|
+
const defaultVal = prop.default || "-";
|
|
2342
|
+
output += `| ${name} | \`${prop.type}\` | ${defaultVal} | ${prop.description}${required} |
|
|
2343
|
+
`;
|
|
2344
|
+
});
|
|
2345
|
+
output += "\n";
|
|
2346
|
+
}
|
|
2347
|
+
if (component.subComponents && component.subComponents.length > 0) {
|
|
2348
|
+
output += `## Sub-Components
|
|
2349
|
+
`;
|
|
2350
|
+
output += component.subComponents.join(", ") + "\n\n";
|
|
2351
|
+
}
|
|
2352
|
+
if (component.example) {
|
|
2353
|
+
output += `## Example
|
|
2354
|
+
`;
|
|
2355
|
+
output += `\`\`\`tsx
|
|
2356
|
+
${component.example}
|
|
2357
|
+
\`\`\`
|
|
2358
|
+
|
|
2359
|
+
`;
|
|
2360
|
+
}
|
|
1494
2361
|
output += `## Use Cases
|
|
1495
2362
|
`;
|
|
1496
2363
|
component.useCases.forEach((useCase) => {
|
|
@@ -1498,9 +2365,6 @@ ${component.description}
|
|
|
1498
2365
|
`;
|
|
1499
2366
|
});
|
|
1500
2367
|
output += "\n";
|
|
1501
|
-
output += `## Keywords
|
|
1502
|
-
`;
|
|
1503
|
-
output += component.keywords.join(", ") + "\n\n";
|
|
1504
2368
|
if (component.dependencies.length > 0) {
|
|
1505
2369
|
output += `## Dependencies
|
|
1506
2370
|
`;
|
|
@@ -1517,16 +2381,12 @@ ${component.description}
|
|
|
1517
2381
|
|
|
1518
2382
|
`;
|
|
1519
2383
|
}
|
|
1520
|
-
output += `## Import
|
|
1521
|
-
`;
|
|
1522
|
-
output += `\`\`\`typescript
|
|
1523
|
-
import { ${component.name} } from '@thesage/ui';
|
|
1524
|
-
\`\`\`
|
|
1525
|
-
|
|
1526
|
-
`;
|
|
1527
2384
|
output += `## Documentation
|
|
1528
2385
|
`;
|
|
1529
|
-
output += `View full documentation at: https://thesage.dev
|
|
2386
|
+
output += `View full documentation at: https://thesage.dev/docs#${component.category}/${component.name.toLowerCase().replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase()}
|
|
2387
|
+
`;
|
|
2388
|
+
output += `
|
|
2389
|
+
Full API reference: https://thesage.dev/llms-full.txt
|
|
1530
2390
|
`;
|
|
1531
2391
|
return output;
|
|
1532
2392
|
}
|