start-vibing-stacks 2.17.0 → 2.19.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,97 +1,325 @@
1
1
  ---
2
2
  name: shadcn-ui
3
- version: 1.0.0
3
+ version: 2.0.0
4
+ description: "shadcn/ui CLI v4 (March 2026) for React 19 + Tailwind v4. Components updated to remove forwardRef (refs as props in R19), every primitive carries a data-slot attribute for targeted styling, HSL → OKLCH tokens, size-* utility replaces w-h pairs, default style deprecated in favor of new-york. CLI v4 brings shadcn/skills (AI agent context for component registry), --preset (shareable design-system bundle), --dry-run / --diff / --view (inspect changes before applying), --template scaffolds (Next.js, Vite, Laravel, React Router, Astro, TanStack Start), --base flag (Radix vs Base UI primitives), and `shadcn info` / `shadcn docs` commands for agents. Includes components.json schema, registry-item.json, blocks. Invoke when adding, customising, theming, or scaffolding shadcn components."
4
5
  ---
5
6
 
6
- # shadcn/ui — Component Library Patterns
7
+ # shadcn/ui — CLI v4 + React 19 + Tailwind v4 (2026)
7
8
 
8
- **ALWAYS invoke when adding or modifying shadcn/ui components.**
9
+ **ALWAYS invoke when adding, customising, theming, or scaffolding shadcn components.**
9
10
 
10
- ## Installation
11
+ > shadcn/ui is a copy-paste component system, not an npm dependency — components live **in your repo**, get owned and modified there. The CLI keeps them in sync with the upstream registry without hiding the source.
12
+
13
+ ## What's new in 2026 (CLI v4 — March 2026)
14
+
15
+ | Change | Impact |
16
+ |---|---|
17
+ | **Tailwind v4 + React 19 first-class** | All components updated; v3+R18 still works (non-breaking) |
18
+ | **`forwardRef` removed** | React 19 treats `ref` as a prop — components are simpler |
19
+ | **`data-slot="…"` on every primitive** | Style any sub-element from outside without overriding source |
20
+ | **HSL → OKLCH** colour tokens | Smoother gradients, perceptual uniformity |
21
+ | **`size-*` utility** | `size-9` instead of `w-9 h-9` |
22
+ | **`default` style deprecated** | Use **`new-york`** (the new default in `components.json`) |
23
+ | **`shadcn/skills`** | AI-agent registry context — agents discover components via the CLI |
24
+ | **`--preset` flag** | Pack colours/theme/fonts/radius into a shareable code string |
25
+ | **`--dry-run` / `--diff` / `--view`** | Inspect registry changes before writing files |
26
+ | **`--template`** | Scaffolds for Next.js, Vite, Laravel, React Router, Astro, TanStack Start |
27
+ | **`--base`** | Choose between **Radix** and **Base UI** primitives |
28
+ | **`shadcn info` / `shadcn docs`** | Context commands for agents and humans |
29
+
30
+ ## Initialisation
11
31
 
12
32
  ```bash
13
- npx shadcn@latest init
14
- npx shadcn@latest add button card dialog input
33
+ # Pick a template (CLI v4 — March 2026)
34
+ npx shadcn@latest init --template next-app
35
+ # Other templates: vite, laravel, react-router, astro, tanstack-start
36
+
37
+ # Add components — non-interactive, idempotent
38
+ npx shadcn@latest add button card dialog input form
39
+
40
+ # Inspect before writing (new in v4)
41
+ npx shadcn@latest add button --dry-run --diff
42
+
43
+ # Use Base UI primitives instead of Radix
44
+ npx shadcn@latest add dialog --base baseui
15
45
  ```
16
46
 
17
- ## Theming
47
+ ## `components.json` (Tailwind v4 shape)
48
+
49
+ ```json
50
+ {
51
+ "$schema": "https://ui.shadcn.com/schema.json",
52
+ "style": "new-york",
53
+ "rsc": true,
54
+ "tsx": true,
55
+ "tailwind": {
56
+ "config": "",
57
+ "css": "src/app/globals.css",
58
+ "baseColor": "neutral",
59
+ "cssVariables": true,
60
+ "prefix": ""
61
+ },
62
+ "aliases": {
63
+ "components": "@/components",
64
+ "utils": "@/lib/utils",
65
+ "ui": "@/components/ui",
66
+ "lib": "@/lib",
67
+ "hooks": "@/hooks"
68
+ },
69
+ "iconLibrary": "lucide"
70
+ }
71
+ ```
72
+
73
+ > For Tailwind v4 the `tailwind.config` field stays empty — there's no JS config file in v4.
74
+
75
+ ## Theming with OKLCH
18
76
 
19
77
  ```css
20
- /* globals.css — CSS variables for theming */
21
- @layer base {
22
- :root {
23
- --background: 0 0% 100%;
24
- --foreground: 222.2 84% 4.9%;
25
- --primary: 222.2 47.4% 11.2%;
26
- --primary-foreground: 210 40% 98%;
27
- --muted: 210 40% 96.1%;
28
- --muted-foreground: 215.4 16.3% 46.9%;
29
- --border: 214.3 31.8% 91.4%;
30
- --ring: 222.2 84% 4.9%;
31
- --radius: 0.5rem;
32
- }
33
- .dark {
34
- --background: 222.2 84% 4.9%;
35
- --foreground: 210 40% 98%;
36
- --primary: 210 40% 98%;
37
- --primary-foreground: 222.2 47.4% 11.2%;
38
- }
78
+ /* src/app/globals.css */
79
+ @import "tailwindcss";
80
+
81
+ @theme inline {
82
+ /* Light theme — OKLCH (replaces v1 HSL tokens) */
83
+ --color-background: oklch(1.000 0 0);
84
+ --color-foreground: oklch(0.145 0 0);
85
+
86
+ --color-primary: oklch(0.205 0 0);
87
+ --color-primary-foreground: oklch(0.985 0 0);
88
+
89
+ --color-secondary: oklch(0.970 0 0);
90
+ --color-secondary-foreground: oklch(0.205 0 0);
91
+
92
+ --color-muted: oklch(0.970 0 0);
93
+ --color-muted-foreground: oklch(0.556 0 0);
94
+
95
+ --color-destructive: oklch(0.577 0.245 27.325);
96
+ --color-destructive-foreground: oklch(0.985 0 0);
97
+
98
+ --color-border: oklch(0.922 0 0);
99
+ --color-ring: oklch(0.708 0 0);
100
+
101
+ --radius: 0.625rem; /* slightly larger than v1's 0.5rem */
102
+ }
103
+
104
+ @theme dark inline {
105
+ --color-background: oklch(0.145 0 0);
106
+ --color-foreground: oklch(0.985 0 0);
107
+ --color-primary: oklch(0.985 0 0);
108
+ --color-primary-foreground: oklch(0.205 0 0);
109
+ /* … rest of dark overrides */
110
+ }
111
+ ```
112
+
113
+ OKLCH ranges (rough guide): lightness 0–1, chroma 0–~0.4, hue 0–360°. Pick lightness on the same axis for siblings — gradients stay perceptually smooth.
114
+
115
+ ## Components without `forwardRef`
116
+
117
+ ```tsx
118
+ // React 19 — refs are props, no forwardRef needed
119
+ import * as React from "react";
120
+ import { cn } from "@/lib/utils";
121
+
122
+ function Button({
123
+ ref, // ← just a normal prop
124
+ className,
125
+ variant = "default",
126
+ size = "default",
127
+ ...props
128
+ }: React.ButtonHTMLAttributes<HTMLButtonElement> & {
129
+ ref?: React.Ref<HTMLButtonElement>;
130
+ variant?: "default" | "outline" | "ghost" | "destructive";
131
+ size?: "default" | "sm" | "lg" | "icon";
132
+ }) {
133
+ return (
134
+ <button
135
+ ref={ref}
136
+ data-slot="button" // ← every primitive carries data-slot
137
+ className={cn(buttonVariants({ variant, size }), className)}
138
+ {...props}
139
+ />
140
+ );
39
141
  }
142
+
143
+ export { Button };
144
+ ```
145
+
146
+ `forwardRef` still works — but the new components ship without it.
147
+
148
+ ## `data-slot` — style sub-parts from outside
149
+
150
+ ```tsx
151
+ // Style the icon inside a Button without touching the Button source
152
+ <Button className="[&_[data-slot=icon]]:size-4 [&_[data-slot=icon]]:text-primary">
153
+ <CheckIcon data-slot="icon" />
154
+ Confirm
155
+ </Button>
156
+
157
+ // Style the trigger of a Dialog from a parent
158
+ <Dialog>
159
+ <DialogTrigger className="[&[data-slot=trigger]]:rounded-full" asChild>
160
+ <Button>Open</Button>
161
+ </DialogTrigger>
162
+ </Dialog>
40
163
  ```
41
164
 
42
- ## Component Customization
165
+ This replaces the old "expose every internal class through props" pattern — the contract is the slot name, not the className.
166
+
167
+ ## Customisation — extend, don't fork
43
168
 
44
169
  ```tsx
45
170
  // CORRECT — extend via className + variants
46
- import { Button } from '@/components/ui/button';
47
- <Button variant="outline" size="lg" className="rounded-full">Custom</Button>
171
+ <Button variant="outline" size="lg" className="rounded-full">
172
+ Custom
173
+ </Button>
48
174
 
49
- // WRONGmodify component source for one-off styles
175
+ // CORRECTwrap a shadcn primitive when you need a project-specific variant
176
+ function PageHeading({ children, className, ...rest }: ComponentProps<"h1">) {
177
+ return (
178
+ <h1 data-slot="page-heading" className={cn("text-2xl font-semibold tracking-tight", className)} {...rest}>
179
+ {children}
180
+ </h1>
181
+ );
182
+ }
183
+
184
+ // WRONG — modifying the shadcn source for one-off styles
185
+ // → upgrade path breaks; intent gets lost
50
186
  ```
51
187
 
52
- ## Composition Pattern
188
+ ## Composition
53
189
 
54
190
  ```tsx
55
- import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
56
- import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog';
191
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
192
+ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
57
193
 
58
- // Compose primitives, don't create monolithic components
59
194
  <Dialog>
60
195
  <DialogTrigger asChild>
61
196
  <Button variant="outline">Open</Button>
62
197
  </DialogTrigger>
63
198
  <DialogContent>
64
199
  <DialogHeader>
65
- <DialogTitle>Title</DialogTitle>
200
+ <DialogTitle>Edit profile</DialogTitle>
66
201
  </DialogHeader>
67
- <Card><CardContent>...</CardContent></Card>
202
+ <Card>
203
+ <CardHeader>
204
+ <CardTitle>Account</CardTitle>
205
+ <CardDescription>Update your information.</CardDescription>
206
+ </CardHeader>
207
+ <CardContent>{/* form fields */}</CardContent>
208
+ </Card>
68
209
  </DialogContent>
69
210
  </Dialog>
70
211
  ```
71
212
 
72
- ## Form Pattern (with Zod)
213
+ ## Forms — shadcn Form + React Hook Form + Zod 4
73
214
 
74
215
  ```tsx
75
- import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form';
76
- import { useForm } from 'react-hook-form';
77
- import { zodResolver } from '@hookform/resolvers/zod';
78
-
79
- const form = useForm<z.infer<typeof schema>>({ resolver: zodResolver(schema) });
80
-
81
- <Form {...form}>
82
- <FormField control={form.control} name="email" render={({ field }) => (
83
- <FormItem>
84
- <FormLabel>Email</FormLabel>
85
- <FormControl><Input {...field} /></FormControl>
86
- <FormMessage />
87
- </FormItem>
88
- )} />
89
- </Form>
216
+ "use client";
217
+ import { z } from "zod";
218
+ import { useForm } from "react-hook-form";
219
+ import { zodResolver } from "@hookform/resolvers/zod";
220
+ import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
221
+ import { Input } from "@/components/ui/input";
222
+ import { Button } from "@/components/ui/button";
223
+
224
+ const Schema = z.object({
225
+ email: z.email("Enter a valid email"), // Zod 4 top-level
226
+ password: z.string().min(8, "At least 8 characters"),
227
+ });
228
+
229
+ type FormValues = z.infer<typeof Schema>;
230
+
231
+ export function LoginForm() {
232
+ const form = useForm<FormValues>({
233
+ resolver: zodResolver(Schema),
234
+ defaultValues: { email: "", password: "" },
235
+ });
236
+
237
+ function onSubmit(values: FormValues) { /* call your API */ }
238
+
239
+ return (
240
+ <Form {...form}>
241
+ <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
242
+ <FormField control={form.control} name="email" render={({ field }) => (
243
+ <FormItem>
244
+ <FormLabel>Email</FormLabel>
245
+ <FormControl><Input type="email" autoComplete="email" {...field} /></FormControl>
246
+ <FormMessage />
247
+ </FormItem>
248
+ )}/>
249
+ <FormField control={form.control} name="password" render={({ field }) => (
250
+ <FormItem>
251
+ <FormLabel>Password</FormLabel>
252
+ <FormControl><Input type="password" autoComplete="current-password" {...field} /></FormControl>
253
+ <FormMessage />
254
+ </FormItem>
255
+ )}/>
256
+ <Button type="submit" className="w-full">Sign in</Button>
257
+ </form>
258
+ </Form>
259
+ );
260
+ }
261
+ ```
262
+
263
+ ## Blocks — copy-paste full UI sections
264
+
265
+ ```bash
266
+ # List blocks (auth, dashboards, charts, sidebars, calendars, …)
267
+ npx shadcn@latest add --list-blocks
268
+
269
+ # Add a specific block
270
+ npx shadcn@latest add login-04
271
+ ```
272
+
273
+ Blocks are full sections (login pages, dashboard shells, billing screens) registered as `registry:block` in the catalog. They land in `components/` and you own them after that.
274
+
275
+ ## Custom registries
276
+
277
+ ```json
278
+ // registry-item.json — share components across your team / org
279
+ {
280
+ "$schema": "https://ui.shadcn.com/schema/registry-item.json",
281
+ "name": "data-table",
282
+ "type": "registry:component",
283
+ "dependencies": ["@tanstack/react-table"],
284
+ "registryDependencies": ["button", "input"],
285
+ "files": [{ "path": "components/data-table.tsx", "type": "registry:component" }]
286
+ }
287
+ ```
288
+
289
+ Host the JSON anywhere (GitHub Pages, Vercel) and consume:
290
+
291
+ ```bash
292
+ npx shadcn@latest add https://your-registry.com/r/data-table.json
293
+ ```
294
+
295
+ ## CLI v4 — workflow commands
296
+
297
+ ```bash
298
+ shadcn info # show project + dependency context (great for AI agents)
299
+ shadcn docs <component> # open docs for a specific component
300
+ shadcn add button --dry-run --view # show what would change, don't write
301
+ shadcn add button --diff # show diff against current files
302
+ shadcn add --preset <hash> # bootstrap an entire design-system from a preset hash
90
303
  ```
91
304
 
92
305
  ## FORBIDDEN
93
306
 
94
- 1. **Modifying component source for one-off needs** — use className/variants
95
- 2. **Installing without init** — always `npx shadcn@latest init` first
96
- 3. **Ignoring dark mode** all components must work in both themes
97
- 4. **Skipping accessibility** shadcn components have built-in a11y, don't break it
307
+ | Don't | Why |
308
+ |---|---|
309
+ | Modify component source for one-off styles | Use `className` + `variant` + slots |
310
+ | Skip `init` | The CLI needs `components.json` for paths/aliases |
311
+ | Stay on the deprecated `default` style | Use `new-york` (new CLI default) |
312
+ | Use `forwardRef` in new R19 components | Refs are plain props now |
313
+ | Add `w-10 h-10` instead of `size-10` | Tailwind v4 `size-*` is the recommended utility |
314
+ | HSL tokens for new themes | OKLCH gives smoother gradients & a11y-friendly mixing |
315
+ | Add a component then `npm install` it as a package | shadcn lives **in your repo**, never as a runtime dependency |
316
+ | Break built-in a11y (aria, focus, escape handlers) | Radix/Base UI primitives wire it correctly out of the box |
317
+
318
+ ## See Also
319
+
320
+ - `tailwind-patterns` v2 — `@theme`, container queries, OKLCH
321
+ - `react-patterns` v2 — refs as props in R19, `useActionState`, `useOptimistic`
322
+ - `react-standards` v2 — STYLES/LABELS const pattern that pairs with shadcn slots
323
+ - `zod-validation` v2 — Zod 4 + `@hookform/resolvers/zod`
324
+ - `react-ui-patterns` v2 — loading/error/empty states using shadcn primitives
325
+ - `_shared/skills/ui-ux-audit` v2 — WCAG 2.2 AA on shadcn components
@@ -1,21 +1,37 @@
1
1
  ---
2
2
  name: tailwind-patterns
3
- version: 1.0.0
3
+ version: 2.0.0
4
+ description: "Tailwind CSS v4 (stable Jan 22 2025) CSS-first design system with the Rust-based Oxide engine — 3.78× faster full builds, 8.8× faster incremental, 100× faster on no-CSS-change runs. CSS-first config via `@theme` directive (no `tailwind.config.js`), automatic content detection, native container queries (`@container` + `@md:`), OKLCH color space (perceptual uniformity), modern CSS features (cascade layers, `@property`, `color-mix()`), `@import \"tailwindcss\"` single line. Covers the v3 → v4 migration, semantic-token architecture, mobile-first + container-query responsive strategy, dark mode via `@theme dark`, and the 4px spacing scale. Invoke whenever writing Tailwind classes, theming a project, or designing responsive layouts."
4
5
  ---
5
6
 
6
- # TailwindCSS 4 — CSS-First Design System
7
+ # Tailwind CSS v4 — CSS-First Design System (2026)
7
8
 
8
9
  **ALWAYS invoke when writing Tailwind classes, theming, or responsive layouts.**
9
10
 
10
- ## What Changed (v3 → v4)
11
+ ## v4 Status (2026)
11
12
 
12
- | v3 (Legacy) | v4 (Current) |
13
+ - **Tailwind v4.0 stable**: January 22, 2025
14
+ - **Oxide engine** (Rust) — full builds **3.78× faster** (378ms → 100ms), incremental rebuilds **8.8× faster** (44ms → 5ms), no-CSS-change rebuilds **100× faster** (35ms → 192µs)
15
+ - **No `tailwind.config.js`** — config lives in CSS via `@theme`
16
+ - **Automatic content detection** — no `content: [...]` paths to maintain
17
+ - **Native container queries** — no plugin
18
+ - **OKLCH** color space everywhere (perceptual uniformity, smoother gradients)
19
+ - Built-in support for cascade layers, `@property`, `color-mix()`, modern CSS
20
+
21
+ ## v3 → v4 cheatsheet
22
+
23
+ | v3 (legacy) | v4 (current) |
13
24
  |---|---|
14
- | `tailwind.config.js` | CSS `@theme` directive |
15
- | PostCSS plugin | Oxide engine (10x faster) |
16
- | `@tailwind base/components/utilities` | `@import "tailwindcss"` |
17
- | Colors in JS config | Colors as CSS variables |
18
- | `@apply` everywhere | Components > `@apply` |
25
+ | `tailwind.config.js` (JS) | `@theme { … }` block (CSS) |
26
+ | `@tailwind base/components/utilities` | `@import "tailwindcss"` (single line) |
27
+ | `content: ["./src/**/*.tsx"]` | Auto-detected (no setup) |
28
+ | Colors in JS object | CSS variables (`--color-primary`) |
29
+ | HSL or hex tokens | **OKLCH** (recommended) |
30
+ | `@tailwindcss/container-queries` plugin | Native (`@container`, `@md:flex-row`) |
31
+ | `dark:` only | `dark:` **and** `@theme dark { … }` for token switching |
32
+ | `@apply` for everything | React components + tokens; reserve `@apply` for legacy CSS |
33
+
34
+ Migration is non-breaking for existing v3 codebases — both can coexist. Run `npx @tailwindcss/upgrade@latest` to automate the bulk.
19
35
 
20
36
  ## Setup (v4)
21
37
 
@@ -262,17 +278,60 @@ Section gaps: space-y-6 md:space-y-8
262
278
  Card padding: p-4 md:p-6
263
279
  ```
264
280
 
281
+ ## Modern CSS — leverage what v4 unlocks
282
+
283
+ ```css
284
+ /* color-mix() — derive variants from semantic tokens */
285
+ .btn-primary-soft {
286
+ background: color-mix(in oklch, var(--color-primary) 12%, transparent);
287
+ }
288
+
289
+ /* @property — animatable custom properties */
290
+ @property --gradient-angle {
291
+ syntax: '<angle>';
292
+ inherits: false;
293
+ initial-value: 0deg;
294
+ }
295
+
296
+ /* Cascade layers — predictable specificity (Tailwind already uses these) */
297
+ @layer components {
298
+ .card-hero { /* your custom layer */ }
299
+ }
300
+ ```
301
+
302
+ ## `size-*` utility (use over `w-N h-N`)
303
+
304
+ ```tsx
305
+ {/* OK — single utility, less repetition */}
306
+ <img className="size-10 rounded-full" />
307
+ <button className="size-9 grid place-items-center">
308
+
309
+ {/* Avoid the duplicate */}
310
+ <img className="w-10 h-10 rounded-full" />
311
+ ```
312
+
265
313
  ## FORBIDDEN
266
314
 
267
315
  | ❌ Don't | ✅ Do |
268
316
  |---|---|
269
317
  | `tailwind.config.js` in v4 | `@theme` in CSS |
270
- | `@apply` for everything | React components |
271
- | `!important` | Fix specificity |
318
+ | `@apply` for everything | React components + token classes |
319
+ | `!important` | Fix specificity (or use cascade layers) |
272
320
  | `style={{ color: 'red' }}` | `text-destructive` |
273
- | Arbitrary values for tokens | Define in `@theme` |
274
- | `bg-white dark:bg-gray-900` | `bg-background` (semantic) |
275
- | `@tailwind base` | `@import "tailwindcss"` (v4) |
276
- | Dynamic class strings | Static complete strings (purge-safe) |
277
- | `text-[#FF5733]` inline | `--color-accent` in `@theme` |
321
+ | Arbitrary values for design tokens (`text-[#2563eb]`) | Define `--color-*` in `@theme` |
322
+ | `bg-white dark:bg-gray-900` | `bg-background` (semantic + `@theme dark`) |
323
+ | `@tailwind base/components/utilities` | `@import "tailwindcss"` |
324
+ | Dynamic class strings (`bg-${color}-500`) | Static complete strings (Oxide can't see derived ones) |
325
+ | HSL tokens for new themes | OKLCH (perceptual uniformity, smoother gradients) |
326
+ | `w-10 h-10` pairs | `size-10` |
327
+ | `forwardRef`-style ref-as-prop indirection | Refs are just props in React 19 |
328
+ | `content: [...]` arrays | Auto-detection in v4 |
278
329
  | Inconsistent spacing | Follow 4px scale |
330
+
331
+ ## See Also
332
+
333
+ - `react-standards` — STYLES const pattern using these tokens
334
+ - `shadcn-ui` — components built on top of Tailwind v4 + OKLCH + `data-slot`
335
+ - `preline-ui` — alternative token system on top of Tailwind v4
336
+ - `react-ui-patterns` — loading/error/empty states using semantic tokens
337
+ - `_shared/skills/ui-ux-audit` — WCAG 2.2 AA contrast checks against semantic tokens