@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.
- package/dist/anti-patterns.json +222 -0
- package/dist/cheat-sheets/accordion.md +25 -0
- package/dist/cheat-sheets/alert.md +35 -0
- package/dist/cheat-sheets/avatar.md +34 -0
- package/dist/cheat-sheets/badge.md +41 -0
- package/dist/cheat-sheets/breadcrumb.md +26 -0
- package/dist/cheat-sheets/button.md +63 -0
- package/dist/cheat-sheets/calendar.md +27 -0
- package/dist/cheat-sheets/card.md +37 -0
- package/dist/cheat-sheets/checkbox.md +32 -0
- package/dist/cheat-sheets/command.md +29 -0
- package/dist/cheat-sheets/dropdownmenu.md +25 -0
- package/dist/cheat-sheets/field.md +36 -0
- package/dist/cheat-sheets/index.md +34 -0
- package/dist/cheat-sheets/input.md +28 -0
- package/dist/cheat-sheets/label.md +22 -0
- package/dist/cheat-sheets/modal.md +33 -0
- package/dist/cheat-sheets/pagination.md +15 -0
- package/dist/cheat-sheets/popover.md +32 -0
- package/dist/cheat-sheets/progress.md +27 -0
- package/dist/cheat-sheets/select.md +32 -0
- package/dist/cheat-sheets/separator.md +26 -0
- package/dist/cheat-sheets/sheet.md +28 -0
- package/dist/cheat-sheets/sidebar.md +33 -0
- package/dist/cheat-sheets/skeleton.md +27 -0
- package/dist/cheat-sheets/slider.md +22 -0
- package/dist/cheat-sheets/switch.md +26 -0
- package/dist/cheat-sheets/table.md +28 -0
- package/dist/cheat-sheets/tabs.md +24 -0
- package/dist/cheat-sheets/toast.md +41 -0
- package/dist/cheat-sheets/tooltip.md +30 -0
- package/dist/cheat-sheets/typography.md +22 -0
- package/dist/claude-context.md +716 -40
- package/dist/copilot-instructions.md +716 -40
- package/dist/cursor-rules.md +255 -261
- package/dist/full-context.md +715 -40
- package/dist/index.js +5054 -584
- package/dist/schema.json +1278 -0
- package/dist/version-info.json +233 -0
- package/dist/windsurf-rules.md +716 -40
- package/package.json +6 -2
package/dist/claude-context.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# useVyre Design System Context
|
|
2
|
+
# Version: 0.2.0
|
|
2
3
|
|
|
3
4
|
You are working in a codebase that uses the useVyre design system.
|
|
4
5
|
Follow the rules below strictly when writing any UI code.
|
|
5
6
|
|
|
6
7
|
# useVyre Design System — AI Context
|
|
7
|
-
# Version: 0.
|
|
8
|
+
# Version: 0.2.0
|
|
8
9
|
# Include this file in your AI agent's system prompt, .cursor/rules, or CLAUDE.md
|
|
9
10
|
# Source: https://usevyre.com/ai-context
|
|
10
11
|
|
|
@@ -156,35 +157,87 @@ Examples:
|
|
|
156
157
|
|
|
157
158
|
## Component API Reference
|
|
158
159
|
|
|
159
|
-
###
|
|
160
|
+
### Accordion
|
|
161
|
+
|
|
162
|
+
Vertically stacked collapsible sections. Compose with AccordionItem, AccordionTrigger, AccordionContent.
|
|
160
163
|
|
|
161
164
|
```tsx
|
|
162
|
-
import {
|
|
165
|
+
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from "@usevyre/react"
|
|
166
|
+
|
|
167
|
+
// Examples:
|
|
168
|
+
<Accordion>
|
|
169
|
+
<AccordionItem value="item-1">
|
|
170
|
+
<AccordionTrigger>Section Title</AccordionTrigger>
|
|
171
|
+
<AccordionContent>Content goes here.</AccordionContent>
|
|
172
|
+
</AccordionItem>
|
|
173
|
+
</Accordion>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Common mistakes:**
|
|
177
|
+
- ❌ `Accordion without AccordionItem` → Always compose: Accordion > AccordionItem > AccordionTrigger + AccordionContent
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
### Alert
|
|
182
|
+
|
|
183
|
+
Inline feedback message for info, success, warning, or danger states.
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
import { Alert } from "@usevyre/react"
|
|
163
187
|
|
|
164
188
|
// Props:
|
|
165
|
-
// variant
|
|
166
|
-
//
|
|
167
|
-
//
|
|
168
|
-
// disabled = boolean
|
|
169
|
-
// as = React.ElementType (default: "button")
|
|
170
|
-
// leftIcon = ReactNode
|
|
171
|
-
// rightIcon = ReactNode
|
|
189
|
+
// variant = "info" | "success" | "warning" | "danger" (default: info)
|
|
190
|
+
// title = string
|
|
191
|
+
// onClose = function
|
|
172
192
|
|
|
173
193
|
// Examples:
|
|
174
|
-
<
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
<
|
|
194
|
+
<Alert variant="warning" title="Heads up" onClose={() => setOpen(false)}>
|
|
195
|
+
This action cannot be undone.
|
|
196
|
+
</Alert>
|
|
197
|
+
<Alert variant="success" title="Saved!">Your changes have been saved.</Alert>
|
|
178
198
|
```
|
|
179
199
|
|
|
200
|
+
**Common mistakes:**
|
|
201
|
+
- ❌ `variant="error"` → Use variant="danger"
|
|
202
|
+
- ❌ `variant="primary"` → Use variant="info" | "success" | "warning" | "danger"
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
### Avatar
|
|
207
|
+
|
|
208
|
+
User profile image with fallback initials or icon.
|
|
209
|
+
|
|
210
|
+
```tsx
|
|
211
|
+
import { Avatar } from "@usevyre/react"
|
|
212
|
+
|
|
213
|
+
// Props:
|
|
214
|
+
// src = string
|
|
215
|
+
// alt = string (default: "")
|
|
216
|
+
// fallback = string
|
|
217
|
+
// size = "sm" | "md" | "lg" | "xl" (default: md)
|
|
218
|
+
// status = "online" | "offline" | "busy" | "away"
|
|
219
|
+
|
|
220
|
+
// Examples:
|
|
221
|
+
<Avatar src="/user.png" alt="Jane Doe" size="lg" status="online" />
|
|
222
|
+
<Avatar fallback="JD" size="md" />
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**Common mistakes:**
|
|
226
|
+
- ❌ `size="xs"` → Use size="sm"
|
|
227
|
+
- ❌ `size="2xl"` → Use size="xl"
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
180
231
|
### Badge
|
|
181
232
|
|
|
233
|
+
Small label for status, category, or count. Use dot prop for live status indicator.
|
|
234
|
+
|
|
182
235
|
```tsx
|
|
183
236
|
import { Badge } from "@usevyre/react"
|
|
184
237
|
|
|
185
238
|
// Props:
|
|
186
|
-
// variant
|
|
187
|
-
// dot
|
|
239
|
+
// variant = "default" | "accent" | "teal" | "success" | "warning" | "danger" (default: default)
|
|
240
|
+
// dot = boolean (default: false)
|
|
188
241
|
|
|
189
242
|
// Examples:
|
|
190
243
|
<Badge variant="success" dot>Online</Badge>
|
|
@@ -192,21 +245,107 @@ import { Badge } from "@usevyre/react"
|
|
|
192
245
|
<Badge variant="danger">Error</Badge>
|
|
193
246
|
```
|
|
194
247
|
|
|
248
|
+
**Common mistakes:**
|
|
249
|
+
- ❌ `variant="primary"` → Use variant="accent" for brand color
|
|
250
|
+
- ❌ `variant="error"` → Use variant="danger"
|
|
251
|
+
- ❌ `variant="info"` → Use variant="teal" for info-like styling
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
### Breadcrumb
|
|
256
|
+
|
|
257
|
+
Navigation trail showing current page location in hierarchy.
|
|
258
|
+
|
|
259
|
+
```tsx
|
|
260
|
+
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbSeparator } from "@usevyre/react"
|
|
261
|
+
|
|
262
|
+
// Examples:
|
|
263
|
+
<Breadcrumb>
|
|
264
|
+
<BreadcrumbItem><BreadcrumbLink href="/">Home</BreadcrumbLink></BreadcrumbItem>
|
|
265
|
+
<BreadcrumbSeparator />
|
|
266
|
+
<BreadcrumbItem><BreadcrumbLink href="/docs">Docs</BreadcrumbLink></BreadcrumbItem>
|
|
267
|
+
<BreadcrumbSeparator />
|
|
268
|
+
<BreadcrumbItem aria-current="page">Button</BreadcrumbItem>
|
|
269
|
+
</Breadcrumb>
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Common mistakes:**
|
|
273
|
+
- ❌ `Using plain <a> tags inside Breadcrumb` → Use BreadcrumbItem > BreadcrumbLink for each crumb
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
### Button
|
|
278
|
+
|
|
279
|
+
Triggers actions and navigation. The most commonly used interactive element.
|
|
280
|
+
|
|
281
|
+
```tsx
|
|
282
|
+
import { Button } from "@usevyre/react"
|
|
283
|
+
|
|
284
|
+
// Props:
|
|
285
|
+
// variant = "primary" | "secondary" | "ghost" | "accent" | "teal" | "danger" (default: secondary)
|
|
286
|
+
// size = "sm" | "md" | "lg" | "icon" (default: md)
|
|
287
|
+
// loading = boolean (default: false)
|
|
288
|
+
// disabled = boolean (default: false)
|
|
289
|
+
// as = React.ElementType (default: "button")
|
|
290
|
+
// leftIcon = ReactNode
|
|
291
|
+
// rightIcon = ReactNode
|
|
292
|
+
|
|
293
|
+
// Examples:
|
|
294
|
+
<Button variant="primary">Get Started</Button>
|
|
295
|
+
<Button variant="accent" size="lg">Launch App</Button>
|
|
296
|
+
<Button variant="danger" loading>Deleting...</Button>
|
|
297
|
+
<Button as="a" href="/docs" variant="secondary">Read Docs</Button>
|
|
298
|
+
<Button variant="ghost" size="icon" aria-label="Close">
|
|
299
|
+
<X size={16} />
|
|
300
|
+
</Button>
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**Common mistakes:**
|
|
304
|
+
- ❌ `variant="blue"` → Use variant="accent" for brand amber, or variant="teal" for teal
|
|
305
|
+
- ❌ `size="xl"` → Use size="lg"
|
|
306
|
+
- ❌ `color="..."` → Use variant prop instead
|
|
307
|
+
- ❌ `icon={...}` → Use leftIcon={...} or rightIcon={...}
|
|
308
|
+
- ❌ `size="icon" without aria-label` → Add aria-label describing the action
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
### Calendar
|
|
313
|
+
|
|
314
|
+
Date picker calendar widget for selecting single dates or ranges.
|
|
315
|
+
|
|
316
|
+
```tsx
|
|
317
|
+
import { Calendar } from "@usevyre/react"
|
|
318
|
+
|
|
319
|
+
// Props:
|
|
320
|
+
// value = Date | null
|
|
321
|
+
// onChange = function
|
|
322
|
+
// disabled = boolean (default: false)
|
|
323
|
+
|
|
324
|
+
// Examples:
|
|
325
|
+
const [date, setDate] = useState(null);
|
|
326
|
+
<Calendar value={date} onChange={setDate} />
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
**Common mistakes:**
|
|
330
|
+
- ❌ `Using Calendar for time selection` → Combine with a separate time Input if time selection is needed
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
195
334
|
### Card
|
|
196
335
|
|
|
336
|
+
Content container with optional header, body, and footer sections.
|
|
337
|
+
|
|
197
338
|
```tsx
|
|
198
339
|
import { Card, CardHeader, CardBody, CardFooter } from "@usevyre/react"
|
|
199
340
|
|
|
200
|
-
//
|
|
201
|
-
// variant
|
|
202
|
-
// hoverable
|
|
203
|
-
// clickable
|
|
341
|
+
// Props:
|
|
342
|
+
// variant = "default" | "elevated" | "outlined" | "ghost" | "accent" (default: default)
|
|
343
|
+
// hoverable = boolean (default: false)
|
|
344
|
+
// clickable = boolean (default: false)
|
|
204
345
|
|
|
205
346
|
// Examples:
|
|
206
347
|
<Card variant="elevated">
|
|
207
|
-
<CardHeader>
|
|
208
|
-
<Badge variant="teal">New</Badge>
|
|
209
|
-
</CardHeader>
|
|
348
|
+
<CardHeader><Badge variant="teal">New</Badge></CardHeader>
|
|
210
349
|
<CardBody>
|
|
211
350
|
<h3>Card Title</h3>
|
|
212
351
|
<p>Description text.</p>
|
|
@@ -217,39 +356,576 @@ import { Card, CardHeader, CardBody, CardFooter } from "@usevyre/react"
|
|
|
217
356
|
</Card>
|
|
218
357
|
```
|
|
219
358
|
|
|
220
|
-
|
|
359
|
+
**Common mistakes:**
|
|
360
|
+
- ❌ `variant="primary"` → Use variant="elevated" | "outlined" | "ghost" | "accent"
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
### Checkbox
|
|
365
|
+
|
|
366
|
+
Binary toggle for boolean form values.
|
|
221
367
|
|
|
222
368
|
```tsx
|
|
223
|
-
import {
|
|
369
|
+
import { Checkbox } from "@usevyre/react"
|
|
224
370
|
|
|
225
|
-
//
|
|
226
|
-
//
|
|
227
|
-
//
|
|
228
|
-
//
|
|
229
|
-
//
|
|
371
|
+
// Props:
|
|
372
|
+
// size = "sm" | "md" (default: md)
|
|
373
|
+
// checked = boolean
|
|
374
|
+
// onChange = function
|
|
375
|
+
// disabled = boolean (default: false)
|
|
376
|
+
// indeterminate = boolean (default: false)
|
|
230
377
|
|
|
231
|
-
//
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
378
|
+
// Examples:
|
|
379
|
+
<label style={{ display: 'flex', alignItems: 'center', gap: 'var(--vyre-spacing-2)' }}>
|
|
380
|
+
<Checkbox checked={agreed} onChange={e => setAgreed(e.target.checked)} />
|
|
381
|
+
I agree to the terms
|
|
382
|
+
</label>
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
**Common mistakes:**
|
|
386
|
+
- ❌ `size="lg"` → Use size="md"
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
### Command
|
|
391
|
+
|
|
392
|
+
Command palette / search dialog. Use for search-first navigation or quick actions.
|
|
393
|
+
|
|
394
|
+
```tsx
|
|
395
|
+
import { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandDialog } from "@usevyre/react"
|
|
396
|
+
|
|
397
|
+
// Examples:
|
|
398
|
+
<Command>
|
|
399
|
+
<CommandInput placeholder="Search..." />
|
|
400
|
+
<CommandList>
|
|
401
|
+
<CommandEmpty>No results found.</CommandEmpty>
|
|
402
|
+
<CommandGroup heading="Suggestions">
|
|
403
|
+
<CommandItem onSelect={() => handleSelect('dashboard')}>Dashboard</CommandItem>
|
|
404
|
+
<CommandItem onSelect={() => handleSelect('settings')}>Settings</CommandItem>
|
|
405
|
+
</CommandGroup>
|
|
406
|
+
</CommandList>
|
|
407
|
+
</Command>
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
**Common mistakes:**
|
|
411
|
+
- ❌ `Using Input type="search" for search UI` → Use Command + CommandInput + CommandList + CommandItem
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
### DropdownMenu
|
|
416
|
+
|
|
417
|
+
Contextual menu triggered by a button. Supports items, separators, checkbox items, radio groups, and sub-menus.
|
|
418
|
+
|
|
419
|
+
```tsx
|
|
420
|
+
import { DropdownMenu, DropdownItem, DropdownSeparator, DropdownCheckboxItem, DropdownRadioGroup, DropdownRadioItem, DropdownSub } from "@usevyre/react"
|
|
421
|
+
|
|
422
|
+
// Props:
|
|
423
|
+
// trigger = ReactElement
|
|
236
424
|
|
|
237
425
|
// Examples:
|
|
238
|
-
<
|
|
426
|
+
<DropdownMenu trigger={<Button variant="secondary">Options</Button>}>
|
|
427
|
+
<DropdownItem onSelect={() => handleEdit()}>Edit</DropdownItem>
|
|
428
|
+
<DropdownItem onSelect={() => handleDuplicate()}>Duplicate</DropdownItem>
|
|
429
|
+
<DropdownSeparator />
|
|
430
|
+
<DropdownItem variant="danger" onSelect={() => handleDelete()}>Delete</DropdownItem>
|
|
431
|
+
</DropdownMenu>
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
**Common mistakes:**
|
|
435
|
+
- ❌ `DropdownItem variant="primary"` → Use variant="danger" for destructive items only
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
### Field
|
|
440
|
+
|
|
441
|
+
Form field wrapper providing label, hint text, and validation state for Input or Textarea.
|
|
442
|
+
|
|
443
|
+
```tsx
|
|
444
|
+
import { Field, Input, Textarea } from "@usevyre/react"
|
|
445
|
+
|
|
446
|
+
// Props:
|
|
447
|
+
// label = string
|
|
448
|
+
// hint = string
|
|
449
|
+
// state = "idle" | "error" | "success" | "warning" (default: idle)
|
|
450
|
+
// required = boolean (default: false)
|
|
451
|
+
|
|
452
|
+
// Examples:
|
|
453
|
+
<Field label="Email" state="error" hint="Invalid email format">
|
|
239
454
|
<Input type="email" placeholder="you@example.com" />
|
|
240
455
|
</Field>
|
|
241
|
-
|
|
242
456
|
<Field label="Search">
|
|
243
457
|
<Input leftElement={<SearchIcon />} placeholder="Search..." />
|
|
244
458
|
</Field>
|
|
459
|
+
```
|
|
245
460
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
461
|
+
**Common mistakes:**
|
|
462
|
+
- ❌ `Applying state prop directly to Input` → Wrap Input in <Field state="error"> to apply validation styling
|
|
463
|
+
|
|
464
|
+
---
|
|
465
|
+
|
|
466
|
+
### Input
|
|
467
|
+
|
|
468
|
+
Text input field. Wrap in Field for labels and validation. Use leftElement/rightElement for icons.
|
|
469
|
+
|
|
470
|
+
```tsx
|
|
471
|
+
import { Input } from "@usevyre/react"
|
|
472
|
+
|
|
473
|
+
// Props:
|
|
474
|
+
// size = "sm" | "md" | "lg" (default: md)
|
|
475
|
+
// leftElement = ReactNode
|
|
476
|
+
// rightElement = ReactNode
|
|
477
|
+
|
|
478
|
+
// Examples:
|
|
479
|
+
<Input type="password" rightElement={<EyeIcon />} placeholder="Password" />
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
**Common mistakes:**
|
|
483
|
+
- ❌ `size="icon"` → Use size="sm" | "md" | "lg"
|
|
484
|
+
- ❌ `type="search" for search UI` → Import Command from @usevyre/react for search palettes
|
|
485
|
+
|
|
486
|
+
---
|
|
487
|
+
|
|
488
|
+
### Label
|
|
489
|
+
|
|
490
|
+
Accessible form label. Associate with input via htmlFor.
|
|
491
|
+
|
|
492
|
+
```tsx
|
|
493
|
+
import { Label } from "@usevyre/react"
|
|
494
|
+
|
|
495
|
+
// Props:
|
|
496
|
+
// htmlFor = string
|
|
497
|
+
// required = boolean (default: false)
|
|
498
|
+
|
|
499
|
+
// Examples:
|
|
500
|
+
<Label htmlFor="email">Email address</Label>
|
|
501
|
+
<Input id="email" type="email" />
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
---
|
|
505
|
+
|
|
506
|
+
### Modal
|
|
507
|
+
|
|
508
|
+
Dialog overlay for confirmations, forms, or focused content.
|
|
509
|
+
|
|
510
|
+
```tsx
|
|
511
|
+
import { Modal, ModalHeader, ModalBody, ModalFooter } from "@usevyre/react"
|
|
512
|
+
|
|
513
|
+
// Props:
|
|
514
|
+
// open = boolean
|
|
515
|
+
// onClose = function
|
|
516
|
+
// size = "sm" | "md" | "lg" | "full" (default: md)
|
|
517
|
+
// title = string
|
|
518
|
+
|
|
519
|
+
// Examples:
|
|
520
|
+
<Modal open={isOpen} onClose={() => setIsOpen(false)} title="Confirm Delete" size="sm">
|
|
521
|
+
<ModalBody>Are you sure you want to delete this item?</ModalBody>
|
|
522
|
+
<ModalFooter>
|
|
523
|
+
<Button variant="ghost" onClick={() => setIsOpen(false)}>Cancel</Button>
|
|
524
|
+
<Button variant="danger" onClick={handleDelete}>Delete</Button>
|
|
525
|
+
</ModalFooter>
|
|
526
|
+
</Modal>
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
**Common mistakes:**
|
|
530
|
+
- ❌ `size="xl"` → Use size="lg" or size="full"
|
|
531
|
+
|
|
532
|
+
---
|
|
533
|
+
|
|
534
|
+
### Pagination
|
|
535
|
+
|
|
536
|
+
Page navigation for paginated lists or tables.
|
|
537
|
+
|
|
538
|
+
```tsx
|
|
539
|
+
import { Pagination } from "@usevyre/react"
|
|
540
|
+
|
|
541
|
+
// Props:
|
|
542
|
+
// page = number
|
|
543
|
+
// total = number
|
|
544
|
+
// onChange = function
|
|
545
|
+
|
|
546
|
+
// Examples:
|
|
547
|
+
<Pagination page={currentPage} total={totalPages} onChange={setCurrentPage} />
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
---
|
|
551
|
+
|
|
552
|
+
### Popover
|
|
553
|
+
|
|
554
|
+
Floating content panel anchored to a trigger element. For simple labels use Tooltip instead.
|
|
555
|
+
|
|
556
|
+
```tsx
|
|
557
|
+
import { Popover } from "@usevyre/react"
|
|
558
|
+
|
|
559
|
+
// Props:
|
|
560
|
+
// trigger = ReactElement
|
|
561
|
+
// placement = "top" | "top-start" | "top-end" | "bottom" | "bottom-start" | "bottom-end" | "left" | "left-start" | "left-end" | "right" | "right-start" | "right-end" (default: bottom)
|
|
562
|
+
// open = boolean
|
|
563
|
+
// onOpenChange = function
|
|
564
|
+
// closeOnOutside = boolean (default: true)
|
|
565
|
+
|
|
566
|
+
// Examples:
|
|
567
|
+
<Popover trigger={<Button variant="secondary">More info</Button>} placement="bottom-start">
|
|
568
|
+
<div style={{ padding: 'var(--vyre-spacing-4)' }}>
|
|
569
|
+
<p>Detailed information here.</p>
|
|
570
|
+
</div>
|
|
571
|
+
</Popover>
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
**Common mistakes:**
|
|
575
|
+
- ❌ `placement="top-center"` → Use placement="top" for centered placement
|
|
576
|
+
|
|
577
|
+
---
|
|
578
|
+
|
|
579
|
+
### Progress
|
|
580
|
+
|
|
581
|
+
Visual progress indicator for tasks, uploads, or completion status.
|
|
582
|
+
|
|
583
|
+
```tsx
|
|
584
|
+
import { Progress } from "@usevyre/react"
|
|
585
|
+
|
|
586
|
+
// Props:
|
|
587
|
+
// value = number
|
|
588
|
+
// size = "sm" | "md" | "lg" (default: md)
|
|
589
|
+
// variant = "default" | "accent" | "teal" | "success" | "danger" (default: default)
|
|
590
|
+
|
|
591
|
+
// Examples:
|
|
592
|
+
<Progress value={uploadPercent} variant="accent" size="sm" />
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
**Common mistakes:**
|
|
596
|
+
- ❌ `value > 100` → Normalize your value to 0–100 range before passing
|
|
597
|
+
|
|
598
|
+
---
|
|
599
|
+
|
|
600
|
+
### Select
|
|
601
|
+
|
|
602
|
+
Dropdown for selecting one option from a list.
|
|
603
|
+
|
|
604
|
+
```tsx
|
|
605
|
+
import { Select } from "@usevyre/react"
|
|
606
|
+
|
|
607
|
+
// Props:
|
|
608
|
+
// options = SelectOption[]
|
|
609
|
+
// value = string
|
|
610
|
+
// onChange = function
|
|
611
|
+
// size = "sm" | "md" | "lg" (default: md)
|
|
612
|
+
// placeholder = string
|
|
613
|
+
// disabled = boolean (default: false)
|
|
614
|
+
|
|
615
|
+
// Examples:
|
|
616
|
+
<Select
|
|
617
|
+
options={[{ value: 'react', label: 'React' }, { value: 'vue', label: 'Vue' }]}
|
|
618
|
+
value={framework}
|
|
619
|
+
onChange={setFramework}
|
|
620
|
+
placeholder="Choose framework"
|
|
621
|
+
/>
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
**Common mistakes:**
|
|
625
|
+
- ❌ `Passing strings directly as children` → Pass options={[{ value: 'a', label: 'Option A' }]}
|
|
626
|
+
|
|
627
|
+
---
|
|
628
|
+
|
|
629
|
+
### Separator
|
|
630
|
+
|
|
631
|
+
Horizontal or vertical divider line.
|
|
632
|
+
|
|
633
|
+
```tsx
|
|
634
|
+
import { Separator } from "@usevyre/react"
|
|
635
|
+
|
|
636
|
+
// Props:
|
|
637
|
+
// orientation = "horizontal" | "vertical" (default: horizontal)
|
|
638
|
+
|
|
639
|
+
// Examples:
|
|
640
|
+
<Separator />
|
|
641
|
+
<Separator orientation="vertical" />
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
---
|
|
645
|
+
|
|
646
|
+
### Sheet
|
|
647
|
+
|
|
648
|
+
Side panel (drawer) that slides in from the edge. For forms, detail views, or settings.
|
|
649
|
+
|
|
650
|
+
```tsx
|
|
651
|
+
import { Sheet, SheetHeader, SheetBody, SheetFooter } from "@usevyre/react"
|
|
652
|
+
|
|
653
|
+
// Props:
|
|
654
|
+
// open = boolean
|
|
655
|
+
// onClose = function
|
|
656
|
+
// size = "sm" | "md" | "lg" | "full" (default: md)
|
|
657
|
+
// side = "left" | "right" (default: right)
|
|
658
|
+
// title = string
|
|
659
|
+
|
|
660
|
+
// Examples:
|
|
661
|
+
<Sheet open={isOpen} onClose={() => setIsOpen(false)} title="Settings" side="right">
|
|
662
|
+
<SheetBody>Settings content here.</SheetBody>
|
|
663
|
+
<SheetFooter>
|
|
664
|
+
<Button variant="accent">Save</Button>
|
|
665
|
+
</SheetFooter>
|
|
666
|
+
</Sheet>
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
---
|
|
670
|
+
|
|
671
|
+
### Sidebar
|
|
672
|
+
|
|
673
|
+
App navigation sidebar. Use AppLayout as the root layout wrapper.
|
|
674
|
+
|
|
675
|
+
```tsx
|
|
676
|
+
import { AppLayout, Sidebar, SidebarHeader, SidebarContent, SidebarSection, SidebarItem, SidebarFooter } from "@usevyre/react"
|
|
677
|
+
|
|
678
|
+
// Props:
|
|
679
|
+
// variant = "default" | "floating" (default: default)
|
|
680
|
+
|
|
681
|
+
// Examples:
|
|
682
|
+
<AppLayout>
|
|
683
|
+
<Sidebar>
|
|
684
|
+
<SidebarHeader>Logo</SidebarHeader>
|
|
685
|
+
<SidebarContent>
|
|
686
|
+
<SidebarSection heading="Main">
|
|
687
|
+
<SidebarItem href="/" active>Dashboard</SidebarItem>
|
|
688
|
+
<SidebarItem href="/settings">Settings</SidebarItem>
|
|
689
|
+
</SidebarSection>
|
|
690
|
+
</SidebarContent>
|
|
691
|
+
<SidebarFooter><Avatar fallback="JD" size="sm" /></SidebarFooter>
|
|
692
|
+
</Sidebar>
|
|
693
|
+
<main>Page content</main>
|
|
694
|
+
</AppLayout>
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
---
|
|
698
|
+
|
|
699
|
+
### Skeleton
|
|
700
|
+
|
|
701
|
+
Loading placeholder that mimics the shape of content while data loads.
|
|
702
|
+
|
|
703
|
+
```tsx
|
|
704
|
+
import { Skeleton } from "@usevyre/react"
|
|
705
|
+
|
|
706
|
+
// Props:
|
|
707
|
+
// variant = "rect" | "circle" | "text" (default: rect)
|
|
708
|
+
// width = string | number
|
|
709
|
+
// height = string | number
|
|
710
|
+
|
|
711
|
+
// Examples:
|
|
712
|
+
<Skeleton variant="circle" width={40} height={40} />
|
|
713
|
+
<Skeleton variant="text" width="100%" />
|
|
714
|
+
<Skeleton variant="text" width="60%" />
|
|
249
715
|
```
|
|
250
716
|
|
|
251
717
|
---
|
|
252
718
|
|
|
719
|
+
### Slider
|
|
720
|
+
|
|
721
|
+
Range input for selecting a numeric value within a range.
|
|
722
|
+
|
|
723
|
+
```tsx
|
|
724
|
+
import { Slider } from "@usevyre/react"
|
|
725
|
+
|
|
726
|
+
// Props:
|
|
727
|
+
// value = number
|
|
728
|
+
// onChange = function
|
|
729
|
+
// min = number (default: 0)
|
|
730
|
+
// max = number (default: 100)
|
|
731
|
+
// step = number (default: 1)
|
|
732
|
+
// size = "sm" | "md" (default: md)
|
|
733
|
+
// disabled = boolean (default: false)
|
|
734
|
+
|
|
735
|
+
// Examples:
|
|
736
|
+
<Slider value={volume} onChange={setVolume} min={0} max={100} step={5} />
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
---
|
|
740
|
+
|
|
741
|
+
### Switch
|
|
742
|
+
|
|
743
|
+
Toggle switch for boolean on/off settings.
|
|
744
|
+
|
|
745
|
+
```tsx
|
|
746
|
+
import { Switch } from "@usevyre/react"
|
|
747
|
+
|
|
748
|
+
// Props:
|
|
749
|
+
// checked = boolean
|
|
750
|
+
// onChange = function
|
|
751
|
+
// size = "sm" | "md" (default: md)
|
|
752
|
+
// disabled = boolean (default: false)
|
|
753
|
+
|
|
754
|
+
// Examples:
|
|
755
|
+
<label style={{ display: 'flex', alignItems: 'center', gap: 'var(--vyre-spacing-2)' }}>
|
|
756
|
+
<Switch checked={notifications} onChange={setNotifications} />
|
|
757
|
+
Enable notifications
|
|
758
|
+
</label>
|
|
759
|
+
```
|
|
760
|
+
|
|
761
|
+
---
|
|
762
|
+
|
|
763
|
+
### Table
|
|
764
|
+
|
|
765
|
+
Data table with optional sorting. Compose with TableHeader, TableRow, TableCell.
|
|
766
|
+
|
|
767
|
+
```tsx
|
|
768
|
+
import { Table, TableHead, TableBody, TableRow, TableHeader, TableCell } from "@usevyre/react"
|
|
769
|
+
|
|
770
|
+
// Examples:
|
|
771
|
+
<Table>
|
|
772
|
+
<TableHead>
|
|
773
|
+
<TableRow>
|
|
774
|
+
<TableHeader>Name</TableHeader>
|
|
775
|
+
<TableHeader>Status</TableHeader>
|
|
776
|
+
</TableRow>
|
|
777
|
+
</TableHead>
|
|
778
|
+
<TableBody>
|
|
779
|
+
<TableRow>
|
|
780
|
+
<TableCell>Alice</TableCell>
|
|
781
|
+
<TableCell><Badge variant="success">Active</Badge></TableCell>
|
|
782
|
+
</TableRow>
|
|
783
|
+
</TableBody>
|
|
784
|
+
</Table>
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
---
|
|
788
|
+
|
|
789
|
+
### Tabs
|
|
790
|
+
|
|
791
|
+
Tabbed navigation for switching between content panels.
|
|
792
|
+
|
|
793
|
+
```tsx
|
|
794
|
+
import { Tabs, TabList, Tab, TabPanels, TabPanel } from "@usevyre/react"
|
|
795
|
+
|
|
796
|
+
// Props:
|
|
797
|
+
// defaultIndex = number (default: 0)
|
|
798
|
+
// index = number
|
|
799
|
+
// onChange = function
|
|
800
|
+
|
|
801
|
+
// Examples:
|
|
802
|
+
<Tabs defaultIndex={0}>
|
|
803
|
+
<TabList>
|
|
804
|
+
<Tab>Overview</Tab>
|
|
805
|
+
<Tab>Settings</Tab>
|
|
806
|
+
</TabList>
|
|
807
|
+
<TabPanels>
|
|
808
|
+
<TabPanel>Overview content</TabPanel>
|
|
809
|
+
<TabPanel>Settings content</TabPanel>
|
|
810
|
+
</TabPanels>
|
|
811
|
+
</Tabs>
|
|
812
|
+
```
|
|
813
|
+
|
|
814
|
+
---
|
|
815
|
+
|
|
816
|
+
### Toast
|
|
817
|
+
|
|
818
|
+
Transient notification. Use the useToast hook to trigger toasts imperatively.
|
|
819
|
+
|
|
820
|
+
```tsx
|
|
821
|
+
import { useToast, ToastProvider } from "@usevyre/react"
|
|
822
|
+
|
|
823
|
+
// Props:
|
|
824
|
+
// variant = "default" | "success" | "warning" | "danger" (default: default)
|
|
825
|
+
// title = string
|
|
826
|
+
// description = string
|
|
827
|
+
// duration = number (default: 4000)
|
|
828
|
+
|
|
829
|
+
// Examples:
|
|
830
|
+
const { toast } = useToast();
|
|
831
|
+
|
|
832
|
+
<Button onClick={() => toast({ title: 'Saved!', variant: 'success', duration: 3000 })}>
|
|
833
|
+
Save
|
|
834
|
+
</Button>
|
|
835
|
+
<ToastProvider>
|
|
836
|
+
<App />
|
|
837
|
+
</ToastProvider>
|
|
838
|
+
```
|
|
839
|
+
|
|
840
|
+
**Common mistakes:**
|
|
841
|
+
- ❌ `Rendering <Toast> directly in JSX` → Use: const { toast } = useToast(); then toast({ title, variant })
|
|
842
|
+
- ❌ `variant="error"` → Use variant="danger"
|
|
843
|
+
- ❌ `variant="info"` → Use variant="default"
|
|
844
|
+
|
|
845
|
+
---
|
|
846
|
+
|
|
847
|
+
### Tooltip
|
|
848
|
+
|
|
849
|
+
Short label that appears on hover/focus. For rich content use Popover instead.
|
|
850
|
+
|
|
851
|
+
```tsx
|
|
852
|
+
import { Tooltip } from "@usevyre/react"
|
|
853
|
+
|
|
854
|
+
// Props:
|
|
855
|
+
// content = string | ReactNode
|
|
856
|
+
// placement = "top" | "bottom" | "left" | "right" (default: top)
|
|
857
|
+
// delay = number (default: 300)
|
|
858
|
+
|
|
859
|
+
// Examples:
|
|
860
|
+
<Tooltip content="Close dialog" placement="bottom">
|
|
861
|
+
<Button variant="ghost" size="icon" aria-label="Close">
|
|
862
|
+
<X size={16} />
|
|
863
|
+
</Button>
|
|
864
|
+
</Tooltip>
|
|
865
|
+
```
|
|
866
|
+
|
|
867
|
+
**Common mistakes:**
|
|
868
|
+
- ❌ `Using Tooltip for rich content (forms, buttons, etc.)` → Use Popover for rich interactive content
|
|
869
|
+
|
|
870
|
+
---
|
|
871
|
+
|
|
872
|
+
### Typography
|
|
873
|
+
|
|
874
|
+
Text rendering components with semantic scale. Includes Text, Heading, Lead, Code, Blockquote.
|
|
875
|
+
|
|
876
|
+
```tsx
|
|
877
|
+
import { Text, Heading, Lead, Code, Blockquote } from "@usevyre/react"
|
|
878
|
+
|
|
879
|
+
// Examples:
|
|
880
|
+
<Heading size="2xl" as="h1">Dashboard</Heading>
|
|
881
|
+
<Lead>Welcome back. Here's what's happening today.</Lead>
|
|
882
|
+
<Text size="sm" style={{ color: 'var(--vyre-color-semantic-text-muted)' }}>Last updated 5 minutes ago.</Text>
|
|
883
|
+
```
|
|
884
|
+
|
|
885
|
+
**Common mistakes:**
|
|
886
|
+
- ❌ `Using raw <h1>, <p> tags instead of Typography components` → Use <Heading>, <Text>, <Lead> from @usevyre/react
|
|
887
|
+
|
|
888
|
+
---
|
|
889
|
+
|
|
890
|
+
## Hallucination Guard — Common AI Mistakes
|
|
891
|
+
|
|
892
|
+
The following prop values and patterns do NOT exist in useVyre.
|
|
893
|
+
If you generate these, you are hallucinating.
|
|
894
|
+
|
|
895
|
+
- ❌ `<Accordion Accordion without AccordionItem>` → Always compose: Accordion > AccordionItem > AccordionTrigger + AccordionContent
|
|
896
|
+
- ❌ `<Alert variant="error">` → Use variant="danger"
|
|
897
|
+
- ❌ `<Alert variant="primary">` → Use variant="info" | "success" | "warning" | "danger"
|
|
898
|
+
- ❌ `<Avatar size="xs">` → Use size="sm"
|
|
899
|
+
- ❌ `<Avatar size="2xl">` → Use size="xl"
|
|
900
|
+
- ❌ `<Badge variant="primary">` → Use variant="accent" for brand color
|
|
901
|
+
- ❌ `<Badge variant="error">` → Use variant="danger"
|
|
902
|
+
- ❌ `<Badge variant="info">` → Use variant="teal" for info-like styling
|
|
903
|
+
- ❌ `<Breadcrumb Using plain <a> tags inside Breadcrumb>` → Use BreadcrumbItem > BreadcrumbLink for each crumb
|
|
904
|
+
- ❌ `<Button variant="blue">` → Use variant="accent" for brand amber, or variant="teal" for teal
|
|
905
|
+
- ❌ `<Button size="xl">` → Use size="lg"
|
|
906
|
+
- ❌ `<Button color="...">` → Use variant prop instead
|
|
907
|
+
- ❌ `<Button icon={...}>` → Use leftIcon={...} or rightIcon={...}
|
|
908
|
+
- ❌ `<Button size="icon" without aria-label>` → Add aria-label describing the action
|
|
909
|
+
- ❌ `<Calendar Using Calendar for time selection>` → Combine with a separate time Input if time selection is needed
|
|
910
|
+
- ❌ `<Card variant="primary">` → Use variant="elevated" | "outlined" | "ghost" | "accent"
|
|
911
|
+
- ❌ `<Checkbox size="lg">` → Use size="md"
|
|
912
|
+
- ❌ `<Command Using Input type="search" for search UI>` → Use Command + CommandInput + CommandList + CommandItem
|
|
913
|
+
- ❌ `<DropdownMenu DropdownItem variant="primary">` → Use variant="danger" for destructive items only
|
|
914
|
+
- ❌ `<Field Applying state prop directly to Input>` → Wrap Input in <Field state="error"> to apply validation styling
|
|
915
|
+
- ❌ `<Input size="icon">` → Use size="sm" | "md" | "lg"
|
|
916
|
+
- ❌ `<Input type="search" for search UI>` → Import Command from @usevyre/react for search palettes
|
|
917
|
+
- ❌ `<Modal size="xl">` → Use size="lg" or size="full"
|
|
918
|
+
- ❌ `<Popover placement="top-center">` → Use placement="top" for centered placement
|
|
919
|
+
- ❌ `<Progress value > 100>` → Normalize your value to 0–100 range before passing
|
|
920
|
+
- ❌ `<Select Passing strings directly as children>` → Pass options={[{ value: 'a', label: 'Option A' }]}
|
|
921
|
+
- ❌ `<Toast Rendering <Toast> directly in JSX>` → Use: const { toast } = useToast(); then toast({ title, variant })
|
|
922
|
+
- ❌ `<Toast variant="error">` → Use variant="danger"
|
|
923
|
+
- ❌ `<Toast variant="info">` → Use variant="default"
|
|
924
|
+
- ❌ `<Tooltip Using Tooltip for rich content (forms, buttons, etc.)>` → Use Popover for rich interactive content
|
|
925
|
+
- ❌ `<Typography Using raw <h1>, <p> tags instead of Typography components>` → Use <Heading>, <Text>, <Lead> from @usevyre/react
|
|
926
|
+
|
|
927
|
+
---
|
|
928
|
+
|
|
253
929
|
## Styling Rules for AI Agents
|
|
254
930
|
|
|
255
931
|
1. ALWAYS use semantic tokens (`--vyre-color-semantic-*`), never primitive tokens
|