autoworkflow 3.1.5 → 3.6.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/.claude/commands/analyze.md +19 -0
- package/.claude/commands/audit.md +26 -0
- package/.claude/commands/build.md +39 -0
- package/.claude/commands/commit.md +25 -0
- package/.claude/commands/fix.md +23 -0
- package/.claude/commands/plan.md +18 -0
- package/.claude/commands/suggest.md +23 -0
- package/.claude/commands/verify.md +18 -0
- package/.claude/hooks/post-bash-router.sh +20 -0
- package/.claude/hooks/post-commit.sh +140 -0
- package/.claude/hooks/post-edit.sh +190 -17
- package/.claude/hooks/pre-edit.sh +221 -0
- package/.claude/hooks/session-check.sh +90 -0
- package/.claude/settings.json +56 -6
- package/.claude/settings.local.json +5 -1
- package/.claude/skills/actix.md +337 -0
- package/.claude/skills/alembic.md +504 -0
- package/.claude/skills/angular.md +237 -0
- package/.claude/skills/api-design.md +187 -0
- package/.claude/skills/aspnet-core.md +377 -0
- package/.claude/skills/astro.md +245 -0
- package/.claude/skills/auth-clerk.md +327 -0
- package/.claude/skills/auth-firebase.md +367 -0
- package/.claude/skills/auth-nextauth.md +359 -0
- package/.claude/skills/auth-supabase.md +368 -0
- package/.claude/skills/axum.md +386 -0
- package/.claude/skills/blazor.md +456 -0
- package/.claude/skills/chi.md +348 -0
- package/.claude/skills/code-review.md +133 -0
- package/.claude/skills/csharp.md +296 -0
- package/.claude/skills/css-modules.md +325 -0
- package/.claude/skills/cypress.md +343 -0
- package/.claude/skills/debugging.md +133 -0
- package/.claude/skills/diesel.md +392 -0
- package/.claude/skills/django.md +301 -0
- package/.claude/skills/docker.md +319 -0
- package/.claude/skills/doctrine.md +473 -0
- package/.claude/skills/documentation.md +182 -0
- package/.claude/skills/dotnet.md +409 -0
- package/.claude/skills/drizzle.md +293 -0
- package/.claude/skills/echo.md +321 -0
- package/.claude/skills/eloquent.md +256 -0
- package/.claude/skills/emotion.md +426 -0
- package/.claude/skills/entity-framework.md +370 -0
- package/.claude/skills/express.md +316 -0
- package/.claude/skills/fastapi.md +329 -0
- package/.claude/skills/fastify.md +299 -0
- package/.claude/skills/fiber.md +315 -0
- package/.claude/skills/flask.md +322 -0
- package/.claude/skills/gin.md +342 -0
- package/.claude/skills/git.md +116 -0
- package/.claude/skills/github-actions.md +353 -0
- package/.claude/skills/go.md +377 -0
- package/.claude/skills/gorm.md +409 -0
- package/.claude/skills/graphql.md +478 -0
- package/.claude/skills/hibernate.md +379 -0
- package/.claude/skills/hono.md +306 -0
- package/.claude/skills/java.md +400 -0
- package/.claude/skills/jest.md +313 -0
- package/.claude/skills/jpa.md +282 -0
- package/.claude/skills/kotlin.md +347 -0
- package/.claude/skills/kubernetes.md +363 -0
- package/.claude/skills/laravel.md +414 -0
- package/.claude/skills/mcp-browser.md +320 -0
- package/.claude/skills/mcp-database.md +219 -0
- package/.claude/skills/mcp-fetch.md +241 -0
- package/.claude/skills/mcp-filesystem.md +204 -0
- package/.claude/skills/mcp-github.md +217 -0
- package/.claude/skills/mcp-memory.md +240 -0
- package/.claude/skills/mcp-search.md +218 -0
- package/.claude/skills/mcp-slack.md +262 -0
- package/.claude/skills/micronaut.md +388 -0
- package/.claude/skills/mongodb.md +319 -0
- package/.claude/skills/mongoose.md +355 -0
- package/.claude/skills/mysql.md +281 -0
- package/.claude/skills/nestjs.md +335 -0
- package/.claude/skills/nextjs-app-router.md +260 -0
- package/.claude/skills/nextjs-pages.md +172 -0
- package/.claude/skills/nuxt.md +202 -0
- package/.claude/skills/openapi.md +489 -0
- package/.claude/skills/performance.md +199 -0
- package/.claude/skills/php.md +398 -0
- package/.claude/skills/playwright.md +371 -0
- package/.claude/skills/postgresql.md +257 -0
- package/.claude/skills/prisma.md +293 -0
- package/.claude/skills/pydantic.md +304 -0
- package/.claude/skills/pytest.md +313 -0
- package/.claude/skills/python.md +272 -0
- package/.claude/skills/quarkus.md +377 -0
- package/.claude/skills/react.md +230 -0
- package/.claude/skills/redis.md +391 -0
- package/.claude/skills/refactoring.md +143 -0
- package/.claude/skills/remix.md +246 -0
- package/.claude/skills/rest-api.md +490 -0
- package/.claude/skills/rocket.md +366 -0
- package/.claude/skills/rust.md +341 -0
- package/.claude/skills/sass.md +380 -0
- package/.claude/skills/sea-orm.md +382 -0
- package/.claude/skills/security.md +167 -0
- package/.claude/skills/sequelize.md +395 -0
- package/.claude/skills/spring-boot.md +416 -0
- package/.claude/skills/sqlalchemy.md +269 -0
- package/.claude/skills/sqlx-rust.md +408 -0
- package/.claude/skills/state-jotai.md +346 -0
- package/.claude/skills/state-mobx.md +353 -0
- package/.claude/skills/state-pinia.md +431 -0
- package/.claude/skills/state-redux.md +337 -0
- package/.claude/skills/state-tanstack-query.md +434 -0
- package/.claude/skills/state-zustand.md +340 -0
- package/.claude/skills/styled-components.md +403 -0
- package/.claude/skills/svelte.md +238 -0
- package/.claude/skills/sveltekit.md +207 -0
- package/.claude/skills/symfony.md +437 -0
- package/.claude/skills/tailwind.md +279 -0
- package/.claude/skills/terraform.md +394 -0
- package/.claude/skills/testing-library.md +371 -0
- package/.claude/skills/trpc.md +426 -0
- package/.claude/skills/typeorm.md +368 -0
- package/.claude/skills/vitest.md +330 -0
- package/.claude/skills/vue.md +202 -0
- package/.claude/skills/warp.md +365 -0
- package/README.md +163 -52
- package/package.json +1 -1
- package/system/triggers.md +256 -17
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
# Emotion Skill
|
|
2
|
+
|
|
3
|
+
## CSS Prop (with @emotion/react)
|
|
4
|
+
\`\`\`tsx
|
|
5
|
+
/** @jsxImportSource @emotion/react */
|
|
6
|
+
import { css } from '@emotion/react';
|
|
7
|
+
|
|
8
|
+
// String styles
|
|
9
|
+
const containerStyle = css\`
|
|
10
|
+
max-width: 1200px;
|
|
11
|
+
margin: 0 auto;
|
|
12
|
+
padding: 0 1rem;
|
|
13
|
+
\`;
|
|
14
|
+
|
|
15
|
+
// Object styles
|
|
16
|
+
const buttonStyle = css({
|
|
17
|
+
padding: '0.5rem 1rem',
|
|
18
|
+
background: '#3b82f6',
|
|
19
|
+
color: 'white',
|
|
20
|
+
border: 'none',
|
|
21
|
+
borderRadius: '0.375rem',
|
|
22
|
+
cursor: 'pointer',
|
|
23
|
+
'&:hover': {
|
|
24
|
+
background: '#2563eb',
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// Usage with css prop
|
|
29
|
+
function App() {
|
|
30
|
+
return (
|
|
31
|
+
<div css={containerStyle}>
|
|
32
|
+
<button css={buttonStyle}>Click me</button>
|
|
33
|
+
</div>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Inline css prop
|
|
38
|
+
<div css={css\`
|
|
39
|
+
display: flex;
|
|
40
|
+
gap: 1rem;
|
|
41
|
+
\`}>
|
|
42
|
+
\`\`\`
|
|
43
|
+
|
|
44
|
+
## Styled Components API
|
|
45
|
+
\`\`\`tsx
|
|
46
|
+
import styled from '@emotion/styled';
|
|
47
|
+
|
|
48
|
+
// Basic styled component
|
|
49
|
+
const Container = styled.div\`
|
|
50
|
+
max-width: 1200px;
|
|
51
|
+
margin: 0 auto;
|
|
52
|
+
padding: 0 1rem;
|
|
53
|
+
\`;
|
|
54
|
+
|
|
55
|
+
// With props
|
|
56
|
+
interface ButtonProps {
|
|
57
|
+
variant?: 'primary' | 'secondary';
|
|
58
|
+
size?: 'sm' | 'md' | 'lg';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const Button = styled.button<ButtonProps>\`
|
|
62
|
+
padding: \${({ size }) => {
|
|
63
|
+
switch (size) {
|
|
64
|
+
case 'sm': return '0.25rem 0.5rem';
|
|
65
|
+
case 'lg': return '0.75rem 1.5rem';
|
|
66
|
+
default: return '0.5rem 1rem';
|
|
67
|
+
}
|
|
68
|
+
}};
|
|
69
|
+
|
|
70
|
+
background: \${({ variant }) =>
|
|
71
|
+
variant === 'secondary' ? '#6b7280' : '#3b82f6'};
|
|
72
|
+
|
|
73
|
+
color: white;
|
|
74
|
+
border: none;
|
|
75
|
+
border-radius: 0.375rem;
|
|
76
|
+
cursor: pointer;
|
|
77
|
+
|
|
78
|
+
&:hover {
|
|
79
|
+
opacity: 0.9;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
&:disabled {
|
|
83
|
+
opacity: 0.5;
|
|
84
|
+
cursor: not-allowed;
|
|
85
|
+
}
|
|
86
|
+
\`;
|
|
87
|
+
|
|
88
|
+
// Object syntax
|
|
89
|
+
const Card = styled.div({
|
|
90
|
+
padding: '1.5rem',
|
|
91
|
+
borderRadius: '0.5rem',
|
|
92
|
+
boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)',
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Extending components
|
|
96
|
+
const PrimaryButton = styled(Button)\`
|
|
97
|
+
background: #3b82f6;
|
|
98
|
+
\`;
|
|
99
|
+
|
|
100
|
+
const OutlineButton = styled(Button)\`
|
|
101
|
+
background: transparent;
|
|
102
|
+
border: 1px solid #3b82f6;
|
|
103
|
+
color: #3b82f6;
|
|
104
|
+
\`;
|
|
105
|
+
\`\`\`
|
|
106
|
+
|
|
107
|
+
## Theming
|
|
108
|
+
\`\`\`tsx
|
|
109
|
+
import { ThemeProvider, useTheme } from '@emotion/react';
|
|
110
|
+
|
|
111
|
+
// Define theme
|
|
112
|
+
const theme = {
|
|
113
|
+
colors: {
|
|
114
|
+
primary: '#3b82f6',
|
|
115
|
+
secondary: '#6b7280',
|
|
116
|
+
danger: '#ef4444',
|
|
117
|
+
success: '#10b981',
|
|
118
|
+
background: '#ffffff',
|
|
119
|
+
text: '#1f2937',
|
|
120
|
+
},
|
|
121
|
+
spacing: {
|
|
122
|
+
xs: '0.25rem',
|
|
123
|
+
sm: '0.5rem',
|
|
124
|
+
md: '1rem',
|
|
125
|
+
lg: '1.5rem',
|
|
126
|
+
xl: '2rem',
|
|
127
|
+
},
|
|
128
|
+
borderRadius: {
|
|
129
|
+
sm: '0.25rem',
|
|
130
|
+
md: '0.375rem',
|
|
131
|
+
lg: '0.5rem',
|
|
132
|
+
full: '9999px',
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// TypeScript: Extend Emotion's theme type
|
|
137
|
+
declare module '@emotion/react' {
|
|
138
|
+
export interface Theme {
|
|
139
|
+
colors: typeof theme.colors;
|
|
140
|
+
spacing: typeof theme.spacing;
|
|
141
|
+
borderRadius: typeof theme.borderRadius;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Provider setup
|
|
146
|
+
function App() {
|
|
147
|
+
return (
|
|
148
|
+
<ThemeProvider theme={theme}>
|
|
149
|
+
<YourApp />
|
|
150
|
+
</ThemeProvider>
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Using theme in styled components
|
|
155
|
+
const Button = styled.button\`
|
|
156
|
+
padding: \${({ theme }) => theme.spacing.sm} \${({ theme }) => theme.spacing.md};
|
|
157
|
+
background: \${({ theme }) => theme.colors.primary};
|
|
158
|
+
border-radius: \${({ theme }) => theme.borderRadius.md};
|
|
159
|
+
\`;
|
|
160
|
+
|
|
161
|
+
// Using theme with css prop
|
|
162
|
+
const Card = ({ children }) => {
|
|
163
|
+
const theme = useTheme();
|
|
164
|
+
|
|
165
|
+
return (
|
|
166
|
+
<div css={css\`
|
|
167
|
+
padding: \${theme.spacing.lg};
|
|
168
|
+
background: \${theme.colors.background};
|
|
169
|
+
\`}>
|
|
170
|
+
{children}
|
|
171
|
+
</div>
|
|
172
|
+
);
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
// Theme access in css function
|
|
176
|
+
const cardStyle = (theme) => css\`
|
|
177
|
+
padding: \${theme.spacing.lg};
|
|
178
|
+
background: \${theme.colors.background};
|
|
179
|
+
color: \${theme.colors.text};
|
|
180
|
+
\`;
|
|
181
|
+
|
|
182
|
+
<div css={cardStyle}>Content</div>
|
|
183
|
+
\`\`\`
|
|
184
|
+
|
|
185
|
+
## Composition
|
|
186
|
+
\`\`\`tsx
|
|
187
|
+
import { css } from '@emotion/react';
|
|
188
|
+
|
|
189
|
+
// Reusable style blocks
|
|
190
|
+
const flexCenter = css\`
|
|
191
|
+
display: flex;
|
|
192
|
+
align-items: center;
|
|
193
|
+
justify-content: center;
|
|
194
|
+
\`;
|
|
195
|
+
|
|
196
|
+
const truncate = css\`
|
|
197
|
+
overflow: hidden;
|
|
198
|
+
text-overflow: ellipsis;
|
|
199
|
+
white-space: nowrap;
|
|
200
|
+
\`;
|
|
201
|
+
|
|
202
|
+
const visuallyHidden = css\`
|
|
203
|
+
position: absolute;
|
|
204
|
+
width: 1px;
|
|
205
|
+
height: 1px;
|
|
206
|
+
padding: 0;
|
|
207
|
+
margin: -1px;
|
|
208
|
+
overflow: hidden;
|
|
209
|
+
clip: rect(0, 0, 0, 0);
|
|
210
|
+
border: 0;
|
|
211
|
+
\`;
|
|
212
|
+
|
|
213
|
+
// Compose styles
|
|
214
|
+
const Header = styled.header\`
|
|
215
|
+
\${flexCenter}
|
|
216
|
+
padding: 1rem;
|
|
217
|
+
background: white;
|
|
218
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
219
|
+
\`;
|
|
220
|
+
|
|
221
|
+
const Title = styled.h1\`
|
|
222
|
+
\${truncate}
|
|
223
|
+
max-width: 300px;
|
|
224
|
+
font-size: 1.5rem;
|
|
225
|
+
\`;
|
|
226
|
+
|
|
227
|
+
// Array composition
|
|
228
|
+
<div css={[flexCenter, { padding: '1rem' }]}>
|
|
229
|
+
|
|
230
|
+
// Conditional composition
|
|
231
|
+
<div css={[
|
|
232
|
+
baseStyle,
|
|
233
|
+
isActive && activeStyle,
|
|
234
|
+
isDisabled && disabledStyle,
|
|
235
|
+
]}>
|
|
236
|
+
\`\`\`
|
|
237
|
+
|
|
238
|
+
## Animations
|
|
239
|
+
\`\`\`tsx
|
|
240
|
+
import { css, keyframes } from '@emotion/react';
|
|
241
|
+
|
|
242
|
+
// Define keyframes
|
|
243
|
+
const fadeIn = keyframes\`
|
|
244
|
+
from {
|
|
245
|
+
opacity: 0;
|
|
246
|
+
transform: translateY(-10px);
|
|
247
|
+
}
|
|
248
|
+
to {
|
|
249
|
+
opacity: 1;
|
|
250
|
+
transform: translateY(0);
|
|
251
|
+
}
|
|
252
|
+
\`;
|
|
253
|
+
|
|
254
|
+
const spin = keyframes\`
|
|
255
|
+
from { transform: rotate(0deg); }
|
|
256
|
+
to { transform: rotate(360deg); }
|
|
257
|
+
\`;
|
|
258
|
+
|
|
259
|
+
const pulse = keyframes\`
|
|
260
|
+
0%, 100% { opacity: 1; }
|
|
261
|
+
50% { opacity: 0.5; }
|
|
262
|
+
\`;
|
|
263
|
+
|
|
264
|
+
// Using keyframes
|
|
265
|
+
const FadeInDiv = styled.div\`
|
|
266
|
+
animation: \${fadeIn} 0.3s ease-out;
|
|
267
|
+
\`;
|
|
268
|
+
|
|
269
|
+
const Spinner = styled.div\`
|
|
270
|
+
width: 24px;
|
|
271
|
+
height: 24px;
|
|
272
|
+
border: 2px solid #e5e7eb;
|
|
273
|
+
border-top-color: #3b82f6;
|
|
274
|
+
border-radius: 50%;
|
|
275
|
+
animation: \${spin} 0.8s linear infinite;
|
|
276
|
+
\`;
|
|
277
|
+
|
|
278
|
+
// Conditional animation
|
|
279
|
+
const AnimatedCard = styled.div<{ isVisible: boolean }>\`
|
|
280
|
+
opacity: 0;
|
|
281
|
+
|
|
282
|
+
\${({ isVisible }) => isVisible && css\`
|
|
283
|
+
animation: \${fadeIn} 0.5s ease-out forwards;
|
|
284
|
+
\`}
|
|
285
|
+
\`;
|
|
286
|
+
\`\`\`
|
|
287
|
+
|
|
288
|
+
## Global Styles
|
|
289
|
+
\`\`\`tsx
|
|
290
|
+
import { Global, css } from '@emotion/react';
|
|
291
|
+
|
|
292
|
+
const globalStyles = css\`
|
|
293
|
+
*,
|
|
294
|
+
*::before,
|
|
295
|
+
*::after {
|
|
296
|
+
box-sizing: border-box;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
html {
|
|
300
|
+
font-size: 16px;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
body {
|
|
304
|
+
margin: 0;
|
|
305
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
306
|
+
line-height: 1.5;
|
|
307
|
+
-webkit-font-smoothing: antialiased;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
img, picture, video, canvas, svg {
|
|
311
|
+
display: block;
|
|
312
|
+
max-width: 100%;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
input, button, textarea, select {
|
|
316
|
+
font: inherit;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
p, h1, h2, h3, h4, h5, h6 {
|
|
320
|
+
overflow-wrap: break-word;
|
|
321
|
+
margin: 0;
|
|
322
|
+
}
|
|
323
|
+
\`;
|
|
324
|
+
|
|
325
|
+
// In App component
|
|
326
|
+
function App() {
|
|
327
|
+
return (
|
|
328
|
+
<>
|
|
329
|
+
<Global styles={globalStyles} />
|
|
330
|
+
<ThemeProvider theme={theme}>
|
|
331
|
+
<YourApp />
|
|
332
|
+
</ThemeProvider>
|
|
333
|
+
</>
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Global styles with theme
|
|
338
|
+
const globalStylesWithTheme = (theme) => css\`
|
|
339
|
+
body {
|
|
340
|
+
background: \${theme.colors.background};
|
|
341
|
+
color: \${theme.colors.text};
|
|
342
|
+
}
|
|
343
|
+
\`;
|
|
344
|
+
|
|
345
|
+
<Global styles={globalStylesWithTheme} />
|
|
346
|
+
\`\`\`
|
|
347
|
+
|
|
348
|
+
## Media Queries
|
|
349
|
+
\`\`\`tsx
|
|
350
|
+
// Breakpoint helpers
|
|
351
|
+
const breakpoints = {
|
|
352
|
+
sm: 640,
|
|
353
|
+
md: 768,
|
|
354
|
+
lg: 1024,
|
|
355
|
+
xl: 1280,
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
const mq = {
|
|
359
|
+
sm: \`@media (min-width: \${breakpoints.sm}px)\`,
|
|
360
|
+
md: \`@media (min-width: \${breakpoints.md}px)\`,
|
|
361
|
+
lg: \`@media (min-width: \${breakpoints.lg}px)\`,
|
|
362
|
+
xl: \`@media (min-width: \${breakpoints.xl}px)\`,
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
// Usage in styled components
|
|
366
|
+
const Container = styled.div\`
|
|
367
|
+
padding: 1rem;
|
|
368
|
+
|
|
369
|
+
\${mq.md} {
|
|
370
|
+
padding: 2rem;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
\${mq.lg} {
|
|
374
|
+
padding: 3rem;
|
|
375
|
+
max-width: 1200px;
|
|
376
|
+
margin: 0 auto;
|
|
377
|
+
}
|
|
378
|
+
\`;
|
|
379
|
+
|
|
380
|
+
// Object syntax
|
|
381
|
+
const responsiveStyle = css({
|
|
382
|
+
fontSize: '1rem',
|
|
383
|
+
[mq.md]: {
|
|
384
|
+
fontSize: '1.25rem',
|
|
385
|
+
},
|
|
386
|
+
[mq.lg]: {
|
|
387
|
+
fontSize: '1.5rem',
|
|
388
|
+
},
|
|
389
|
+
});
|
|
390
|
+
\`\`\`
|
|
391
|
+
|
|
392
|
+
## Server-Side Rendering
|
|
393
|
+
\`\`\`tsx
|
|
394
|
+
// Next.js App Router (app/layout.tsx)
|
|
395
|
+
// Emotion works with React Server Components
|
|
396
|
+
// Add the pragma for client components using css prop
|
|
397
|
+
|
|
398
|
+
// For Pages Router, use @emotion/cache and @emotion/server
|
|
399
|
+
import createEmotionServer from '@emotion/server/create-instance';
|
|
400
|
+
import createCache from '@emotion/cache';
|
|
401
|
+
|
|
402
|
+
// Create cache
|
|
403
|
+
const cache = createCache({ key: 'css' });
|
|
404
|
+
const { extractCriticalToChunks, constructStyleTagsFromChunks } =
|
|
405
|
+
createEmotionServer(cache);
|
|
406
|
+
|
|
407
|
+
// In _document.tsx
|
|
408
|
+
const emotionChunks = extractCriticalToChunks(html);
|
|
409
|
+
const emotionStyleTags = constructStyleTagsFromChunks(emotionChunks);
|
|
410
|
+
\`\`\`
|
|
411
|
+
|
|
412
|
+
## ❌ DON'T
|
|
413
|
+
- Create styled components inside render functions
|
|
414
|
+
- Use dynamic styles when static works
|
|
415
|
+
- Forget the JSX pragma for css prop
|
|
416
|
+
- Mix string and object syntax unnecessarily
|
|
417
|
+
- Skip TypeScript theme declaration
|
|
418
|
+
|
|
419
|
+
## ✅ DO
|
|
420
|
+
- Define styled components outside render
|
|
421
|
+
- Use theme for consistent values
|
|
422
|
+
- Compose styles for reusability
|
|
423
|
+
- Use TypeScript for theme type safety
|
|
424
|
+
- Use object syntax for dynamic styles
|
|
425
|
+
- Set up SSR correctly for production
|
|
426
|
+
- Use keyframes for animations
|