autoworkflow 3.1.4 → 3.5.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 (123) hide show
  1. package/.claude/commands/analyze.md +19 -0
  2. package/.claude/commands/audit.md +174 -11
  3. package/.claude/commands/build.md +39 -0
  4. package/.claude/commands/commit.md +25 -0
  5. package/.claude/commands/fix.md +23 -0
  6. package/.claude/commands/plan.md +18 -0
  7. package/.claude/commands/suggest.md +23 -0
  8. package/.claude/commands/verify.md +18 -0
  9. package/.claude/hooks/post-bash-router.sh +20 -0
  10. package/.claude/hooks/post-commit.sh +140 -0
  11. package/.claude/hooks/pre-edit.sh +129 -0
  12. package/.claude/hooks/session-check.sh +79 -0
  13. package/.claude/settings.json +40 -6
  14. package/.claude/settings.local.json +3 -1
  15. package/.claude/skills/actix.md +337 -0
  16. package/.claude/skills/alembic.md +504 -0
  17. package/.claude/skills/angular.md +237 -0
  18. package/.claude/skills/api-design.md +187 -0
  19. package/.claude/skills/aspnet-core.md +377 -0
  20. package/.claude/skills/astro.md +245 -0
  21. package/.claude/skills/auth-clerk.md +327 -0
  22. package/.claude/skills/auth-firebase.md +367 -0
  23. package/.claude/skills/auth-nextauth.md +359 -0
  24. package/.claude/skills/auth-supabase.md +368 -0
  25. package/.claude/skills/axum.md +386 -0
  26. package/.claude/skills/blazor.md +456 -0
  27. package/.claude/skills/chi.md +348 -0
  28. package/.claude/skills/code-review.md +133 -0
  29. package/.claude/skills/csharp.md +296 -0
  30. package/.claude/skills/css-modules.md +325 -0
  31. package/.claude/skills/cypress.md +343 -0
  32. package/.claude/skills/debugging.md +133 -0
  33. package/.claude/skills/diesel.md +392 -0
  34. package/.claude/skills/django.md +301 -0
  35. package/.claude/skills/docker.md +319 -0
  36. package/.claude/skills/doctrine.md +473 -0
  37. package/.claude/skills/documentation.md +182 -0
  38. package/.claude/skills/dotnet.md +409 -0
  39. package/.claude/skills/drizzle.md +293 -0
  40. package/.claude/skills/echo.md +321 -0
  41. package/.claude/skills/eloquent.md +256 -0
  42. package/.claude/skills/emotion.md +426 -0
  43. package/.claude/skills/entity-framework.md +370 -0
  44. package/.claude/skills/express.md +316 -0
  45. package/.claude/skills/fastapi.md +329 -0
  46. package/.claude/skills/fastify.md +299 -0
  47. package/.claude/skills/fiber.md +315 -0
  48. package/.claude/skills/flask.md +322 -0
  49. package/.claude/skills/gin.md +342 -0
  50. package/.claude/skills/git.md +116 -0
  51. package/.claude/skills/github-actions.md +353 -0
  52. package/.claude/skills/go.md +377 -0
  53. package/.claude/skills/gorm.md +409 -0
  54. package/.claude/skills/graphql.md +478 -0
  55. package/.claude/skills/hibernate.md +379 -0
  56. package/.claude/skills/hono.md +306 -0
  57. package/.claude/skills/java.md +400 -0
  58. package/.claude/skills/jest.md +313 -0
  59. package/.claude/skills/jpa.md +282 -0
  60. package/.claude/skills/kotlin.md +347 -0
  61. package/.claude/skills/kubernetes.md +363 -0
  62. package/.claude/skills/laravel.md +414 -0
  63. package/.claude/skills/mcp-browser.md +320 -0
  64. package/.claude/skills/mcp-database.md +219 -0
  65. package/.claude/skills/mcp-fetch.md +241 -0
  66. package/.claude/skills/mcp-filesystem.md +204 -0
  67. package/.claude/skills/mcp-github.md +217 -0
  68. package/.claude/skills/mcp-memory.md +240 -0
  69. package/.claude/skills/mcp-search.md +218 -0
  70. package/.claude/skills/mcp-slack.md +262 -0
  71. package/.claude/skills/micronaut.md +388 -0
  72. package/.claude/skills/mongodb.md +319 -0
  73. package/.claude/skills/mongoose.md +355 -0
  74. package/.claude/skills/mysql.md +281 -0
  75. package/.claude/skills/nestjs.md +335 -0
  76. package/.claude/skills/nextjs-app-router.md +260 -0
  77. package/.claude/skills/nextjs-pages.md +172 -0
  78. package/.claude/skills/nuxt.md +202 -0
  79. package/.claude/skills/openapi.md +489 -0
  80. package/.claude/skills/performance.md +199 -0
  81. package/.claude/skills/php.md +398 -0
  82. package/.claude/skills/playwright.md +371 -0
  83. package/.claude/skills/postgresql.md +257 -0
  84. package/.claude/skills/prisma.md +293 -0
  85. package/.claude/skills/pydantic.md +304 -0
  86. package/.claude/skills/pytest.md +313 -0
  87. package/.claude/skills/python.md +272 -0
  88. package/.claude/skills/quarkus.md +377 -0
  89. package/.claude/skills/react.md +230 -0
  90. package/.claude/skills/redis.md +391 -0
  91. package/.claude/skills/refactoring.md +143 -0
  92. package/.claude/skills/remix.md +246 -0
  93. package/.claude/skills/rest-api.md +490 -0
  94. package/.claude/skills/rocket.md +366 -0
  95. package/.claude/skills/rust.md +341 -0
  96. package/.claude/skills/sass.md +380 -0
  97. package/.claude/skills/sea-orm.md +382 -0
  98. package/.claude/skills/security.md +167 -0
  99. package/.claude/skills/sequelize.md +395 -0
  100. package/.claude/skills/spring-boot.md +416 -0
  101. package/.claude/skills/sqlalchemy.md +269 -0
  102. package/.claude/skills/sqlx-rust.md +408 -0
  103. package/.claude/skills/state-jotai.md +346 -0
  104. package/.claude/skills/state-mobx.md +353 -0
  105. package/.claude/skills/state-pinia.md +431 -0
  106. package/.claude/skills/state-redux.md +337 -0
  107. package/.claude/skills/state-tanstack-query.md +434 -0
  108. package/.claude/skills/state-zustand.md +340 -0
  109. package/.claude/skills/styled-components.md +403 -0
  110. package/.claude/skills/svelte.md +238 -0
  111. package/.claude/skills/sveltekit.md +207 -0
  112. package/.claude/skills/symfony.md +437 -0
  113. package/.claude/skills/tailwind.md +279 -0
  114. package/.claude/skills/terraform.md +394 -0
  115. package/.claude/skills/testing-library.md +371 -0
  116. package/.claude/skills/trpc.md +426 -0
  117. package/.claude/skills/typeorm.md +368 -0
  118. package/.claude/skills/vitest.md +330 -0
  119. package/.claude/skills/vue.md +202 -0
  120. package/.claude/skills/warp.md +365 -0
  121. package/README.md +135 -52
  122. package/package.json +1 -1
  123. package/system/triggers.md +152 -11
@@ -0,0 +1,403 @@
1
+ # Styled Components Skill
2
+
3
+ ## Basic Usage
4
+ \`\`\`tsx
5
+ import styled from 'styled-components';
6
+
7
+ // Basic styled component
8
+ const Container = styled.div\`
9
+ max-width: 1200px;
10
+ margin: 0 auto;
11
+ padding: 0 1rem;
12
+ \`;
13
+
14
+ // With pseudo-selectors
15
+ const Button = styled.button\`
16
+ padding: 0.5rem 1rem;
17
+ background: #3b82f6;
18
+ color: white;
19
+ border: none;
20
+ border-radius: 0.375rem;
21
+ cursor: pointer;
22
+ transition: background 0.2s;
23
+
24
+ &:hover {
25
+ background: #2563eb;
26
+ }
27
+
28
+ &:focus {
29
+ outline: none;
30
+ box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.5);
31
+ }
32
+
33
+ &:disabled {
34
+ opacity: 0.5;
35
+ cursor: not-allowed;
36
+ }
37
+ \`;
38
+
39
+ // Nesting
40
+ const Card = styled.div\`
41
+ padding: 1.5rem;
42
+ border-radius: 0.5rem;
43
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
44
+
45
+ h2 {
46
+ margin: 0 0 1rem;
47
+ font-size: 1.25rem;
48
+ }
49
+
50
+ p {
51
+ color: #6b7280;
52
+ }
53
+ \`;
54
+ \`\`\`
55
+
56
+ ## Props & Dynamic Styles
57
+ \`\`\`tsx
58
+ // TypeScript props interface
59
+ interface ButtonProps {
60
+ variant?: 'primary' | 'secondary' | 'danger';
61
+ size?: 'sm' | 'md' | 'lg';
62
+ fullWidth?: boolean;
63
+ }
64
+
65
+ const Button = styled.button<ButtonProps>\`
66
+ /* Dynamic styles based on props */
67
+ padding: \${({ size }) => {
68
+ switch (size) {
69
+ case 'sm': return '0.25rem 0.5rem';
70
+ case 'lg': return '0.75rem 1.5rem';
71
+ default: return '0.5rem 1rem';
72
+ }
73
+ }};
74
+
75
+ background: \${({ variant }) => {
76
+ switch (variant) {
77
+ case 'secondary': return '#6b7280';
78
+ case 'danger': return '#ef4444';
79
+ default: return '#3b82f6';
80
+ }
81
+ }};
82
+
83
+ width: \${({ fullWidth }) => fullWidth ? '100%' : 'auto'};
84
+
85
+ font-size: \${({ size }) => size === 'sm' ? '0.875rem' : '1rem'};
86
+ \`;
87
+
88
+ // Usage
89
+ <Button variant="primary" size="lg" fullWidth>Submit</Button>
90
+ \`\`\`
91
+
92
+ ## Theming
93
+ \`\`\`tsx
94
+ // theme.ts
95
+ export const theme = {
96
+ colors: {
97
+ primary: '#3b82f6',
98
+ secondary: '#6b7280',
99
+ danger: '#ef4444',
100
+ success: '#10b981',
101
+ background: '#ffffff',
102
+ text: '#1f2937',
103
+ textMuted: '#6b7280',
104
+ },
105
+ spacing: {
106
+ xs: '0.25rem',
107
+ sm: '0.5rem',
108
+ md: '1rem',
109
+ lg: '1.5rem',
110
+ xl: '2rem',
111
+ },
112
+ borderRadius: {
113
+ sm: '0.25rem',
114
+ md: '0.375rem',
115
+ lg: '0.5rem',
116
+ full: '9999px',
117
+ },
118
+ shadows: {
119
+ sm: '0 1px 2px rgba(0, 0, 0, 0.05)',
120
+ md: '0 4px 6px rgba(0, 0, 0, 0.1)',
121
+ lg: '0 10px 15px rgba(0, 0, 0, 0.1)',
122
+ },
123
+ };
124
+
125
+ export type Theme = typeof theme;
126
+
127
+ // styled.d.ts - TypeScript declaration
128
+ import 'styled-components';
129
+ declare module 'styled-components' {
130
+ export interface DefaultTheme extends Theme {}
131
+ }
132
+
133
+ // App.tsx - Provider setup
134
+ import { ThemeProvider } from 'styled-components';
135
+ import { theme } from './theme';
136
+
137
+ function App() {
138
+ return (
139
+ <ThemeProvider theme={theme}>
140
+ <YourApp />
141
+ </ThemeProvider>
142
+ );
143
+ }
144
+
145
+ // Using theme in components
146
+ const Card = styled.div\`
147
+ padding: \${({ theme }) => theme.spacing.lg};
148
+ background: \${({ theme }) => theme.colors.background};
149
+ border-radius: \${({ theme }) => theme.borderRadius.lg};
150
+ box-shadow: \${({ theme }) => theme.shadows.md};
151
+ \`;
152
+
153
+ const Button = styled.button\`
154
+ background: \${({ theme }) => theme.colors.primary};
155
+ color: white;
156
+ padding: \${({ theme }) => \`\${theme.spacing.sm} \${theme.spacing.md}\`};
157
+ \`;
158
+ \`\`\`
159
+
160
+ ## Extending & Composing
161
+ \`\`\`tsx
162
+ // Extend existing styled component
163
+ const Button = styled.button\`
164
+ padding: 0.5rem 1rem;
165
+ border-radius: 0.375rem;
166
+ \`;
167
+
168
+ const PrimaryButton = styled(Button)\`
169
+ background: #3b82f6;
170
+ color: white;
171
+ \`;
172
+
173
+ const OutlineButton = styled(Button)\`
174
+ background: transparent;
175
+ border: 1px solid #3b82f6;
176
+ color: #3b82f6;
177
+ \`;
178
+
179
+ // Extend any component (must accept className prop)
180
+ const Link = styled(RouterLink)\`
181
+ color: #3b82f6;
182
+ text-decoration: none;
183
+
184
+ &:hover {
185
+ text-decoration: underline;
186
+ }
187
+ \`;
188
+
189
+ // Style HTML element with 'as' prop
190
+ <Button as="a" href="/link">Link styled as button</Button>
191
+ <Container as="section">Section container</Container>
192
+ \`\`\`
193
+
194
+ ## Animations
195
+ \`\`\`tsx
196
+ import styled, { keyframes, css } from 'styled-components';
197
+
198
+ // Define keyframes
199
+ const fadeIn = keyframes\`
200
+ from { opacity: 0; transform: translateY(-10px); }
201
+ to { opacity: 1; transform: translateY(0); }
202
+ \`;
203
+
204
+ const spin = keyframes\`
205
+ from { transform: rotate(0deg); }
206
+ to { transform: rotate(360deg); }
207
+ \`;
208
+
209
+ const pulse = keyframes\`
210
+ 0%, 100% { opacity: 1; }
211
+ 50% { opacity: 0.5; }
212
+ \`;
213
+
214
+ // Use in styled component
215
+ const FadeInDiv = styled.div\`
216
+ animation: \${fadeIn} 0.3s ease-out;
217
+ \`;
218
+
219
+ const Spinner = styled.div\`
220
+ width: 24px;
221
+ height: 24px;
222
+ border: 2px solid #e5e7eb;
223
+ border-top-color: #3b82f6;
224
+ border-radius: 50%;
225
+ animation: \${spin} 0.8s linear infinite;
226
+ \`;
227
+
228
+ // Conditional animation
229
+ const AnimatedCard = styled.div<{ isVisible: boolean }>\`
230
+ opacity: 0;
231
+
232
+ \${({ isVisible }) => isVisible && css\`
233
+ animation: \${fadeIn} 0.5s ease-out forwards;
234
+ \`}
235
+ \`;
236
+ \`\`\`
237
+
238
+ ## Global Styles
239
+ \`\`\`tsx
240
+ import { createGlobalStyle } from 'styled-components';
241
+
242
+ const GlobalStyle = createGlobalStyle\`
243
+ *, *::before, *::after {
244
+ box-sizing: border-box;
245
+ }
246
+
247
+ html {
248
+ font-size: 16px;
249
+ }
250
+
251
+ body {
252
+ margin: 0;
253
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
254
+ background: \${({ theme }) => theme.colors.background};
255
+ color: \${({ theme }) => theme.colors.text};
256
+ line-height: 1.5;
257
+ }
258
+
259
+ a {
260
+ color: \${({ theme }) => theme.colors.primary};
261
+ }
262
+
263
+ /* CSS reset or normalize styles */
264
+ h1, h2, h3, h4, h5, h6, p {
265
+ margin: 0;
266
+ }
267
+ \`;
268
+
269
+ // In App.tsx
270
+ function App() {
271
+ return (
272
+ <ThemeProvider theme={theme}>
273
+ <GlobalStyle />
274
+ <YourApp />
275
+ </ThemeProvider>
276
+ );
277
+ }
278
+ \`\`\`
279
+
280
+ ## CSS Helper & Mixins
281
+ \`\`\`tsx
282
+ import styled, { css } from 'styled-components';
283
+
284
+ // Reusable style mixins
285
+ const flexCenter = css\`
286
+ display: flex;
287
+ align-items: center;
288
+ justify-content: center;
289
+ \`;
290
+
291
+ const truncate = css\`
292
+ overflow: hidden;
293
+ text-overflow: ellipsis;
294
+ white-space: nowrap;
295
+ \`;
296
+
297
+ const visuallyHidden = css\`
298
+ position: absolute;
299
+ width: 1px;
300
+ height: 1px;
301
+ padding: 0;
302
+ margin: -1px;
303
+ overflow: hidden;
304
+ clip: rect(0, 0, 0, 0);
305
+ border: 0;
306
+ \`;
307
+
308
+ // Media query helper
309
+ const media = {
310
+ sm: (styles: TemplateStringsArray) => css\`
311
+ @media (min-width: 640px) { \${styles} }
312
+ \`,
313
+ md: (styles: TemplateStringsArray) => css\`
314
+ @media (min-width: 768px) { \${styles} }
315
+ \`,
316
+ lg: (styles: TemplateStringsArray) => css\`
317
+ @media (min-width: 1024px) { \${styles} }
318
+ \`,
319
+ };
320
+
321
+ // Usage
322
+ const Card = styled.div\`
323
+ \${flexCenter}
324
+ padding: 1rem;
325
+
326
+ \${media.md\`
327
+ padding: 2rem;
328
+ \`}
329
+ \`;
330
+
331
+ const Title = styled.h1\`
332
+ \${truncate}
333
+ max-width: 300px;
334
+ \`;
335
+ \`\`\`
336
+
337
+ ## Attrs & Default Props
338
+ \`\`\`tsx
339
+ // Add default attributes
340
+ const Input = styled.input.attrs<{ type?: string }>((props) => ({
341
+ type: props.type || 'text',
342
+ }))\`
343
+ padding: 0.5rem;
344
+ border: 1px solid #d1d5db;
345
+ border-radius: 0.375rem;
346
+ \`;
347
+
348
+ const PasswordInput = styled(Input).attrs({ type: 'password' })\`\`;
349
+
350
+ // Dynamic attrs
351
+ const Button = styled.button.attrs<{ disabled?: boolean }>((props) => ({
352
+ disabled: props.disabled,
353
+ 'aria-disabled': props.disabled,
354
+ }))\`
355
+ /* styles */
356
+ \`;
357
+ \`\`\`
358
+
359
+ ## Server-Side Rendering
360
+ \`\`\`tsx
361
+ // Next.js setup (pages/_document.tsx)
362
+ import Document, { DocumentContext } from 'next/document';
363
+ import { ServerStyleSheet } from 'styled-components';
364
+
365
+ export default class MyDocument extends Document {
366
+ static async getInitialProps(ctx: DocumentContext) {
367
+ const sheet = new ServerStyleSheet();
368
+ const originalRenderPage = ctx.renderPage;
369
+
370
+ try {
371
+ ctx.renderPage = () =>
372
+ originalRenderPage({
373
+ enhanceApp: (App) => (props) =>
374
+ sheet.collectStyles(<App {...props} />),
375
+ });
376
+
377
+ const initialProps = await Document.getInitialProps(ctx);
378
+ return {
379
+ ...initialProps,
380
+ styles: [initialProps.styles, sheet.getStyleElement()],
381
+ };
382
+ } finally {
383
+ sheet.seal();
384
+ }
385
+ }
386
+ }
387
+ \`\`\`
388
+
389
+ ## ❌ DON'T
390
+ - Create styled components inside render functions
391
+ - Use inline styles when styled-components works
392
+ - Forget to type props in TypeScript
393
+ - Create overly complex conditional styles
394
+ - Skip ThemeProvider when using theme
395
+
396
+ ## ✅ DO
397
+ - Define styled components outside of render
398
+ - Use theme for consistent values
399
+ - Keep styles colocated with components
400
+ - Use props for dynamic styles
401
+ - Create reusable mixins with css helper
402
+ - Use attrs for default/computed attributes
403
+ - Setup SSR properly for production
@@ -0,0 +1,238 @@
1
+ # Svelte Skill
2
+
3
+ ## Component Structure
4
+ \`\`\`svelte
5
+ <script lang="ts">
6
+ import { onMount, onDestroy, createEventDispatcher } from 'svelte';
7
+
8
+ // Props
9
+ export let userId: string;
10
+ export let initialCount = 0;
11
+
12
+ // Local state
13
+ let count = initialCount;
14
+ let user: User | null = null;
15
+
16
+ // Reactive declarations
17
+ $: doubleCount = count * 2;
18
+ $: if (count > 10) {
19
+ console.log('Count exceeded 10!');
20
+ }
21
+
22
+ // Event dispatcher
23
+ const dispatch = createEventDispatcher<{
24
+ update: number;
25
+ submit: { data: FormData };
26
+ }>();
27
+
28
+ function increment() {
29
+ count++;
30
+ dispatch('update', count);
31
+ }
32
+
33
+ // Lifecycle
34
+ onMount(async () => {
35
+ user = await fetchUser(userId);
36
+ return () => {
37
+ // Cleanup (alternative to onDestroy)
38
+ };
39
+ });
40
+ </script>
41
+
42
+ <div>
43
+ <h2>{user?.name ?? 'Loading...'}</h2>
44
+ <p>Count: {count} (Double: {doubleCount})</p>
45
+ <button on:click={increment}>Increment</button>
46
+ </div>
47
+ \`\`\`
48
+
49
+ ## Stores
50
+ \`\`\`typescript
51
+ // stores/auth.ts
52
+ import { writable, derived, readable } from 'svelte/store';
53
+
54
+ // Writable store
55
+ export const user = writable<User | null>(null);
56
+
57
+ // With custom methods
58
+ function createAuthStore() {
59
+ const { subscribe, set, update } = writable<User | null>(null);
60
+
61
+ return {
62
+ subscribe,
63
+ login: async (email: string, password: string) => {
64
+ const user = await api.login(email, password);
65
+ set(user);
66
+ },
67
+ logout: () => set(null),
68
+ updateProfile: (data: Partial<User>) => {
69
+ update(u => u ? { ...u, ...data } : null);
70
+ }
71
+ };
72
+ }
73
+
74
+ export const auth = createAuthStore();
75
+
76
+ // Derived store
77
+ export const isLoggedIn = derived(user, $user => !!$user);
78
+
79
+ // Readable store (external source)
80
+ export const time = readable(new Date(), (set) => {
81
+ const interval = setInterval(() => set(new Date()), 1000);
82
+ return () => clearInterval(interval);
83
+ });
84
+
85
+ // Usage in component
86
+ <script>
87
+ import { user, isLoggedIn, auth } from './stores/auth';
88
+
89
+ // Auto-subscription with $
90
+ $: console.log('User:', $user);
91
+ $: console.log('Logged in:', $isLoggedIn);
92
+ </script>
93
+
94
+ {#if $isLoggedIn}
95
+ <p>Welcome, {$user.name}</p>
96
+ <button on:click={() => auth.logout()}>Logout</button>
97
+ {/if}
98
+ \`\`\`
99
+
100
+ ## Event Handling
101
+ \`\`\`svelte
102
+ <!-- Basic events -->
103
+ <button on:click={handleClick}>Click</button>
104
+ <button on:click={() => count++}>Inline</button>
105
+
106
+ <!-- Event modifiers -->
107
+ <button on:click|once={handleClick}>Click once</button>
108
+ <button on:click|preventDefault={handleSubmit}>Submit</button>
109
+ <button on:click|stopPropagation={handleClick}>Stop bubbling</button>
110
+
111
+ <!-- Component events -->
112
+ <Child on:update={handleUpdate} />
113
+ <Child on:update /> <!-- Forward to parent -->
114
+
115
+ <!-- DOM event forwarding -->
116
+ <button on:click>
117
+ <slot />
118
+ </button>
119
+ \`\`\`
120
+
121
+ ## Slots
122
+ \`\`\`svelte
123
+ <!-- Card.svelte -->
124
+ <div class="card">
125
+ <header>
126
+ <slot name="header">Default Header</slot>
127
+ </header>
128
+
129
+ <main>
130
+ <slot>Default content</slot>
131
+ </main>
132
+
133
+ <footer>
134
+ <slot name="footer" user={currentUser}>
135
+ <!-- Slot props -->
136
+ </slot>
137
+ </footer>
138
+ </div>
139
+
140
+ <!-- Usage -->
141
+ <Card>
142
+ <svelte:fragment slot="header">
143
+ <h1>Title</h1>
144
+ </svelte:fragment>
145
+
146
+ <p>Main content</p>
147
+
148
+ <div slot="footer" let:user>
149
+ <p>Footer for {user.name}</p>
150
+ </div>
151
+ </Card>
152
+ \`\`\`
153
+
154
+ ## Context API
155
+ \`\`\`svelte
156
+ <!-- Parent.svelte -->
157
+ <script>
158
+ import { setContext } from 'svelte';
159
+ import { writable } from 'svelte/store';
160
+
161
+ const theme = writable('dark');
162
+ setContext('theme', theme);
163
+ </script>
164
+
165
+ <!-- Child.svelte (any depth) -->
166
+ <script>
167
+ import { getContext } from 'svelte';
168
+
169
+ const theme = getContext('theme');
170
+ </script>
171
+
172
+ <div class={$theme}>Content</div>
173
+ \`\`\`
174
+
175
+ ## Transitions & Animations
176
+ \`\`\`svelte
177
+ <script>
178
+ import { fade, fly, slide, scale } from 'svelte/transition';
179
+ import { flip } from 'svelte/animate';
180
+
181
+ let visible = true;
182
+ let items = [1, 2, 3];
183
+ </script>
184
+
185
+ <!-- Basic transition -->
186
+ {#if visible}
187
+ <div transition:fade>Fades in/out</div>
188
+ {/if}
189
+
190
+ <!-- In/out transitions -->
191
+ {#if visible}
192
+ <div in:fly={{ y: 200 }} out:fade>
193
+ Flies in, fades out
194
+ </div>
195
+ {/if}
196
+
197
+ <!-- Animate list reordering -->
198
+ {#each items as item (item)}
199
+ <div animate:flip={{ duration: 300 }}>
200
+ {item}
201
+ </div>
202
+ {/each}
203
+ \`\`\`
204
+
205
+ ## Bindings
206
+ \`\`\`svelte
207
+ <!-- Two-way binding -->
208
+ <input bind:value={name} />
209
+ <input type="checkbox" bind:checked={accepted} />
210
+ <select bind:value={selected}>
211
+ <option value="a">A</option>
212
+ </select>
213
+
214
+ <!-- Group binding -->
215
+ {#each options as option}
216
+ <input type="checkbox" bind:group={selectedOptions} value={option} />
217
+ {/each}
218
+
219
+ <!-- Element binding -->
220
+ <canvas bind:this={canvasElement}></canvas>
221
+
222
+ <!-- Component binding -->
223
+ <Child bind:value />
224
+ \`\`\`
225
+
226
+ ## ❌ DON'T
227
+ - Mutate objects/arrays without reassignment (won't trigger reactivity)
228
+ - Forget $ prefix when reading stores in script
229
+ - Use context for frequently changing data (use stores)
230
+ - Create stores inside components (create outside)
231
+
232
+ ## ✅ DO
233
+ - Use \`$:\` for reactive statements
234
+ - Use stores for shared state
235
+ - Keep components small
236
+ - Use transitions for smooth UX
237
+ - Use context for static/rarely-changing data
238
+ - Reassign arrays/objects to trigger updates: \`items = [...items, newItem]\`