@usevyre/ai-context 1.2.2 → 1.3.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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.2.0",
2
+ "version": "1.6.0",
3
3
  "rules": [
4
4
  {
5
5
  "component": "Accordion",
@@ -120,6 +120,13 @@
120
120
  "fix": "Add aria-label describing the action",
121
121
  "severity": "error"
122
122
  },
123
+ {
124
+ "component": "Button",
125
+ "pattern": "padding / margin / marginTop (any spacing prop) on a useVyre component",
126
+ "reason": "Components have NO spacing props by design — internal spacing is fixed by tokens for visual consistency",
127
+ "fix": "Space BETWEEN components with <Stack gap> / <Grid gap>; space AROUND a block with <Box padding/margin> wrapping it",
128
+ "severity": "error"
129
+ },
123
130
  {
124
131
  "component": "Calendar",
125
132
  "pattern": "Calendar for an input field that opens a popover",
@@ -155,6 +162,13 @@
155
162
  "fix": "Use variant=\"elevated\" | \"outlined\" | \"ghost\" | \"accent\"",
156
163
  "severity": "error"
157
164
  },
165
+ {
166
+ "component": "Card",
167
+ "pattern": "padding / margin / marginTop (any spacing prop) on a useVyre component",
168
+ "reason": "Components have NO spacing props by design — internal spacing is fixed by tokens for visual consistency",
169
+ "fix": "Space BETWEEN components with <Stack gap> / <Grid gap>; space AROUND a block with <Box padding/margin> wrapping it",
170
+ "severity": "error"
171
+ },
158
172
  {
159
173
  "component": "Checkbox",
160
174
  "pattern": "size=\"lg\"",
@@ -253,6 +267,13 @@
253
267
  "fix": "Use v-model on <Input>/<Textarea> in Vue; in React use value + onChange",
254
268
  "severity": "error"
255
269
  },
270
+ {
271
+ "component": "Input",
272
+ "pattern": "padding / margin / marginTop (any spacing prop) on a useVyre component",
273
+ "reason": "Components have NO spacing props by design — internal spacing is fixed by tokens for visual consistency",
274
+ "fix": "Space BETWEEN components with <Stack gap> / <Grid gap>; space AROUND a block with <Box padding/margin> wrapping it",
275
+ "severity": "error"
276
+ },
256
277
  {
257
278
  "component": "Modal",
258
279
  "pattern": "size=\"xl\"",
@@ -505,6 +526,90 @@
505
526
  "fix": "Handle onSend(text, files) — map files to message attachments and append",
506
527
  "severity": "error"
507
528
  },
529
+ {
530
+ "component": "Stack",
531
+ "pattern": "<div style={{ display: 'flex', gap: 12 }}>",
532
+ "reason": "Inline flex styles bypass the design system and use magic-number spacing",
533
+ "fix": "Use <Stack gap=\"md\"> — gap is a token",
534
+ "severity": "error"
535
+ },
536
+ {
537
+ "component": "Stack",
538
+ "pattern": "gap={12} or gap=\"12px\"",
539
+ "reason": "Stack gap is a closed token enum",
540
+ "fix": "Use gap=\"none|xs|sm|md|lg|xl|2xl\"",
541
+ "severity": "error"
542
+ },
543
+ {
544
+ "component": "Stack",
545
+ "pattern": "direction=\"vertical\" / \"horizontal\"",
546
+ "reason": "Stack mirrors CSS flex-direction names",
547
+ "fix": "Use direction=\"row\" or \"column\" (also row-reverse / column-reverse)",
548
+ "severity": "error"
549
+ },
550
+ {
551
+ "component": "Stack",
552
+ "pattern": "style={{ width: \"100%\" }} / style={{ height: 320 }}",
553
+ "reason": "Inline width/height bypass the design system and use magic numbers",
554
+ "fix": "Use the width / height prop: width=\"full\", width=\"md\", height=\"screen\", etc.",
555
+ "severity": "error"
556
+ },
557
+ {
558
+ "component": "Grid",
559
+ "pattern": "<div style={{ display:'grid', gridTemplateColumns:'1fr 1fr 1fr' }}>",
560
+ "reason": "Inline grid styles bypass the design system",
561
+ "fix": "Use <Grid columns={3} gap=\"md\">",
562
+ "severity": "error"
563
+ },
564
+ {
565
+ "component": "Grid",
566
+ "pattern": "columns=\"3\" (string)",
567
+ "reason": "columns is a number or the literal 'auto-fit'",
568
+ "fix": "Use columns={3} or columns=\"auto-fit\"",
569
+ "severity": "error"
570
+ },
571
+ {
572
+ "component": "Grid",
573
+ "pattern": "Nested div with inline grid-column for spanning",
574
+ "reason": "Spanning has a dedicated primitive",
575
+ "fix": "Wrap the cell in <GridItem colSpan={2}>",
576
+ "severity": "error"
577
+ },
578
+ {
579
+ "component": "Grid",
580
+ "pattern": "style={{ width: \"100%\" }} / style={{ height: 320 }}",
581
+ "reason": "Inline width/height bypass the design system and use magic numbers",
582
+ "fix": "Use the width / height prop: width=\"full\", width=\"md\", height=\"screen\", etc.",
583
+ "severity": "error"
584
+ },
585
+ {
586
+ "component": "GridItem",
587
+ "pattern": "GridItem outside a Grid",
588
+ "reason": "GridItem only has effect as a direct child of Grid",
589
+ "fix": "Place <GridItem> directly inside <Grid>",
590
+ "severity": "error"
591
+ },
592
+ {
593
+ "component": "Box",
594
+ "pattern": "<Box style={{ padding: 16 }}>",
595
+ "reason": "padding is a token prop; style is a last resort",
596
+ "fix": "Use <Box padding=\"md\"> (or paddingX/paddingTop/...)",
597
+ "severity": "error"
598
+ },
599
+ {
600
+ "component": "Box",
601
+ "pattern": "Using Box for flex/grid layout",
602
+ "reason": "Box is spacing-only and has no layout props",
603
+ "fix": "Use <Stack> or <Grid>",
604
+ "severity": "error"
605
+ },
606
+ {
607
+ "component": "Box",
608
+ "pattern": "style={{ width: \"100%\" }} / style={{ height: 320 }}",
609
+ "reason": "Inline width/height bypass the design system and use magic numbers",
610
+ "fix": "Use the width / height prop: width=\"full\", width=\"md\", height=\"screen\", etc.",
611
+ "severity": "error"
612
+ },
508
613
  {
509
614
  "component": "DateRangePicker",
510
615
  "pattern": "value={[from, to]}",
@@ -0,0 +1,52 @@
1
+ # Box — AI Cheat Sheet
2
+ > Quick reference for Claude / Cursor / Copilot
3
+
4
+ **Spacing-only container plus a controlled escape hatch. Token padding/margin with shorthand, per-axis (X/Y) and per-side (Top/Right/Bottom/Left) overrides. The `style` prop is an explicit anti-pattern escape hatch. Renders a plain <div> (or `as`).**
5
+
6
+ ```ts
7
+ import { Box } from "@usevyre/react"
8
+ ```
9
+
10
+ ## Valid Props
11
+
12
+ | Prop | Values | Default |
13
+ |------|--------|---------|
14
+ | `padding` | `"none"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
15
+ | `paddingX` | `"none"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
16
+ | `paddingY` | `"none"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
17
+ | `paddingTop` | `"none"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
18
+ | `paddingRight` | `"none"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
19
+ | `paddingBottom` | `"none"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
20
+ | `paddingLeft` | `"none"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
21
+ | `margin` | `"none"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
22
+ | `marginX` | `"none"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
23
+ | `marginY` | `"none"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
24
+ | `marginTop` | `"none"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
25
+ | `marginRight` | `"none"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
26
+ | `marginBottom` | `"none"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
27
+ | `marginLeft` | `"none"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
28
+ | `width` | `"auto"` \| `"full"` \| `"fit"` \| `"screen"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
29
+ | `height` | `"auto"` \| `"full"` \| `"fit"` \| `"screen"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
30
+
31
+ ## Common AI Mistakes
32
+
33
+ - ❌ `<Box style={{ padding: 16 }}>`
34
+ → Use <Box padding="md"> (or paddingX/paddingTop/...)
35
+ - ❌ `Using Box for flex/grid layout`
36
+ → Use <Stack> or <Grid>
37
+ - ❌ `style={{ width: "100%" }} / style={{ height: 320 }}`
38
+ → Use the width / height prop: width="full", width="md", height="screen", etc.
39
+
40
+ ## Examples
41
+
42
+ **Asymmetric padding**
43
+ ```tsx
44
+ <Box as="section" paddingX="lg" paddingY="md">
45
+ <Heading>Settings</Heading>
46
+ </Box>
47
+ ```
48
+
49
+ **Vertical rhythm via margin-top**
50
+ ```tsx
51
+ <Box marginTop="xl"><Separator /></Box>
52
+ ```
@@ -28,6 +28,8 @@ import { Button } from "@usevyre/react"
28
28
  → Use leftIcon={...} or rightIcon={...}
29
29
  - ❌ `size="icon" without aria-label`
30
30
  → Add aria-label describing the action
31
+ - ❌ `padding / margin / marginTop (any spacing prop) on a useVyre component`
32
+ → Space BETWEEN components with <Stack gap> / <Grid gap>; space AROUND a block with <Box padding/margin> wrapping it
31
33
 
32
34
  ## Examples
33
35
 
@@ -19,6 +19,8 @@ import { Card, CardHeader, CardBody, CardFooter } from "@usevyre/react"
19
19
 
20
20
  - ❌ `variant="primary"`
21
21
  → Use variant="elevated" | "outlined" | "ghost" | "accent"
22
+ - ❌ `padding / margin / marginTop (any spacing prop) on a useVyre component`
23
+ → Space BETWEEN components with <Stack gap> / <Grid gap>; space AROUND a block with <Box padding/margin> wrapping it
22
24
 
23
25
  ## Examples
24
26
 
@@ -0,0 +1,50 @@
1
+ # Grid — AI Cheat Sheet
2
+ > Quick reference for Claude / Cursor / Copilot
3
+
4
+ **Two-dimensional CSS grid primitive. Explicit column/row counts (or auto-fit), auto-flow control, token gap. Pair with GridItem for cell spanning/placement. Renders a plain <div> (or `as`).**
5
+
6
+ ```ts
7
+ import { Grid, GridItem } from "@usevyre/react"
8
+ ```
9
+
10
+ ## Valid Props
11
+
12
+ | Prop | Values | Default |
13
+ |------|--------|---------|
14
+ | `flow` | `"row"` \| `"column"` \| `"dense"` \| `"row-dense"` \| `"column-dense"` | — |
15
+ | `gap` | `"none"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | `md` |
16
+ | `rowGap` | `"none"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
17
+ | `columnGap` | `"none"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
18
+ | `align` | `"start"` \| `"center"` \| `"end"` \| `"stretch"` | `stretch` |
19
+ | `justify` | `"start"` \| `"center"` \| `"end"` \| `"stretch"` | — |
20
+ | `width` | `"auto"` \| `"full"` \| `"fit"` \| `"screen"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
21
+ | `height` | `"auto"` \| `"full"` \| `"fit"` \| `"screen"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
22
+
23
+ ## Common AI Mistakes
24
+
25
+ - ❌ `<div style={{ display:'grid', gridTemplateColumns:'1fr 1fr 1fr' }}>`
26
+ → Use <Grid columns={3} gap="md">
27
+ - ❌ `columns="3" (string)`
28
+ → Use columns={3} or columns="auto-fit"
29
+ - ❌ `Nested div with inline grid-column for spanning`
30
+ → Wrap the cell in <GridItem colSpan={2}>
31
+ - ❌ `style={{ width: "100%" }} / style={{ height: 320 }}`
32
+ → Use the width / height prop: width="full", width="md", height="screen", etc.
33
+
34
+ ## Examples
35
+
36
+ **Three-column grid with a wide first cell**
37
+ ```tsx
38
+ <Grid columns={3} gap="lg">
39
+ <GridItem colSpan={2}><Card>Wide</Card></GridItem>
40
+ <Card>Two</Card>
41
+ <Card>Three</Card>
42
+ </Grid>
43
+ ```
44
+
45
+ **Responsive auto-fit grid**
46
+ ```tsx
47
+ <Grid columns="auto-fit" gap="md">
48
+ {items.map((i) => <Card key={i.id}>{i.title}</Card>)}
49
+ </Grid>
50
+ ```
@@ -0,0 +1,24 @@
1
+ # GridItem — AI Cheat Sheet
2
+ > Quick reference for Claude / Cursor / Copilot
3
+
4
+ **Child placement inside <Grid>. Sets column/row span and start lines. Renders a plain <div> (or `as`).**
5
+
6
+ ```ts
7
+ import { GridItem } from "@usevyre/react"
8
+ ```
9
+
10
+ ## Common AI Mistakes
11
+
12
+ - ❌ `GridItem outside a Grid`
13
+ → Place <GridItem> directly inside <Grid>
14
+
15
+ ## Examples
16
+
17
+ **Span two columns**
18
+ ```tsx
19
+ <Grid columns={4} gap="md">
20
+ <GridItem colSpan={2}>Featured</GridItem>
21
+ <div>a</div>
22
+ <div>b</div>
23
+ </Grid>
24
+ ```
@@ -45,4 +45,8 @@ Quick reference for AI agents — one file per component.
45
45
  - [Item](item.md) — Layout primitive for list rows, settings rows, and notification rows. Denser than Card — use Item (not Card) for repeated list rows.
46
46
  - [Kanban](kanban.md) — Drag-and-drop board: cards move between columns (or reorder within a column). CONTROLLED & data-driven like DataGrid. While dragging, a placeholder shows the exact drop position. Each card is wrapped in a Card (variant="outlined"); renderCard (React) / #card slot (Vue) can render ANY content incl. complex components (Avatar/Badge/Progress). Columns and cards accept an optional semantic color tint. Native HTML5 DnD, zero deps.
47
47
  - [Conversation](conversation.md) — Chat / inbox message thread. CONTROLLED & data-driven like Kanban — you own `value` (messages array) and append in your own send handler; Conversation holds no message state. Consecutive messages from the same author are grouped (avatar + name shown once), day separators are inserted on date change, and outgoing messages (authorId === currentUserId) align right.
48
+ - [Stack](stack.md) — Full one-dimensional flex layout primitive. USE INSTEAD OF <div style={{display:'flex'}}>. Covers the whole CSS flexbox surface (direction incl. reverse, wrap, align/justify/alignContent/alignSelf, grow/shrink/basis, per-axis gap) with token-locked spacing. Renders a plain <div> (or `as`).
49
+ - [Grid](grid.md) — Two-dimensional CSS grid primitive. Explicit column/row counts (or auto-fit), auto-flow control, token gap. Pair with GridItem for cell spanning/placement. Renders a plain <div> (or `as`).
50
+ - [GridItem](griditem.md) — Child placement inside <Grid>. Sets column/row span and start lines. Renders a plain <div> (or `as`).
51
+ - [Box](box.md) — Spacing-only container plus a controlled escape hatch. Token padding/margin with shorthand, per-axis (X/Y) and per-side (Top/Right/Bottom/Left) overrides. The `style` prop is an explicit anti-pattern escape hatch. Renders a plain <div> (or `as`).
48
52
  - [DateRangePicker](daterangepicker.md) — Start/end date range picker. Built on Calendar (mode=range) with a friendlier { from, to } object API, a two-month side-by-side view, and preset shortcuts. Use this for report/filter date ranges; use DatePicker for a single date.
@@ -21,6 +21,8 @@ import { Input } from "@usevyre/react"
21
21
  → Import Command from @usevyre/react for search palettes
22
22
  - ❌ `Vue: binding Input/Textarea value without v-model`
23
23
  → Use v-model on <Input>/<Textarea> in Vue; in React use value + onChange
24
+ - ❌ `padding / margin / marginTop (any spacing prop) on a useVyre component`
25
+ → Space BETWEEN components with <Stack gap> / <Grid gap>; space AROUND a block with <Box padding/margin> wrapping it
24
26
 
25
27
  ## Examples
26
28
 
@@ -0,0 +1,55 @@
1
+ # Stack — AI Cheat Sheet
2
+ > Quick reference for Claude / Cursor / Copilot
3
+
4
+ **Full one-dimensional flex layout primitive. USE INSTEAD OF <div style={{display:'flex'}}>. Covers the whole CSS flexbox surface (direction incl. reverse, wrap, align/justify/alignContent/alignSelf, grow/shrink/basis, per-axis gap) with token-locked spacing. Renders a plain <div> (or `as`).**
5
+
6
+ ```ts
7
+ import { Stack } from "@usevyre/react"
8
+ ```
9
+
10
+ ## Valid Props
11
+
12
+ | Prop | Values | Default |
13
+ |------|--------|---------|
14
+ | `direction` | `"row"` \| `"column"` \| `"row-reverse"` \| `"column-reverse"` | `row` |
15
+ | `gap` | `"none"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | `md` |
16
+ | `rowGap` | `"none"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
17
+ | `columnGap` | `"none"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
18
+ | `align` | `"start"` \| `"center"` \| `"end"` \| `"stretch"` \| `"baseline"` | `stretch` |
19
+ | `justify` | `"start"` \| `"center"` \| `"end"` \| `"between"` \| `"around"` \| `"evenly"` | `start` |
20
+ | `alignContent` | `"start"` \| `"center"` \| `"end"` \| `"stretch"` \| `"between"` \| `"around"` \| `"evenly"` | — |
21
+ | `alignSelf` | `"auto"` \| `"start"` \| `"center"` \| `"end"` \| `"stretch"` \| `"baseline"` | — |
22
+ | `wrap` | `"nowrap"` \| `"wrap"` \| `"wrap-reverse"` | `nowrap` |
23
+ | `basis` | `"none"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` \| `"auto"` \| `"content"` \| `"0"` | — |
24
+ | `width` | `"auto"` \| `"full"` \| `"fit"` \| `"screen"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
25
+ | `height` | `"auto"` \| `"full"` \| `"fit"` \| `"screen"` \| `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `"2xl"` | — |
26
+ | `inline` | `true` \| `false` | `false` |
27
+
28
+ ## Common AI Mistakes
29
+
30
+ - ❌ `<div style={{ display: 'flex', gap: 12 }}>`
31
+ → Use <Stack gap="md"> — gap is a token
32
+ - ❌ `gap={12} or gap="12px"`
33
+ → Use gap="none|xs|sm|md|lg|xl|2xl"
34
+ - ❌ `direction="vertical" / "horizontal"`
35
+ → Use direction="row" or "column" (also row-reverse / column-reverse)
36
+ - ❌ `style={{ width: "100%" }} / style={{ height: 320 }}`
37
+ → Use the width / height prop: width="full", width="md", height="screen", etc.
38
+
39
+ ## Examples
40
+
41
+ **Row, vertically centered, spaced apart**
42
+ ```tsx
43
+ <Stack direction="row" gap="md" align="center" justify="between">
44
+ <Avatar src={user.avatar} />
45
+ <Text>{user.name}</Text>
46
+ <Button>Edit</Button>
47
+ </Stack>
48
+ ```
49
+
50
+ **Wrapping grid-ish gallery with per-axis gap**
51
+ ```tsx
52
+ <Stack wrap="wrap" rowGap="lg" columnGap="md">
53
+ {tags.map((t) => <Tag key={t}>{t}</Tag>)}
54
+ </Stack>
55
+ ```
@@ -1,5 +1,5 @@
1
1
  # useVyre Design System Context
2
- # Version: 1.2.0
2
+ # Version: 1.6.0
3
3
 
4
4
  You are working in a codebase that uses the useVyre design system.
5
5
  Follow the rules below strictly when writing any UI code.
@@ -345,6 +345,7 @@ import { Button } from "@usevyre/react"
345
345
  - ❌ `color="..."` → Use variant prop instead
346
346
  - ❌ `icon={...}` → Use leftIcon={...} or rightIcon={...}
347
347
  - ❌ `size="icon" without aria-label` → Add aria-label describing the action
348
+ - ❌ `padding / margin / marginTop (any spacing prop) on a useVyre component` → Space BETWEEN components with <Stack gap> / <Grid gap>; space AROUND a block with <Box padding/margin> wrapping it
348
349
 
349
350
  ---
350
351
 
@@ -430,6 +431,7 @@ import { Card, CardHeader, CardBody, CardFooter } from "@usevyre/react"
430
431
 
431
432
  **Common mistakes:**
432
433
  - ❌ `variant="primary"` → Use variant="elevated" | "outlined" | "ghost" | "accent"
434
+ - ❌ `padding / margin / marginTop (any spacing prop) on a useVyre component` → Space BETWEEN components with <Stack gap> / <Grid gap>; space AROUND a block with <Box padding/margin> wrapping it
433
435
 
434
436
  ---
435
437
 
@@ -641,6 +643,7 @@ import { Input } from "@usevyre/react"
641
643
  - ❌ `size="icon"` → Use size="sm" | "md" | "lg"
642
644
  - ❌ `type="search" for search UI` → Import Command from @usevyre/react for search palettes
643
645
  - ❌ `Vue: binding Input/Textarea value without v-model` → Use v-model on <Input>/<Textarea> in Vue; in React use value + onChange
646
+ - ❌ `padding / margin / marginTop (any spacing prop) on a useVyre component` → Space BETWEEN components with <Stack gap> / <Grid gap>; space AROUND a block with <Box padding/margin> wrapping it
644
647
 
645
648
  ---
646
649
 
@@ -1383,6 +1386,157 @@ const messages = [
1383
1386
 
1384
1387
  ---
1385
1388
 
1389
+ ### Stack
1390
+
1391
+ Full one-dimensional flex layout primitive. USE INSTEAD OF <div style={{display:'flex'}}>. Covers the whole CSS flexbox surface (direction incl. reverse, wrap, align/justify/alignContent/alignSelf, grow/shrink/basis, per-axis gap) with token-locked spacing. Renders a plain <div> (or `as`).
1392
+
1393
+ ```tsx
1394
+ import { Stack } from "@usevyre/react"
1395
+
1396
+ // Props:
1397
+ // direction = "row" | "column" | "row-reverse" | "column-reverse" (default: row)
1398
+ // inline = boolean (default: false)
1399
+ // gap = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" (default: md)
1400
+ // rowGap = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1401
+ // columnGap = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1402
+ // align = "start" | "center" | "end" | "stretch" | "baseline" (default: stretch)
1403
+ // justify = "start" | "center" | "end" | "between" | "around" | "evenly" (default: start)
1404
+ // alignContent = "start" | "center" | "end" | "stretch" | "between" | "around" | "evenly"
1405
+ // alignSelf = "auto" | "start" | "center" | "end" | "stretch" | "baseline"
1406
+ // wrap = "nowrap" | "wrap" | "wrap-reverse" (default: nowrap)
1407
+ // grow = number
1408
+ // shrink = number
1409
+ // basis = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "auto" | "content" | "0"
1410
+ // width = "auto" | "full" | "fit" | "screen" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1411
+ // height = "auto" | "full" | "fit" | "screen" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1412
+ // as = string (default: div)
1413
+
1414
+ // Examples:
1415
+ <Stack direction="row" gap="md" align="center" justify="between">
1416
+ <Avatar src={user.avatar} />
1417
+ <Text>{user.name}</Text>
1418
+ <Button>Edit</Button>
1419
+ </Stack>
1420
+ <Stack wrap="wrap" rowGap="lg" columnGap="md">
1421
+ {tags.map((t) => <Tag key={t}>{t}</Tag>)}
1422
+ </Stack>
1423
+ ```
1424
+
1425
+ **Common mistakes:**
1426
+ - ❌ `<div style={{ display: 'flex', gap: 12 }}>` → Use <Stack gap="md"> — gap is a token
1427
+ - ❌ `gap={12} or gap="12px"` → Use gap="none|xs|sm|md|lg|xl|2xl"
1428
+ - ❌ `direction="vertical" / "horizontal"` → Use direction="row" or "column" (also row-reverse / column-reverse)
1429
+ - ❌ `style={{ width: "100%" }} / style={{ height: 320 }}` → Use the width / height prop: width="full", width="md", height="screen", etc.
1430
+
1431
+ ---
1432
+
1433
+ ### Grid
1434
+
1435
+ Two-dimensional CSS grid primitive. Explicit column/row counts (or auto-fit), auto-flow control, token gap. Pair with GridItem for cell spanning/placement. Renders a plain <div> (or `as`).
1436
+
1437
+ ```tsx
1438
+ import { Grid, GridItem } from "@usevyre/react"
1439
+
1440
+ // Props:
1441
+ // columns = number | "auto-fit" (default: 1)
1442
+ // rows = number | "auto"
1443
+ // flow = "row" | "column" | "dense" | "row-dense" | "column-dense"
1444
+ // gap = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" (default: md)
1445
+ // rowGap = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1446
+ // columnGap = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1447
+ // align = "start" | "center" | "end" | "stretch" (default: stretch)
1448
+ // justify = "start" | "center" | "end" | "stretch"
1449
+ // width = "auto" | "full" | "fit" | "screen" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1450
+ // height = "auto" | "full" | "fit" | "screen" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1451
+ // as = string (default: div)
1452
+
1453
+ // Examples:
1454
+ <Grid columns={3} gap="lg">
1455
+ <GridItem colSpan={2}><Card>Wide</Card></GridItem>
1456
+ <Card>Two</Card>
1457
+ <Card>Three</Card>
1458
+ </Grid>
1459
+ <Grid columns="auto-fit" gap="md">
1460
+ {items.map((i) => <Card key={i.id}>{i.title}</Card>)}
1461
+ </Grid>
1462
+ ```
1463
+
1464
+ **Common mistakes:**
1465
+ - ❌ `<div style={{ display:'grid', gridTemplateColumns:'1fr 1fr 1fr' }}>` → Use <Grid columns={3} gap="md">
1466
+ - ❌ `columns="3" (string)` → Use columns={3} or columns="auto-fit"
1467
+ - ❌ `Nested div with inline grid-column for spanning` → Wrap the cell in <GridItem colSpan={2}>
1468
+ - ❌ `style={{ width: "100%" }} / style={{ height: 320 }}` → Use the width / height prop: width="full", width="md", height="screen", etc.
1469
+
1470
+ ---
1471
+
1472
+ ### GridItem
1473
+
1474
+ Child placement inside <Grid>. Sets column/row span and start lines. Renders a plain <div> (or `as`).
1475
+
1476
+ ```tsx
1477
+ import { GridItem } from "@usevyre/react"
1478
+
1479
+ // Props:
1480
+ // colSpan = number
1481
+ // rowSpan = number
1482
+ // colStart = number
1483
+ // rowStart = number
1484
+ // as = string (default: div)
1485
+
1486
+ // Examples:
1487
+ <Grid columns={4} gap="md">
1488
+ <GridItem colSpan={2}>Featured</GridItem>
1489
+ <div>a</div>
1490
+ <div>b</div>
1491
+ </Grid>
1492
+ ```
1493
+
1494
+ **Common mistakes:**
1495
+ - ❌ `GridItem outside a Grid` → Place <GridItem> directly inside <Grid>
1496
+
1497
+ ---
1498
+
1499
+ ### Box
1500
+
1501
+ Spacing-only container plus a controlled escape hatch. Token padding/margin with shorthand, per-axis (X/Y) and per-side (Top/Right/Bottom/Left) overrides. The `style` prop is an explicit anti-pattern escape hatch. Renders a plain <div> (or `as`).
1502
+
1503
+ ```tsx
1504
+ import { Box } from "@usevyre/react"
1505
+
1506
+ // Props:
1507
+ // padding = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1508
+ // paddingX = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1509
+ // paddingY = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1510
+ // paddingTop = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1511
+ // paddingRight = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1512
+ // paddingBottom = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1513
+ // paddingLeft = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1514
+ // margin = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1515
+ // marginX = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1516
+ // marginY = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1517
+ // marginTop = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1518
+ // marginRight = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1519
+ // marginBottom = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1520
+ // marginLeft = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1521
+ // width = "auto" | "full" | "fit" | "screen" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1522
+ // height = "auto" | "full" | "fit" | "screen" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
1523
+ // as = string (default: div)
1524
+ // style = React.CSSProperties
1525
+
1526
+ // Examples:
1527
+ <Box as="section" paddingX="lg" paddingY="md">
1528
+ <Heading>Settings</Heading>
1529
+ </Box>
1530
+ <Box marginTop="xl"><Separator /></Box>
1531
+ ```
1532
+
1533
+ **Common mistakes:**
1534
+ - ❌ `<Box style={{ padding: 16 }}>` → Use <Box padding="md"> (or paddingX/paddingTop/...)
1535
+ - ❌ `Using Box for flex/grid layout` → Use <Stack> or <Grid>
1536
+ - ❌ `style={{ width: "100%" }} / style={{ height: 320 }}` → Use the width / height prop: width="full", width="md", height="screen", etc.
1537
+
1538
+ ---
1539
+
1386
1540
  ### DateRangePicker
1387
1541
 
1388
1542
  Start/end date range picker. Built on Calendar (mode=range) with a friendlier { from, to } object API, a two-month side-by-side view, and preset shortcuts. Use this for report/filter date ranges; use DatePicker for a single date.
@@ -1436,11 +1590,13 @@ If you generate these, you are hallucinating.
1436
1590
  - ❌ `<Button color="...">` → Use variant prop instead
1437
1591
  - ❌ `<Button icon={...}>` → Use leftIcon={...} or rightIcon={...}
1438
1592
  - ❌ `<Button size="icon" without aria-label>` → Add aria-label describing the action
1593
+ - ❌ `<Button padding / margin / marginTop (any spacing prop) on a useVyre component>` → Space BETWEEN components with <Stack gap> / <Grid gap>; space AROUND a block with <Box padding/margin> wrapping it
1439
1594
  - ❌ `<Calendar Calendar for an input field that opens a popover>` → Use <DatePicker /> (single date) or <DateRangePicker /> (range)
1440
1595
  - ❌ `<Calendar value as tuple for mode="single">` → Pass value matching mode; use mode="range" for [start,end]
1441
1596
  - ❌ `<DatePicker DatePicker mode="range" for { from, to } object>` → Use <DateRangePicker /> for the { from, to } object API + presets + dual month
1442
1597
  - ❌ `<DatePicker DatePicker without value/onChange>` → Provide value and onChange (e.g. from useState)
1443
1598
  - ❌ `<Card variant="primary">` → Use variant="elevated" | "outlined" | "ghost" | "accent"
1599
+ - ❌ `<Card padding / margin / marginTop (any spacing prop) on a useVyre component>` → Space BETWEEN components with <Stack gap> / <Grid gap>; space AROUND a block with <Box padding/margin> wrapping it
1444
1600
  - ❌ `<Checkbox size="lg">` → Use size="md"
1445
1601
  - ❌ `<RadioGroup <Radio> used outside a <RadioGroup>>` → Always wrap <Radio> in <RadioGroup>
1446
1602
  - ❌ `<RadioGroup RadioGroup without value/onChange (React) or v-model (Vue)>` → Bind value + onChange (React) or v-model (Vue); or defaultValue for uncontrolled in React
@@ -1455,6 +1611,7 @@ If you generate these, you are hallucinating.
1455
1611
  - ❌ `<Input size="icon">` → Use size="sm" | "md" | "lg"
1456
1612
  - ❌ `<Input type="search" for search UI>` → Import Command from @usevyre/react for search palettes
1457
1613
  - ❌ `<Input Vue: binding Input/Textarea value without v-model>` → Use v-model on <Input>/<Textarea> in Vue; in React use value + onChange
1614
+ - ❌ `<Input padding / margin / marginTop (any spacing prop) on a useVyre component>` → Space BETWEEN components with <Stack gap> / <Grid gap>; space AROUND a block with <Box padding/margin> wrapping it
1458
1615
  - ❌ `<Modal size="xl">` → Use size="lg" or size="full"
1459
1616
  - ❌ `<Popover placement="top-center">` → Use placement="top" for centered placement
1460
1617
  - ❌ `<Progress value > 100>` → Normalize your value to 0–100 range before passing
@@ -1491,6 +1648,18 @@ If you generate these, you are hallucinating.
1491
1648
  - ❌ `<Conversation Expecting Conversation to store/append messages>` → Append to your own state in onSend (or @send) and pass it back via value
1492
1649
  - ❌ `<Conversation composer without onSend (React) / @send (Vue)>` → Provide onSend / @send to append the message to value
1493
1650
  - ❌ `<Conversation Treating onSend as (text) only when using allowAttachments>` → Handle onSend(text, files) — map files to message attachments and append
1651
+ - ❌ `<Stack <div style={{ display: 'flex', gap: 12 }}>>` → Use <Stack gap="md"> — gap is a token
1652
+ - ❌ `<Stack gap={12} or gap="12px">` → Use gap="none|xs|sm|md|lg|xl|2xl"
1653
+ - ❌ `<Stack direction="vertical" / "horizontal">` → Use direction="row" or "column" (also row-reverse / column-reverse)
1654
+ - ❌ `<Stack style={{ width: "100%" }} / style={{ height: 320 }}>` → Use the width / height prop: width="full", width="md", height="screen", etc.
1655
+ - ❌ `<Grid <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr 1fr' }}>>` → Use <Grid columns={3} gap="md">
1656
+ - ❌ `<Grid columns="3" (string)>` → Use columns={3} or columns="auto-fit"
1657
+ - ❌ `<Grid Nested div with inline grid-column for spanning>` → Wrap the cell in <GridItem colSpan={2}>
1658
+ - ❌ `<Grid style={{ width: "100%" }} / style={{ height: 320 }}>` → Use the width / height prop: width="full", width="md", height="screen", etc.
1659
+ - ❌ `<GridItem GridItem outside a Grid>` → Place <GridItem> directly inside <Grid>
1660
+ - ❌ `<Box <Box style={{ padding: 16 }}>>` → Use <Box padding="md"> (or paddingX/paddingTop/...)
1661
+ - ❌ `<Box Using Box for flex/grid layout>` → Use <Stack> or <Grid>
1662
+ - ❌ `<Box style={{ width: "100%" }} / style={{ height: 320 }}>` → Use the width / height prop: width="full", width="md", height="screen", etc.
1494
1663
  - ❌ `<DateRangePicker value={[from, to]}>` → Use value={{ from, to }} and read range.from / range.to
1495
1664
  - ❌ `<DateRangePicker DateRangePicker for a single date>` → Use <DatePicker /> for a single date
1496
1665
  - ❌ `<DateRangePicker presets="true" (string)>` → Use the bare prop: presets (or presets={true})