@usevyre/ai-context 0.1.1 → 0.2.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 (41) hide show
  1. package/dist/anti-patterns.json +222 -0
  2. package/dist/cheat-sheets/accordion.md +25 -0
  3. package/dist/cheat-sheets/alert.md +35 -0
  4. package/dist/cheat-sheets/avatar.md +34 -0
  5. package/dist/cheat-sheets/badge.md +41 -0
  6. package/dist/cheat-sheets/breadcrumb.md +26 -0
  7. package/dist/cheat-sheets/button.md +63 -0
  8. package/dist/cheat-sheets/calendar.md +27 -0
  9. package/dist/cheat-sheets/card.md +37 -0
  10. package/dist/cheat-sheets/checkbox.md +32 -0
  11. package/dist/cheat-sheets/command.md +29 -0
  12. package/dist/cheat-sheets/dropdownmenu.md +25 -0
  13. package/dist/cheat-sheets/field.md +36 -0
  14. package/dist/cheat-sheets/index.md +34 -0
  15. package/dist/cheat-sheets/input.md +28 -0
  16. package/dist/cheat-sheets/label.md +22 -0
  17. package/dist/cheat-sheets/modal.md +33 -0
  18. package/dist/cheat-sheets/pagination.md +15 -0
  19. package/dist/cheat-sheets/popover.md +32 -0
  20. package/dist/cheat-sheets/progress.md +27 -0
  21. package/dist/cheat-sheets/select.md +32 -0
  22. package/dist/cheat-sheets/separator.md +26 -0
  23. package/dist/cheat-sheets/sheet.md +28 -0
  24. package/dist/cheat-sheets/sidebar.md +33 -0
  25. package/dist/cheat-sheets/skeleton.md +27 -0
  26. package/dist/cheat-sheets/slider.md +22 -0
  27. package/dist/cheat-sheets/switch.md +26 -0
  28. package/dist/cheat-sheets/table.md +28 -0
  29. package/dist/cheat-sheets/tabs.md +24 -0
  30. package/dist/cheat-sheets/toast.md +41 -0
  31. package/dist/cheat-sheets/tooltip.md +30 -0
  32. package/dist/cheat-sheets/typography.md +22 -0
  33. package/dist/claude-context.md +716 -40
  34. package/dist/copilot-instructions.md +716 -40
  35. package/dist/cursor-rules.md +255 -261
  36. package/dist/full-context.md +715 -40
  37. package/dist/index.js +5054 -584
  38. package/dist/schema.json +1278 -0
  39. package/dist/version-info.json +233 -0
  40. package/dist/windsurf-rules.md +716 -40
  41. package/package.json +6 -2
@@ -0,0 +1,1278 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "version": "0.2.0",
4
+ "generatedAt": "2026-05-08",
5
+ "package": "@usevyre/react",
6
+ "packageVersion": "0.1.1",
7
+ "validFor": [
8
+ "@usevyre/react@0.1.1+",
9
+ "@usevyre/vue@0.1.1+"
10
+ ],
11
+ "changelog": {
12
+ "0.2.0": {
13
+ "date": "2026-05-08",
14
+ "breaking": false,
15
+ "summary": "Added structured schema, anti-patterns JSON, per-tool format generation"
16
+ },
17
+ "0.1.1": {
18
+ "date": "2026-05-06",
19
+ "breaking": false,
20
+ "summary": "Initial AI context with full-context.md, cursor/claude/windsurf/copilot formats"
21
+ }
22
+ },
23
+ "components": {
24
+ "Accordion": {
25
+ "description": "Vertically stacked collapsible sections. Compose with AccordionItem, AccordionTrigger, AccordionContent.",
26
+ "import": "import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from \"@usevyre/react\"",
27
+ "subcomponents": [
28
+ "AccordionItem",
29
+ "AccordionTrigger",
30
+ "AccordionContent"
31
+ ],
32
+ "props": {},
33
+ "antiPatterns": [
34
+ {
35
+ "pattern": "Accordion without AccordionItem",
36
+ "reason": "Accordion requires AccordionItem as direct child",
37
+ "fix": "Always compose: Accordion > AccordionItem > AccordionTrigger + AccordionContent"
38
+ }
39
+ ],
40
+ "examples": [
41
+ {
42
+ "description": "Basic accordion",
43
+ "code": "<Accordion>\n <AccordionItem value=\"item-1\">\n <AccordionTrigger>Section Title</AccordionTrigger>\n <AccordionContent>Content goes here.</AccordionContent>\n </AccordionItem>\n</Accordion>"
44
+ }
45
+ ]
46
+ },
47
+ "Alert": {
48
+ "description": "Inline feedback message for info, success, warning, or danger states.",
49
+ "import": "import { Alert } from \"@usevyre/react\"",
50
+ "props": {
51
+ "variant": {
52
+ "type": "enum",
53
+ "values": [
54
+ "info",
55
+ "success",
56
+ "warning",
57
+ "danger"
58
+ ],
59
+ "default": "info",
60
+ "description": "Visual severity style"
61
+ },
62
+ "title": {
63
+ "type": "string",
64
+ "description": "Bold heading text inside the alert"
65
+ },
66
+ "onClose": {
67
+ "type": "function",
68
+ "description": "If provided, renders a close (×) button"
69
+ }
70
+ },
71
+ "antiPatterns": [
72
+ {
73
+ "pattern": "variant=\"error\"",
74
+ "reason": "No 'error' variant exists",
75
+ "fix": "Use variant=\"danger\""
76
+ },
77
+ {
78
+ "pattern": "variant=\"primary\"",
79
+ "reason": "Alert uses severity variants, not brand variants",
80
+ "fix": "Use variant=\"info\" | \"success\" | \"warning\" | \"danger\""
81
+ }
82
+ ],
83
+ "examples": [
84
+ {
85
+ "description": "Warning with close button",
86
+ "code": "<Alert variant=\"warning\" title=\"Heads up\" onClose={() => setOpen(false)}>\n This action cannot be undone.\n</Alert>"
87
+ },
88
+ {
89
+ "description": "Success state",
90
+ "code": "<Alert variant=\"success\" title=\"Saved!\">Your changes have been saved.</Alert>"
91
+ }
92
+ ]
93
+ },
94
+ "Avatar": {
95
+ "description": "User profile image with fallback initials or icon.",
96
+ "import": "import { Avatar } from \"@usevyre/react\"",
97
+ "props": {
98
+ "src": {
99
+ "type": "string",
100
+ "description": "Image URL. Falls back to `fallback` if not provided or fails to load."
101
+ },
102
+ "alt": {
103
+ "type": "string",
104
+ "default": "\"\"",
105
+ "description": "Alt text for the image"
106
+ },
107
+ "fallback": {
108
+ "type": "string",
109
+ "description": "Text or initials shown when image is absent"
110
+ },
111
+ "size": {
112
+ "type": "enum",
113
+ "values": [
114
+ "sm",
115
+ "md",
116
+ "lg",
117
+ "xl"
118
+ ],
119
+ "default": "md",
120
+ "description": "Avatar diameter"
121
+ },
122
+ "status": {
123
+ "type": "enum",
124
+ "values": [
125
+ "online",
126
+ "offline",
127
+ "busy",
128
+ "away"
129
+ ],
130
+ "description": "Optional status indicator dot"
131
+ }
132
+ },
133
+ "antiPatterns": [
134
+ {
135
+ "pattern": "size=\"xs\"",
136
+ "reason": "Minimum size is 'sm'",
137
+ "fix": "Use size=\"sm\""
138
+ },
139
+ {
140
+ "pattern": "size=\"2xl\"",
141
+ "reason": "Maximum size is 'xl'",
142
+ "fix": "Use size=\"xl\""
143
+ }
144
+ ],
145
+ "examples": [
146
+ {
147
+ "description": "Avatar with image and online status",
148
+ "code": "<Avatar src=\"/user.png\" alt=\"Jane Doe\" size=\"lg\" status=\"online\" />"
149
+ },
150
+ {
151
+ "description": "Fallback initials",
152
+ "code": "<Avatar fallback=\"JD\" size=\"md\" />"
153
+ }
154
+ ]
155
+ },
156
+ "Badge": {
157
+ "description": "Small label for status, category, or count. Use dot prop for live status indicator.",
158
+ "import": "import { Badge } from \"@usevyre/react\"",
159
+ "props": {
160
+ "variant": {
161
+ "type": "enum",
162
+ "values": [
163
+ "default",
164
+ "accent",
165
+ "teal",
166
+ "success",
167
+ "warning",
168
+ "danger"
169
+ ],
170
+ "default": "default",
171
+ "description": "Color style of the badge"
172
+ },
173
+ "dot": {
174
+ "type": "boolean",
175
+ "default": false,
176
+ "description": "Shows a pulsing status indicator dot"
177
+ }
178
+ },
179
+ "antiPatterns": [
180
+ {
181
+ "pattern": "variant=\"primary\"",
182
+ "reason": "Badge has no 'primary' variant",
183
+ "fix": "Use variant=\"accent\" for brand color"
184
+ },
185
+ {
186
+ "pattern": "variant=\"error\"",
187
+ "reason": "No 'error' variant exists",
188
+ "fix": "Use variant=\"danger\""
189
+ },
190
+ {
191
+ "pattern": "variant=\"info\"",
192
+ "reason": "No 'info' variant on Badge (use Alert for info messages)",
193
+ "fix": "Use variant=\"teal\" for info-like styling"
194
+ }
195
+ ],
196
+ "examples": [
197
+ {
198
+ "description": "Live status with dot",
199
+ "code": "<Badge variant=\"success\" dot>Online</Badge>"
200
+ },
201
+ {
202
+ "description": "Warning badge",
203
+ "code": "<Badge variant=\"warning\">Beta</Badge>"
204
+ },
205
+ {
206
+ "description": "Danger badge",
207
+ "code": "<Badge variant=\"danger\">Error</Badge>"
208
+ }
209
+ ]
210
+ },
211
+ "Breadcrumb": {
212
+ "description": "Navigation trail showing current page location in hierarchy.",
213
+ "import": "import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbSeparator } from \"@usevyre/react\"",
214
+ "subcomponents": [
215
+ "BreadcrumbItem",
216
+ "BreadcrumbLink",
217
+ "BreadcrumbSeparator"
218
+ ],
219
+ "props": {},
220
+ "antiPatterns": [
221
+ {
222
+ "pattern": "Using plain <a> tags inside Breadcrumb",
223
+ "reason": "Use BreadcrumbLink for correct styling and accessibility",
224
+ "fix": "Use BreadcrumbItem > BreadcrumbLink for each crumb"
225
+ }
226
+ ],
227
+ "examples": [
228
+ {
229
+ "description": "Basic breadcrumb",
230
+ "code": "<Breadcrumb>\n <BreadcrumbItem><BreadcrumbLink href=\"/\">Home</BreadcrumbLink></BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem><BreadcrumbLink href=\"/docs\">Docs</BreadcrumbLink></BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem aria-current=\"page\">Button</BreadcrumbItem>\n</Breadcrumb>"
231
+ }
232
+ ]
233
+ },
234
+ "Button": {
235
+ "description": "Triggers actions and navigation. The most commonly used interactive element.",
236
+ "import": "import { Button } from \"@usevyre/react\"",
237
+ "props": {
238
+ "variant": {
239
+ "type": "enum",
240
+ "values": [
241
+ "primary",
242
+ "secondary",
243
+ "ghost",
244
+ "accent",
245
+ "teal",
246
+ "danger"
247
+ ],
248
+ "default": "secondary",
249
+ "description": "Visual style. primary=high contrast CTA, secondary=bordered, ghost=minimal, accent=amber brand, teal=secondary accent, danger=destructive"
250
+ },
251
+ "size": {
252
+ "type": "enum",
253
+ "values": [
254
+ "sm",
255
+ "md",
256
+ "lg",
257
+ "icon"
258
+ ],
259
+ "default": "md",
260
+ "description": "Size scale. Use 'icon' for square icon-only buttons"
261
+ },
262
+ "loading": {
263
+ "type": "boolean",
264
+ "default": false,
265
+ "description": "Shows spinner and disables interaction"
266
+ },
267
+ "disabled": {
268
+ "type": "boolean",
269
+ "default": false,
270
+ "description": "Disables the button"
271
+ },
272
+ "as": {
273
+ "type": "React.ElementType",
274
+ "default": "\"button\"",
275
+ "description": "Render as different element (e.g. 'a' for link buttons)"
276
+ },
277
+ "leftIcon": {
278
+ "type": "ReactNode",
279
+ "description": "Icon rendered before the label"
280
+ },
281
+ "rightIcon": {
282
+ "type": "ReactNode",
283
+ "description": "Icon rendered after the label"
284
+ }
285
+ },
286
+ "accessibility": {
287
+ "notes": [
288
+ "Always add aria-label when using size='icon' (no visible text)"
289
+ ]
290
+ },
291
+ "antiPatterns": [
292
+ {
293
+ "pattern": "variant=\"blue\"",
294
+ "reason": "No 'blue' variant exists",
295
+ "fix": "Use variant=\"accent\" for brand amber, or variant=\"teal\" for teal"
296
+ },
297
+ {
298
+ "pattern": "size=\"xl\"",
299
+ "reason": "Maximum size is 'lg'",
300
+ "fix": "Use size=\"lg\""
301
+ },
302
+ {
303
+ "pattern": "color=\"...\"",
304
+ "reason": "No color prop exists on Button",
305
+ "fix": "Use variant prop instead"
306
+ },
307
+ {
308
+ "pattern": "icon={...}",
309
+ "reason": "No 'icon' prop for inserting icons",
310
+ "fix": "Use leftIcon={...} or rightIcon={...}"
311
+ },
312
+ {
313
+ "pattern": "size=\"icon\" without aria-label",
314
+ "reason": "Icon-only buttons have no visible text — screen readers need aria-label",
315
+ "fix": "Add aria-label describing the action"
316
+ }
317
+ ],
318
+ "examples": [
319
+ {
320
+ "description": "Primary CTA",
321
+ "code": "<Button variant=\"primary\">Get Started</Button>"
322
+ },
323
+ {
324
+ "description": "Large accent button",
325
+ "code": "<Button variant=\"accent\" size=\"lg\">Launch App</Button>"
326
+ },
327
+ {
328
+ "description": "Loading state",
329
+ "code": "<Button variant=\"danger\" loading>Deleting...</Button>"
330
+ },
331
+ {
332
+ "description": "Link button",
333
+ "code": "<Button as=\"a\" href=\"/docs\" variant=\"secondary\">Read Docs</Button>"
334
+ },
335
+ {
336
+ "description": "Icon-only button",
337
+ "code": "<Button variant=\"ghost\" size=\"icon\" aria-label=\"Close\">\n <X size={16} />\n</Button>"
338
+ }
339
+ ]
340
+ },
341
+ "Calendar": {
342
+ "description": "Date picker calendar widget for selecting single dates or ranges.",
343
+ "import": "import { Calendar } from \"@usevyre/react\"",
344
+ "props": {
345
+ "value": {
346
+ "type": "Date | null",
347
+ "description": "Currently selected date (controlled)"
348
+ },
349
+ "onChange": {
350
+ "type": "function",
351
+ "description": "Callback when a date is selected"
352
+ },
353
+ "disabled": {
354
+ "type": "boolean",
355
+ "default": false
356
+ }
357
+ },
358
+ "antiPatterns": [
359
+ {
360
+ "pattern": "Using Calendar for time selection",
361
+ "reason": "Calendar handles date only, not time",
362
+ "fix": "Combine with a separate time Input if time selection is needed"
363
+ }
364
+ ],
365
+ "examples": [
366
+ {
367
+ "description": "Controlled date picker",
368
+ "code": "const [date, setDate] = useState(null);\n<Calendar value={date} onChange={setDate} />"
369
+ }
370
+ ]
371
+ },
372
+ "Card": {
373
+ "description": "Content container with optional header, body, and footer sections.",
374
+ "import": "import { Card, CardHeader, CardBody, CardFooter } from \"@usevyre/react\"",
375
+ "subcomponents": [
376
+ "CardHeader",
377
+ "CardBody",
378
+ "CardFooter"
379
+ ],
380
+ "props": {
381
+ "variant": {
382
+ "type": "enum",
383
+ "values": [
384
+ "default",
385
+ "elevated",
386
+ "outlined",
387
+ "ghost",
388
+ "accent"
389
+ ],
390
+ "default": "default",
391
+ "description": "Visual style of the card"
392
+ },
393
+ "hoverable": {
394
+ "type": "boolean",
395
+ "default": false,
396
+ "description": "Adds hover lift effect"
397
+ },
398
+ "clickable": {
399
+ "type": "boolean",
400
+ "default": false,
401
+ "description": "Adds cursor pointer and active press feedback"
402
+ }
403
+ },
404
+ "antiPatterns": [
405
+ {
406
+ "pattern": "variant=\"primary\"",
407
+ "reason": "Card has no 'primary' variant",
408
+ "fix": "Use variant=\"elevated\" | \"outlined\" | \"ghost\" | \"accent\""
409
+ }
410
+ ],
411
+ "examples": [
412
+ {
413
+ "description": "Elevated card with sections",
414
+ "code": "<Card variant=\"elevated\">\n <CardHeader><Badge variant=\"teal\">New</Badge></CardHeader>\n <CardBody>\n <h3>Card Title</h3>\n <p>Description text.</p>\n </CardBody>\n <CardFooter>\n <Button variant=\"ghost\" size=\"sm\">Learn more</Button>\n </CardFooter>\n</Card>"
415
+ }
416
+ ]
417
+ },
418
+ "Checkbox": {
419
+ "description": "Binary toggle for boolean form values.",
420
+ "import": "import { Checkbox } from \"@usevyre/react\"",
421
+ "props": {
422
+ "size": {
423
+ "type": "enum",
424
+ "values": [
425
+ "sm",
426
+ "md"
427
+ ],
428
+ "default": "md"
429
+ },
430
+ "checked": {
431
+ "type": "boolean",
432
+ "description": "Controlled checked state"
433
+ },
434
+ "onChange": {
435
+ "type": "function",
436
+ "description": "Callback on change"
437
+ },
438
+ "disabled": {
439
+ "type": "boolean",
440
+ "default": false
441
+ },
442
+ "indeterminate": {
443
+ "type": "boolean",
444
+ "default": false,
445
+ "description": "Shows dash icon for partial selection state"
446
+ }
447
+ },
448
+ "antiPatterns": [
449
+ {
450
+ "pattern": "size=\"lg\"",
451
+ "reason": "Maximum size is 'md'",
452
+ "fix": "Use size=\"md\""
453
+ }
454
+ ],
455
+ "examples": [
456
+ {
457
+ "description": "Labeled checkbox",
458
+ "code": "<label style={{ display: 'flex', alignItems: 'center', gap: 'var(--vyre-spacing-2)' }}>\n <Checkbox checked={agreed} onChange={e => setAgreed(e.target.checked)} />\n I agree to the terms\n</label>"
459
+ }
460
+ ]
461
+ },
462
+ "Command": {
463
+ "description": "Command palette / search dialog. Use for search-first navigation or quick actions.",
464
+ "import": "import { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandDialog } from \"@usevyre/react\"",
465
+ "subcomponents": [
466
+ "CommandInput",
467
+ "CommandList",
468
+ "CommandEmpty",
469
+ "CommandGroup",
470
+ "CommandItem",
471
+ "CommandDialog"
472
+ ],
473
+ "props": {},
474
+ "antiPatterns": [
475
+ {
476
+ "pattern": "Using Input type=\"search\" for search UI",
477
+ "reason": "Command component is the correct pattern for search-first UI",
478
+ "fix": "Use Command + CommandInput + CommandList + CommandItem"
479
+ }
480
+ ],
481
+ "examples": [
482
+ {
483
+ "description": "Basic command palette",
484
+ "code": "<Command>\n <CommandInput placeholder=\"Search...\" />\n <CommandList>\n <CommandEmpty>No results found.</CommandEmpty>\n <CommandGroup heading=\"Suggestions\">\n <CommandItem onSelect={() => handleSelect('dashboard')}>Dashboard</CommandItem>\n <CommandItem onSelect={() => handleSelect('settings')}>Settings</CommandItem>\n </CommandGroup>\n </CommandList>\n</Command>"
485
+ }
486
+ ]
487
+ },
488
+ "DropdownMenu": {
489
+ "description": "Contextual menu triggered by a button. Supports items, separators, checkbox items, radio groups, and sub-menus.",
490
+ "import": "import { DropdownMenu, DropdownItem, DropdownSeparator, DropdownCheckboxItem, DropdownRadioGroup, DropdownRadioItem, DropdownSub } from \"@usevyre/react\"",
491
+ "subcomponents": [
492
+ "DropdownItem",
493
+ "DropdownSeparator",
494
+ "DropdownCheckboxItem",
495
+ "DropdownRadioGroup",
496
+ "DropdownRadioItem",
497
+ "DropdownSub"
498
+ ],
499
+ "props": {
500
+ "trigger": {
501
+ "type": "ReactElement",
502
+ "description": "Element that opens the dropdown when clicked"
503
+ }
504
+ },
505
+ "itemProps": {
506
+ "variant": {
507
+ "type": "enum",
508
+ "values": [
509
+ "default",
510
+ "danger"
511
+ ],
512
+ "default": "default",
513
+ "description": "Use 'danger' for destructive actions"
514
+ }
515
+ },
516
+ "antiPatterns": [
517
+ {
518
+ "pattern": "DropdownItem variant=\"primary\"",
519
+ "reason": "DropdownItem only has 'default' and 'danger' variants",
520
+ "fix": "Use variant=\"danger\" for destructive items only"
521
+ }
522
+ ],
523
+ "examples": [
524
+ {
525
+ "description": "Dropdown with danger item",
526
+ "code": "<DropdownMenu trigger={<Button variant=\"secondary\">Options</Button>}>\n <DropdownItem onSelect={() => handleEdit()}>Edit</DropdownItem>\n <DropdownItem onSelect={() => handleDuplicate()}>Duplicate</DropdownItem>\n <DropdownSeparator />\n <DropdownItem variant=\"danger\" onSelect={() => handleDelete()}>Delete</DropdownItem>\n</DropdownMenu>"
527
+ }
528
+ ]
529
+ },
530
+ "Field": {
531
+ "description": "Form field wrapper providing label, hint text, and validation state for Input or Textarea.",
532
+ "import": "import { Field, Input, Textarea } from \"@usevyre/react\"",
533
+ "props": {
534
+ "label": {
535
+ "type": "string",
536
+ "description": "Visible field label"
537
+ },
538
+ "hint": {
539
+ "type": "string",
540
+ "description": "Helper or error text below the input"
541
+ },
542
+ "state": {
543
+ "type": "enum",
544
+ "values": [
545
+ "idle",
546
+ "error",
547
+ "success",
548
+ "warning"
549
+ ],
550
+ "default": "idle",
551
+ "description": "Validation state — affects border color and hint text color"
552
+ },
553
+ "required": {
554
+ "type": "boolean",
555
+ "default": false,
556
+ "description": "Shows required indicator"
557
+ }
558
+ },
559
+ "antiPatterns": [
560
+ {
561
+ "pattern": "Applying state prop directly to Input",
562
+ "reason": "state belongs on Field, not on the Input itself",
563
+ "fix": "Wrap Input in <Field state=\"error\"> to apply validation styling"
564
+ }
565
+ ],
566
+ "examples": [
567
+ {
568
+ "description": "Error state field",
569
+ "code": "<Field label=\"Email\" state=\"error\" hint=\"Invalid email format\">\n <Input type=\"email\" placeholder=\"you@example.com\" />\n</Field>"
570
+ },
571
+ {
572
+ "description": "Search field with left icon",
573
+ "code": "<Field label=\"Search\">\n <Input leftElement={<SearchIcon />} placeholder=\"Search...\" />\n</Field>"
574
+ }
575
+ ]
576
+ },
577
+ "Input": {
578
+ "description": "Text input field. Wrap in Field for labels and validation. Use leftElement/rightElement for icons.",
579
+ "import": "import { Input } from \"@usevyre/react\"",
580
+ "props": {
581
+ "size": {
582
+ "type": "enum",
583
+ "values": [
584
+ "sm",
585
+ "md",
586
+ "lg"
587
+ ],
588
+ "default": "md",
589
+ "description": "Height and text size scale. Note: 'icon' size is NOT valid for Input"
590
+ },
591
+ "leftElement": {
592
+ "type": "ReactNode",
593
+ "description": "Icon or element rendered inside the input on the left"
594
+ },
595
+ "rightElement": {
596
+ "type": "ReactNode",
597
+ "description": "Icon or element rendered inside the input on the right"
598
+ }
599
+ },
600
+ "antiPatterns": [
601
+ {
602
+ "pattern": "size=\"icon\"",
603
+ "reason": "'icon' size is only valid for Button, not Input",
604
+ "fix": "Use size=\"sm\" | \"md\" | \"lg\""
605
+ },
606
+ {
607
+ "pattern": "type=\"search\" for search UI",
608
+ "reason": "Use Command component for search-first interfaces",
609
+ "fix": "Import Command from @usevyre/react for search palettes"
610
+ }
611
+ ],
612
+ "examples": [
613
+ {
614
+ "description": "Password input with icon",
615
+ "code": "<Input type=\"password\" rightElement={<EyeIcon />} placeholder=\"Password\" />"
616
+ }
617
+ ]
618
+ },
619
+ "Label": {
620
+ "description": "Accessible form label. Associate with input via htmlFor.",
621
+ "import": "import { Label } from \"@usevyre/react\"",
622
+ "props": {
623
+ "htmlFor": {
624
+ "type": "string",
625
+ "description": "ID of the associated input element"
626
+ },
627
+ "required": {
628
+ "type": "boolean",
629
+ "default": false
630
+ }
631
+ },
632
+ "examples": [
633
+ {
634
+ "description": "Label with input",
635
+ "code": "<Label htmlFor=\"email\">Email address</Label>\n<Input id=\"email\" type=\"email\" />"
636
+ }
637
+ ]
638
+ },
639
+ "Modal": {
640
+ "description": "Dialog overlay for confirmations, forms, or focused content.",
641
+ "import": "import { Modal, ModalHeader, ModalBody, ModalFooter } from \"@usevyre/react\"",
642
+ "subcomponents": [
643
+ "ModalHeader",
644
+ "ModalBody",
645
+ "ModalFooter"
646
+ ],
647
+ "props": {
648
+ "open": {
649
+ "type": "boolean",
650
+ "description": "Controls visibility (controlled mode)"
651
+ },
652
+ "onClose": {
653
+ "type": "function",
654
+ "description": "Called when modal is dismissed"
655
+ },
656
+ "size": {
657
+ "type": "enum",
658
+ "values": [
659
+ "sm",
660
+ "md",
661
+ "lg",
662
+ "full"
663
+ ],
664
+ "default": "md",
665
+ "description": "Width of the modal dialog"
666
+ },
667
+ "title": {
668
+ "type": "string",
669
+ "description": "Accessible dialog title (also shown as heading)"
670
+ }
671
+ },
672
+ "antiPatterns": [
673
+ {
674
+ "pattern": "size=\"xl\"",
675
+ "reason": "Maximum size is 'full'",
676
+ "fix": "Use size=\"lg\" or size=\"full\""
677
+ }
678
+ ],
679
+ "examples": [
680
+ {
681
+ "description": "Confirmation modal",
682
+ "code": "<Modal open={isOpen} onClose={() => setIsOpen(false)} title=\"Confirm Delete\" size=\"sm\">\n <ModalBody>Are you sure you want to delete this item?</ModalBody>\n <ModalFooter>\n <Button variant=\"ghost\" onClick={() => setIsOpen(false)}>Cancel</Button>\n <Button variant=\"danger\" onClick={handleDelete}>Delete</Button>\n </ModalFooter>\n</Modal>"
683
+ }
684
+ ]
685
+ },
686
+ "Pagination": {
687
+ "description": "Page navigation for paginated lists or tables.",
688
+ "import": "import { Pagination } from \"@usevyre/react\"",
689
+ "props": {
690
+ "page": {
691
+ "type": "number",
692
+ "description": "Current page (1-indexed)"
693
+ },
694
+ "total": {
695
+ "type": "number",
696
+ "description": "Total number of pages"
697
+ },
698
+ "onChange": {
699
+ "type": "function",
700
+ "description": "Called with new page number when user navigates"
701
+ }
702
+ },
703
+ "examples": [
704
+ {
705
+ "description": "Basic pagination",
706
+ "code": "<Pagination page={currentPage} total={totalPages} onChange={setCurrentPage} />"
707
+ }
708
+ ]
709
+ },
710
+ "Popover": {
711
+ "description": "Floating content panel anchored to a trigger element. For simple labels use Tooltip instead.",
712
+ "import": "import { Popover } from \"@usevyre/react\"",
713
+ "props": {
714
+ "trigger": {
715
+ "type": "ReactElement",
716
+ "description": "Element that opens the popover"
717
+ },
718
+ "placement": {
719
+ "type": "enum",
720
+ "values": [
721
+ "top",
722
+ "top-start",
723
+ "top-end",
724
+ "bottom",
725
+ "bottom-start",
726
+ "bottom-end",
727
+ "left",
728
+ "left-start",
729
+ "left-end",
730
+ "right",
731
+ "right-start",
732
+ "right-end"
733
+ ],
734
+ "default": "bottom",
735
+ "description": "Preferred placement relative to trigger"
736
+ },
737
+ "open": {
738
+ "type": "boolean",
739
+ "description": "Controlled open state"
740
+ },
741
+ "onOpenChange": {
742
+ "type": "function",
743
+ "description": "Callback when open state changes"
744
+ },
745
+ "closeOnOutside": {
746
+ "type": "boolean",
747
+ "default": true,
748
+ "description": "Close when clicking outside"
749
+ }
750
+ },
751
+ "antiPatterns": [
752
+ {
753
+ "pattern": "placement=\"top-center\"",
754
+ "reason": "No 'top-center' — center alignment is the default when no suffix is given",
755
+ "fix": "Use placement=\"top\" for centered placement"
756
+ }
757
+ ],
758
+ "examples": [
759
+ {
760
+ "description": "Popover with custom content",
761
+ "code": "<Popover trigger={<Button variant=\"secondary\">More info</Button>} placement=\"bottom-start\">\n <div style={{ padding: 'var(--vyre-spacing-4)' }}>\n <p>Detailed information here.</p>\n </div>\n</Popover>"
762
+ }
763
+ ]
764
+ },
765
+ "Progress": {
766
+ "description": "Visual progress indicator for tasks, uploads, or completion status.",
767
+ "import": "import { Progress } from \"@usevyre/react\"",
768
+ "props": {
769
+ "value": {
770
+ "type": "number",
771
+ "description": "Progress value (0–100)"
772
+ },
773
+ "size": {
774
+ "type": "enum",
775
+ "values": [
776
+ "sm",
777
+ "md",
778
+ "lg"
779
+ ],
780
+ "default": "md",
781
+ "description": "Height of the progress bar"
782
+ },
783
+ "variant": {
784
+ "type": "enum",
785
+ "values": [
786
+ "default",
787
+ "accent",
788
+ "teal",
789
+ "success",
790
+ "danger"
791
+ ],
792
+ "default": "default",
793
+ "description": "Color variant"
794
+ }
795
+ },
796
+ "antiPatterns": [
797
+ {
798
+ "pattern": "value > 100",
799
+ "reason": "Value is clamped to 0–100",
800
+ "fix": "Normalize your value to 0–100 range before passing"
801
+ }
802
+ ],
803
+ "examples": [
804
+ {
805
+ "description": "Upload progress",
806
+ "code": "<Progress value={uploadPercent} variant=\"accent\" size=\"sm\" />"
807
+ }
808
+ ]
809
+ },
810
+ "Select": {
811
+ "description": "Dropdown for selecting one option from a list.",
812
+ "import": "import { Select } from \"@usevyre/react\"",
813
+ "props": {
814
+ "options": {
815
+ "type": "SelectOption[]",
816
+ "description": "Array of { value: string, label: string } objects"
817
+ },
818
+ "value": {
819
+ "type": "string",
820
+ "description": "Controlled selected value"
821
+ },
822
+ "onChange": {
823
+ "type": "function",
824
+ "description": "Called with new value string on selection"
825
+ },
826
+ "size": {
827
+ "type": "enum",
828
+ "values": [
829
+ "sm",
830
+ "md",
831
+ "lg"
832
+ ],
833
+ "default": "md"
834
+ },
835
+ "placeholder": {
836
+ "type": "string",
837
+ "description": "Placeholder text when no value is selected"
838
+ },
839
+ "disabled": {
840
+ "type": "boolean",
841
+ "default": false
842
+ }
843
+ },
844
+ "antiPatterns": [
845
+ {
846
+ "pattern": "Passing strings directly as children",
847
+ "reason": "Select uses options prop, not children",
848
+ "fix": "Pass options={[{ value: 'a', label: 'Option A' }]}"
849
+ }
850
+ ],
851
+ "examples": [
852
+ {
853
+ "description": "Controlled select",
854
+ "code": "<Select\n options={[{ value: 'react', label: 'React' }, { value: 'vue', label: 'Vue' }]}\n value={framework}\n onChange={setFramework}\n placeholder=\"Choose framework\"\n/>"
855
+ }
856
+ ]
857
+ },
858
+ "Separator": {
859
+ "description": "Horizontal or vertical divider line.",
860
+ "import": "import { Separator } from \"@usevyre/react\"",
861
+ "props": {
862
+ "orientation": {
863
+ "type": "enum",
864
+ "values": [
865
+ "horizontal",
866
+ "vertical"
867
+ ],
868
+ "default": "horizontal"
869
+ }
870
+ },
871
+ "examples": [
872
+ {
873
+ "description": "Horizontal separator",
874
+ "code": "<Separator />"
875
+ },
876
+ {
877
+ "description": "Vertical separator",
878
+ "code": "<Separator orientation=\"vertical\" />"
879
+ }
880
+ ]
881
+ },
882
+ "Sheet": {
883
+ "description": "Side panel (drawer) that slides in from the edge. For forms, detail views, or settings.",
884
+ "import": "import { Sheet, SheetHeader, SheetBody, SheetFooter } from \"@usevyre/react\"",
885
+ "subcomponents": [
886
+ "SheetHeader",
887
+ "SheetBody",
888
+ "SheetFooter"
889
+ ],
890
+ "props": {
891
+ "open": {
892
+ "type": "boolean",
893
+ "description": "Controls visibility"
894
+ },
895
+ "onClose": {
896
+ "type": "function",
897
+ "description": "Called when sheet is dismissed"
898
+ },
899
+ "size": {
900
+ "type": "enum",
901
+ "values": [
902
+ "sm",
903
+ "md",
904
+ "lg",
905
+ "full"
906
+ ],
907
+ "default": "md",
908
+ "description": "Width of the sheet panel"
909
+ },
910
+ "side": {
911
+ "type": "enum",
912
+ "values": [
913
+ "left",
914
+ "right"
915
+ ],
916
+ "default": "right",
917
+ "description": "Which edge the sheet slides from"
918
+ },
919
+ "title": {
920
+ "type": "string",
921
+ "description": "Accessible panel title"
922
+ }
923
+ },
924
+ "examples": [
925
+ {
926
+ "description": "Settings sheet from the right",
927
+ "code": "<Sheet open={isOpen} onClose={() => setIsOpen(false)} title=\"Settings\" side=\"right\">\n <SheetBody>Settings content here.</SheetBody>\n <SheetFooter>\n <Button variant=\"accent\">Save</Button>\n </SheetFooter>\n</Sheet>"
928
+ }
929
+ ]
930
+ },
931
+ "Sidebar": {
932
+ "description": "App navigation sidebar. Use AppLayout as the root layout wrapper.",
933
+ "import": "import { AppLayout, Sidebar, SidebarHeader, SidebarContent, SidebarSection, SidebarItem, SidebarFooter } from \"@usevyre/react\"",
934
+ "subcomponents": [
935
+ "AppLayout",
936
+ "SidebarHeader",
937
+ "SidebarContent",
938
+ "SidebarSection",
939
+ "SidebarItem",
940
+ "SidebarFooter"
941
+ ],
942
+ "props": {
943
+ "variant": {
944
+ "type": "enum",
945
+ "values": [
946
+ "default",
947
+ "floating"
948
+ ],
949
+ "default": "default"
950
+ }
951
+ },
952
+ "examples": [
953
+ {
954
+ "description": "App layout with sidebar",
955
+ "code": "<AppLayout>\n <Sidebar>\n <SidebarHeader>Logo</SidebarHeader>\n <SidebarContent>\n <SidebarSection heading=\"Main\">\n <SidebarItem href=\"/\" active>Dashboard</SidebarItem>\n <SidebarItem href=\"/settings\">Settings</SidebarItem>\n </SidebarSection>\n </SidebarContent>\n <SidebarFooter><Avatar fallback=\"JD\" size=\"sm\" /></SidebarFooter>\n </Sidebar>\n <main>Page content</main>\n</AppLayout>"
956
+ }
957
+ ]
958
+ },
959
+ "Skeleton": {
960
+ "description": "Loading placeholder that mimics the shape of content while data loads.",
961
+ "import": "import { Skeleton } from \"@usevyre/react\"",
962
+ "props": {
963
+ "variant": {
964
+ "type": "enum",
965
+ "values": [
966
+ "rect",
967
+ "circle",
968
+ "text"
969
+ ],
970
+ "default": "rect",
971
+ "description": "Shape of the skeleton. 'circle' for avatars, 'text' for text lines, 'rect' for blocks"
972
+ },
973
+ "width": {
974
+ "type": "string | number",
975
+ "description": "Width (e.g. '200px' or '100%')"
976
+ },
977
+ "height": {
978
+ "type": "string | number",
979
+ "description": "Height (e.g. '20px' or 40)"
980
+ }
981
+ },
982
+ "examples": [
983
+ {
984
+ "description": "Avatar skeleton",
985
+ "code": "<Skeleton variant=\"circle\" width={40} height={40} />"
986
+ },
987
+ {
988
+ "description": "Text line skeletons",
989
+ "code": "<Skeleton variant=\"text\" width=\"100%\" />\n<Skeleton variant=\"text\" width=\"60%\" />"
990
+ }
991
+ ]
992
+ },
993
+ "Slider": {
994
+ "description": "Range input for selecting a numeric value within a range.",
995
+ "import": "import { Slider } from \"@usevyre/react\"",
996
+ "props": {
997
+ "value": {
998
+ "type": "number",
999
+ "description": "Controlled value"
1000
+ },
1001
+ "onChange": {
1002
+ "type": "function",
1003
+ "description": "Called with new numeric value"
1004
+ },
1005
+ "min": {
1006
+ "type": "number",
1007
+ "default": 0
1008
+ },
1009
+ "max": {
1010
+ "type": "number",
1011
+ "default": 100
1012
+ },
1013
+ "step": {
1014
+ "type": "number",
1015
+ "default": 1
1016
+ },
1017
+ "size": {
1018
+ "type": "enum",
1019
+ "values": [
1020
+ "sm",
1021
+ "md"
1022
+ ],
1023
+ "default": "md"
1024
+ },
1025
+ "disabled": {
1026
+ "type": "boolean",
1027
+ "default": false
1028
+ }
1029
+ },
1030
+ "examples": [
1031
+ {
1032
+ "description": "Volume slider",
1033
+ "code": "<Slider value={volume} onChange={setVolume} min={0} max={100} step={5} />"
1034
+ }
1035
+ ]
1036
+ },
1037
+ "Switch": {
1038
+ "description": "Toggle switch for boolean on/off settings.",
1039
+ "import": "import { Switch } from \"@usevyre/react\"",
1040
+ "props": {
1041
+ "checked": {
1042
+ "type": "boolean",
1043
+ "description": "Controlled checked state"
1044
+ },
1045
+ "onChange": {
1046
+ "type": "function",
1047
+ "description": "Called with new boolean value"
1048
+ },
1049
+ "size": {
1050
+ "type": "enum",
1051
+ "values": [
1052
+ "sm",
1053
+ "md"
1054
+ ],
1055
+ "default": "md"
1056
+ },
1057
+ "disabled": {
1058
+ "type": "boolean",
1059
+ "default": false
1060
+ }
1061
+ },
1062
+ "examples": [
1063
+ {
1064
+ "description": "Notifications toggle",
1065
+ "code": "<label style={{ display: 'flex', alignItems: 'center', gap: 'var(--vyre-spacing-2)' }}>\n <Switch checked={notifications} onChange={setNotifications} />\n Enable notifications\n</label>"
1066
+ }
1067
+ ]
1068
+ },
1069
+ "Table": {
1070
+ "description": "Data table with optional sorting. Compose with TableHeader, TableRow, TableCell.",
1071
+ "import": "import { Table, TableHead, TableBody, TableRow, TableHeader, TableCell } from \"@usevyre/react\"",
1072
+ "subcomponents": [
1073
+ "TableHead",
1074
+ "TableBody",
1075
+ "TableRow",
1076
+ "TableHeader",
1077
+ "TableCell"
1078
+ ],
1079
+ "props": {},
1080
+ "examples": [
1081
+ {
1082
+ "description": "Basic data table",
1083
+ "code": "<Table>\n <TableHead>\n <TableRow>\n <TableHeader>Name</TableHeader>\n <TableHeader>Status</TableHeader>\n </TableRow>\n </TableHead>\n <TableBody>\n <TableRow>\n <TableCell>Alice</TableCell>\n <TableCell><Badge variant=\"success\">Active</Badge></TableCell>\n </TableRow>\n </TableBody>\n</Table>"
1084
+ }
1085
+ ]
1086
+ },
1087
+ "Tabs": {
1088
+ "description": "Tabbed navigation for switching between content panels.",
1089
+ "import": "import { Tabs, TabList, Tab, TabPanels, TabPanel } from \"@usevyre/react\"",
1090
+ "subcomponents": [
1091
+ "TabList",
1092
+ "Tab",
1093
+ "TabPanels",
1094
+ "TabPanel"
1095
+ ],
1096
+ "props": {
1097
+ "defaultIndex": {
1098
+ "type": "number",
1099
+ "default": 0,
1100
+ "description": "Index of the initially active tab (uncontrolled)"
1101
+ },
1102
+ "index": {
1103
+ "type": "number",
1104
+ "description": "Controlled active tab index"
1105
+ },
1106
+ "onChange": {
1107
+ "type": "function",
1108
+ "description": "Called with new index when tab changes"
1109
+ }
1110
+ },
1111
+ "examples": [
1112
+ {
1113
+ "description": "Basic tabs",
1114
+ "code": "<Tabs defaultIndex={0}>\n <TabList>\n <Tab>Overview</Tab>\n <Tab>Settings</Tab>\n </TabList>\n <TabPanels>\n <TabPanel>Overview content</TabPanel>\n <TabPanel>Settings content</TabPanel>\n </TabPanels>\n</Tabs>"
1115
+ }
1116
+ ]
1117
+ },
1118
+ "Toast": {
1119
+ "description": "Transient notification. Use the useToast hook to trigger toasts imperatively.",
1120
+ "import": "import { useToast, ToastProvider } from \"@usevyre/react\"",
1121
+ "props": {
1122
+ "variant": {
1123
+ "type": "enum",
1124
+ "values": [
1125
+ "default",
1126
+ "success",
1127
+ "warning",
1128
+ "danger"
1129
+ ],
1130
+ "default": "default",
1131
+ "description": "Color and icon of the toast"
1132
+ },
1133
+ "title": {
1134
+ "type": "string",
1135
+ "description": "Bold heading text"
1136
+ },
1137
+ "description": {
1138
+ "type": "string",
1139
+ "description": "Supporting detail text"
1140
+ },
1141
+ "duration": {
1142
+ "type": "number",
1143
+ "default": 4000,
1144
+ "description": "Auto-dismiss time in milliseconds"
1145
+ }
1146
+ },
1147
+ "antiPatterns": [
1148
+ {
1149
+ "pattern": "Rendering <Toast> directly in JSX",
1150
+ "reason": "Toast is triggered via the useToast hook, not rendered directly",
1151
+ "fix": "Use: const { toast } = useToast(); then toast({ title, variant })"
1152
+ },
1153
+ {
1154
+ "pattern": "variant=\"error\"",
1155
+ "reason": "No 'error' variant",
1156
+ "fix": "Use variant=\"danger\""
1157
+ },
1158
+ {
1159
+ "pattern": "variant=\"info\"",
1160
+ "reason": "No 'info' variant on Toast",
1161
+ "fix": "Use variant=\"default\""
1162
+ }
1163
+ ],
1164
+ "examples": [
1165
+ {
1166
+ "description": "Trigger a success toast",
1167
+ "code": "const { toast } = useToast();\n\n<Button onClick={() => toast({ title: 'Saved!', variant: 'success', duration: 3000 })}>\n Save\n</Button>"
1168
+ },
1169
+ {
1170
+ "description": "Setup: wrap app with ToastProvider",
1171
+ "code": "<ToastProvider>\n <App />\n</ToastProvider>"
1172
+ }
1173
+ ]
1174
+ },
1175
+ "Tooltip": {
1176
+ "description": "Short label that appears on hover/focus. For rich content use Popover instead.",
1177
+ "import": "import { Tooltip } from \"@usevyre/react\"",
1178
+ "props": {
1179
+ "content": {
1180
+ "type": "string | ReactNode",
1181
+ "description": "Text or element shown in the tooltip"
1182
+ },
1183
+ "placement": {
1184
+ "type": "enum",
1185
+ "values": [
1186
+ "top",
1187
+ "bottom",
1188
+ "left",
1189
+ "right"
1190
+ ],
1191
+ "default": "top"
1192
+ },
1193
+ "delay": {
1194
+ "type": "number",
1195
+ "default": 300,
1196
+ "description": "Delay in ms before tooltip appears"
1197
+ }
1198
+ },
1199
+ "antiPatterns": [
1200
+ {
1201
+ "pattern": "Using Tooltip for rich content (forms, buttons, etc.)",
1202
+ "reason": "Tooltip is for short text labels only",
1203
+ "fix": "Use Popover for rich interactive content"
1204
+ }
1205
+ ],
1206
+ "examples": [
1207
+ {
1208
+ "description": "Tooltip on an icon button",
1209
+ "code": "<Tooltip content=\"Close dialog\" placement=\"bottom\">\n <Button variant=\"ghost\" size=\"icon\" aria-label=\"Close\">\n <X size={16} />\n </Button>\n</Tooltip>"
1210
+ }
1211
+ ]
1212
+ },
1213
+ "Typography": {
1214
+ "description": "Text rendering components with semantic scale. Includes Text, Heading, Lead, Code, Blockquote.",
1215
+ "import": "import { Text, Heading, Lead, Code, Blockquote } from \"@usevyre/react\"",
1216
+ "subcomponents": [
1217
+ "Text",
1218
+ "Heading",
1219
+ "Lead",
1220
+ "Code",
1221
+ "Blockquote"
1222
+ ],
1223
+ "textProps": {
1224
+ "size": {
1225
+ "type": "enum",
1226
+ "values": [
1227
+ "xs",
1228
+ "sm",
1229
+ "md",
1230
+ "lg",
1231
+ "xl"
1232
+ ],
1233
+ "default": "md"
1234
+ }
1235
+ },
1236
+ "headingProps": {
1237
+ "size": {
1238
+ "type": "enum",
1239
+ "values": [
1240
+ "xs",
1241
+ "sm",
1242
+ "md",
1243
+ "lg",
1244
+ "xl",
1245
+ "2xl",
1246
+ "3xl"
1247
+ ],
1248
+ "default": "lg"
1249
+ },
1250
+ "as": {
1251
+ "type": "enum",
1252
+ "values": [
1253
+ "h1",
1254
+ "h2",
1255
+ "h3",
1256
+ "h4",
1257
+ "h5",
1258
+ "h6"
1259
+ ],
1260
+ "default": "h2"
1261
+ }
1262
+ },
1263
+ "antiPatterns": [
1264
+ {
1265
+ "pattern": "Using raw <h1>, <p> tags instead of Typography components",
1266
+ "reason": "Typography components apply the correct token-based styles",
1267
+ "fix": "Use <Heading>, <Text>, <Lead> from @usevyre/react"
1268
+ }
1269
+ ],
1270
+ "examples": [
1271
+ {
1272
+ "description": "Page heading and body text",
1273
+ "code": "<Heading size=\"2xl\" as=\"h1\">Dashboard</Heading>\n<Lead>Welcome back. Here's what's happening today.</Lead>\n<Text size=\"sm\" style={{ color: 'var(--vyre-color-semantic-text-muted)' }}>Last updated 5 minutes ago.</Text>"
1274
+ }
1275
+ ]
1276
+ }
1277
+ }
1278
+ }