picasso-skill 1.5.1 → 2.0.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 (44) hide show
  1. package/agents/picasso.md +14 -2
  2. package/checklists/pre-ship.md +83 -0
  3. package/commands/backlog.md +34 -0
  4. package/commands/variants.md +18 -0
  5. package/package.json +3 -1
  6. package/references/accessibility-wcag.md +245 -0
  7. package/references/anti-patterns.md +184 -0
  8. package/references/color-and-contrast.md +477 -0
  9. package/references/component-patterns.md +113 -0
  10. package/references/conversion-design.md +193 -0
  11. package/references/data-visualization.md +226 -0
  12. package/references/depth-and-elevation.md +211 -0
  13. package/references/design-system.md +176 -0
  14. package/references/generative-art.md +648 -0
  15. package/references/interaction-design.md +162 -0
  16. package/references/modern-css-performance.md +361 -0
  17. package/references/motion-and-animation.md +267 -0
  18. package/references/performance-optimization.md +746 -0
  19. package/references/react-patterns.md +318 -0
  20. package/references/responsive-design.md +452 -0
  21. package/references/sensory-design.md +369 -0
  22. package/references/spatial-design.md +176 -0
  23. package/references/style-presets.md +502 -0
  24. package/references/tools-catalog.md +103 -0
  25. package/references/typography.md +415 -0
  26. package/references/ux-psychology.md +235 -0
  27. package/references/ux-writing.md +513 -0
  28. package/skills/picasso/SKILL.md +58 -2
  29. package/skills/picasso/references/animation-performance.md +244 -0
  30. package/skills/picasso/references/brand-and-identity.md +136 -0
  31. package/skills/picasso/references/code-typography.md +222 -0
  32. package/skills/picasso/references/color-and-contrast.md +56 -2
  33. package/skills/picasso/references/dark-mode.md +199 -0
  34. package/skills/picasso/references/depth-and-elevation.md +211 -0
  35. package/skills/picasso/references/i18n-visual-patterns.md +177 -0
  36. package/skills/picasso/references/images-and-media.md +222 -0
  37. package/skills/picasso/references/loading-and-states.md +258 -0
  38. package/skills/picasso/references/micro-interactions.md +291 -0
  39. package/skills/picasso/references/motion-and-animation.md +9 -2
  40. package/skills/picasso/references/navigation-patterns.md +247 -0
  41. package/skills/picasso/references/style-presets.md +1 -1
  42. package/skills/picasso/references/tables-and-forms.md +227 -0
  43. package/skills/picasso/references/tools-catalog.md +103 -0
  44. package/skills/picasso/references/typography.md +45 -2
@@ -0,0 +1,318 @@
1
+ # React Patterns Reference
2
+
3
+ ## Table of Contents
4
+ 1. Component Architecture
5
+ 2. React 19 Features
6
+ 3. State Management
7
+ 4. Performance
8
+ 5. Composition Patterns
9
+ 6. Data Fetching & Mutations
10
+ 7. Styling & Tailwind v4
11
+ 8. Dark Mode Toggle
12
+ 9. Common Mistakes
13
+
14
+ ---
15
+
16
+ ## 1. Component Architecture
17
+
18
+ ### Server vs. Client Components
19
+ Default to Server Components. Add `'use client'` only when the component needs:
20
+ - Event handlers (onClick, onChange, etc.)
21
+ - useState, useEffect, useRef, or other hooks
22
+ - Browser APIs (window, document, navigator)
23
+ - Third-party libraries that use hooks or browser APIs
24
+
25
+ ### File Organization
26
+ Colocate related files. Keep components, styles, tests, and types in the same directory:
27
+ ```
28
+ components/
29
+ user-card/
30
+ user-card.tsx
31
+ user-card.test.tsx
32
+ types.ts
33
+ ```
34
+
35
+ ### Naming
36
+ - Components: PascalCase (`UserCard`, `DashboardHeader`)
37
+ - Files: kebab-case (`user-card.tsx`, `dashboard-header.tsx`)
38
+ - Hooks: camelCase with `use` prefix (`useAuth`, `useMediaQuery`)
39
+ - Event handlers: `handle` + event (`handleClick`, `handleSubmit`)
40
+ - Boolean props: `is`/`has`/`should` prefix (`isLoading`, `hasError`)
41
+
42
+ ### Export Patterns
43
+ - **Default export**: page/route components and layout components
44
+ - **Named export**: everything else (utilities, hooks, shared components)
45
+
46
+ ---
47
+
48
+ ## 2. React 19 Features
49
+
50
+ ### The `use` Hook
51
+ Read promises and context directly in render. Works inside conditionals and loops unlike other hooks:
52
+ ```tsx
53
+ function UserProfile({ userPromise }: { userPromise: Promise<User> }) {
54
+ const user = use(userPromise); // suspends until resolved
55
+ return <h1>{user.name}</h1>;
56
+ }
57
+ ```
58
+
59
+ ### `useActionState` for Form Actions
60
+ Manages form state, pending status, and server action results in one hook:
61
+ ```tsx
62
+ 'use client';
63
+ import { useActionState } from 'react';
64
+ import { submitForm } from './actions';
65
+
66
+ function ContactForm() {
67
+ const [state, formAction, isPending] = useActionState(submitForm, { message: '' });
68
+ return (
69
+ <form action={formAction}>
70
+ <input name="email" type="email" required />
71
+ <button disabled={isPending}>{isPending ? 'Sending...' : 'Submit'}</button>
72
+ </form>
73
+ );
74
+ }
75
+ ```
76
+
77
+ ### `useFormStatus` for Submission State
78
+ Access the parent form's pending state from within child components:
79
+ ```tsx
80
+ 'use client';
81
+ import { useFormStatus } from 'react-dom';
82
+
83
+ function SubmitButton() {
84
+ const { pending } = useFormStatus();
85
+ return <button disabled={pending}>{pending ? 'Saving...' : 'Save'}</button>;
86
+ }
87
+ ```
88
+
89
+ ### `useOptimistic` for Instant Feedback
90
+ Show optimistic state while an async action completes:
91
+ ```tsx
92
+ const [optimistic, addOptimistic] = useOptimistic(
93
+ messages,
94
+ (current, newMsg: string) => [...current, { text: newMsg, pending: true }]
95
+ );
96
+ // Call addOptimistic(value) before await -- renders instantly, reverts on error
97
+ ```
98
+
99
+ ### React Compiler
100
+ React 19 ships with an opt-in compiler that auto-memoizes components, hooks, and expressions. When the compiler is enabled, remove manual `React.memo`, `useMemo`, and `useCallback` calls -- the compiler handles it. Check your project's `react-compiler` config before deciding whether to memoize manually.
101
+
102
+ ---
103
+
104
+ ## 3. State Management
105
+
106
+ ### Where State Lives
107
+ 1. **URL state**: filters, pagination, search queries (use `searchParams`)
108
+ 2. **Server state**: data from APIs (use server components or React Query/SWR for client)
109
+ 3. **Local state**: form inputs, UI toggles, hover/focus state (use `useState`)
110
+ 4. **Shared local state**: state needed by siblings (lift to parent, or use context)
111
+ 5. **Global state**: rarely needed (auth user, theme preference, feature flags)
112
+
113
+ ### Rules
114
+ - Do not store derived state. Compute it during render.
115
+ - Do not sync state between sources. Pick one source of truth.
116
+ - Prefer `useReducer` over `useState` when the next state depends on the previous state or when managing more than 3 related state variables.
117
+
118
+ ```tsx
119
+ // Bad: derived state in useEffect // Good: compute during render
120
+ const [filtered, setFiltered] = useState([]); const filtered = items.filter(i => i.active);
121
+ useEffect(() => setFiltered(items.filter(i => i.active)), [items]);
122
+ ```
123
+
124
+ ---
125
+
126
+ ## 4. Performance
127
+
128
+ ### Rendering
129
+ - With React Compiler enabled: skip manual `React.memo`, `useMemo`, `useCallback`
130
+ - Without the compiler: use `React.memo` only for components that re-render often with the same props; use `useMemo` for expensive computations only; use `useCallback` for callbacks passed to memoized children
131
+ - Use `key` props correctly (stable, unique identifiers, never array indices for reorderable lists)
132
+
133
+ ### Code Splitting
134
+ Use `React.lazy` + `Suspense` for client components (works in Next.js App Router and plain React):
135
+ ```tsx
136
+ const Chart = lazy(() => import('./chart'));
137
+ // Wrap in <Suspense fallback={<ChartSkeleton />}><Chart /></Suspense>
138
+ ```
139
+ Next.js App Router also provides automatic route-level splitting per `page.tsx`/`layout.tsx`.
140
+
141
+ ### Virtualization
142
+ For lists with 100+ items, use `@tanstack/virtual` or `react-window`.
143
+
144
+ ### Image Optimization
145
+ Use `next/image` in Next.js or `loading="lazy"` with explicit `width`/`height`. Always set `aspect-ratio` to prevent layout shift.
146
+
147
+ ---
148
+
149
+ ## 5. Composition Patterns
150
+
151
+ ### Compound Components
152
+ Components that share implicit state through context (e.g., `<Select>`, `<Select.Trigger>`, `<Select.Item>` pattern). Parent holds state, children consume via context.
153
+
154
+ ### Slot Pattern
155
+ Flexible composition through named children (`header`, `children`, `footer` as props). Avoids rigid component trees and enables flexible layouts without render props.
156
+
157
+ ---
158
+
159
+ ## 6. Data Fetching & Mutations
160
+
161
+ ### Server Components (preferred for reads)
162
+ ```tsx
163
+ async function UserList() {
164
+ const users = await fetch('/api/users').then(r => r.json());
165
+ return <ul>{users.map(u => <li key={u.id}>{u.name}</li>)}</ul>;
166
+ }
167
+ ```
168
+
169
+ ### Server Actions (preferred for mutations)
170
+ Define actions in a `'use server'` file and call from client components via form `action`:
171
+ ```tsx
172
+ // actions.ts
173
+ 'use server';
174
+ import { revalidatePath } from 'next/cache';
175
+
176
+ export async function createTodo(formData: FormData) {
177
+ await db.todo.create({ data: { title: formData.get('title') as string } });
178
+ revalidatePath('/todos');
179
+ }
180
+ ```
181
+ ```tsx
182
+ // todo-form.tsx -- 'use client'
183
+ import { createTodo } from './actions';
184
+ export default function TodoForm() {
185
+ return <form action={createTodo}><input name="title" required /><button>Add</button></form>;
186
+ }
187
+ ```
188
+
189
+ Server Actions handle serialization, error boundaries, and progressive enhancement. Prefer them over API route handlers for mutations.
190
+
191
+ ### Client-Side with Suspense + Error Boundaries
192
+ Always wrap data-fetching components:
193
+ ```tsx
194
+ <ErrorBoundary fallback={<ErrorMessage />}>
195
+ <Suspense fallback={<Skeleton />}>
196
+ <DataComponent />
197
+ </Suspense>
198
+ </ErrorBoundary>
199
+ ```
200
+
201
+ ---
202
+
203
+ ## 7. Styling & Tailwind v4
204
+
205
+ ### Tailwind v4 Changes
206
+ Tailwind v4 uses a CSS-first configuration model. Key differences from v3:
207
+
208
+ - **No `tailwind.config.js`**: configuration lives in CSS using the `@theme` directive
209
+ - **New import**: use `@import "tailwindcss"` instead of `@tailwind base/components/utilities` directives
210
+ - **CSS variables for all tokens**: every design token is automatically exposed as a CSS custom property (`--color-blue-500`, `--spacing-4`, etc.)
211
+
212
+ ```css
213
+ /* app/globals.css */
214
+ @import "tailwindcss";
215
+
216
+ @theme {
217
+ --color-brand: #6366f1;
218
+ --color-surface: #ffffff;
219
+ --color-surface-dark: #0f172a;
220
+ --font-display: "Inter", sans-serif;
221
+ --breakpoint-3xl: 1920px;
222
+ }
223
+ ```
224
+
225
+ You can reference these tokens anywhere in CSS or JS via `var(--color-brand)` without any build-step workaround.
226
+
227
+ ### Tailwind Best Practices
228
+ - Use Tailwind's core utility classes (pre-defined classes only in Claude artifacts)
229
+ - Extract repeated patterns into component variants, not `@apply` rules
230
+ - Use CSS variables for theme values, Tailwind utilities for everything else
231
+ - Never use more than ~10 utility classes on a single element; extract a component instead
232
+
233
+ ### CSS Modules
234
+ For non-Tailwind projects:
235
+ ```tsx
236
+ import styles from './button.module.css';
237
+ <button className={styles.primary}>Click</button>
238
+ ```
239
+
240
+ ### Semantic HTML
241
+ Use the right element: `<nav>` for navigation, `<main>` for primary content, `<section>` for thematic grouping, `<article>` for self-contained content, `<button>` for actions, `<a>` for navigation. Do not use bare `div` where semantic elements apply.
242
+
243
+ ---
244
+
245
+ ## 8. Dark Mode Toggle
246
+
247
+ Complete dark mode implementation with localStorage persistence, system preference detection, and flash prevention.
248
+
249
+ ### Blocking Script (prevents flash of wrong theme)
250
+ Place inline in `<head>` before stylesheets (in Next.js, use `<script dangerouslySetInnerHTML>` in `app/layout.tsx`):
251
+ ```html
252
+ <script>
253
+ (function() {
254
+ var s = localStorage.getItem('theme');
255
+ var theme = s || (matchMedia('(prefers-color-scheme:dark)').matches ? 'dark' : 'light');
256
+ document.documentElement.setAttribute('data-theme', theme);
257
+ })();
258
+ </script>
259
+ ```
260
+
261
+ ### Theme Toggle Hook
262
+ ```tsx
263
+ 'use client';
264
+ function useTheme() {
265
+ const [theme, setThemeState] = useState<'light' | 'dark'>(() =>
266
+ typeof window === 'undefined' ? 'light'
267
+ : (document.documentElement.getAttribute('data-theme') as 'light' | 'dark') || 'light'
268
+ );
269
+ const setTheme = useCallback((next: 'light' | 'dark') => {
270
+ document.documentElement.setAttribute('data-theme', next);
271
+ localStorage.setItem('theme', next);
272
+ setThemeState(next);
273
+ }, []);
274
+ const toggle = useCallback(() => setTheme(theme === 'dark' ? 'light' : 'dark'), [theme, setTheme]);
275
+ // Listen for system preference changes when no explicit choice is stored
276
+ useEffect(() => {
277
+ const mq = matchMedia('(prefers-color-scheme: dark)');
278
+ const h = (e: MediaQueryListEvent) => { if (!localStorage.getItem('theme')) setTheme(e.matches ? 'dark' : 'light'); };
279
+ mq.addEventListener('change', h);
280
+ return () => mq.removeEventListener('change', h);
281
+ }, [setTheme]);
282
+ return { theme, setTheme, toggle };
283
+ }
284
+ ```
285
+
286
+ ### CSS Setup with Tailwind v4
287
+ ```css
288
+ @import "tailwindcss";
289
+
290
+ @theme {
291
+ --color-bg: #ffffff;
292
+ --color-text: #0f172a;
293
+ --color-surface: #f8fafc;
294
+ }
295
+
296
+ [data-theme="dark"] {
297
+ --color-bg: #0f172a;
298
+ --color-text: #f8fafc;
299
+ --color-surface: #1e293b;
300
+ }
301
+ ```
302
+
303
+ ---
304
+
305
+ ## 9. Common Mistakes
306
+
307
+ - Using `useEffect` for derived state (compute during render instead)
308
+ - Putting everything in global state (most state should be local or server-derived)
309
+ - Using `index` as `key` for dynamic lists
310
+ - Wrapping every component in `React.memo` (let the React Compiler handle this)
311
+ - Using `any` in TypeScript (defeats the purpose of type safety)
312
+ - Fetching data in `useEffect` when a server component would suffice
313
+ - Not using Suspense boundaries (the whole page flashes instead of parts loading independently)
314
+ - Prop drilling through 5+ levels (use composition or context)
315
+ - Using API route handlers for mutations when Server Actions are simpler
316
+ - Not using `useOptimistic` for actions that need instant visual feedback
317
+ - Manual memoization when the React Compiler is enabled (causes unnecessary code noise)
318
+ - Using `@tailwind` directives or `tailwind.config.js` in Tailwind v4 projects (use `@import "tailwindcss"` and `@theme` instead)