agentic-team-templates 0.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.
- package/README.md +280 -0
- package/bin/cli.js +5 -0
- package/package.json +47 -0
- package/src/index.js +521 -0
- package/templates/_shared/code-quality.md +162 -0
- package/templates/_shared/communication.md +114 -0
- package/templates/_shared/core-principles.md +62 -0
- package/templates/_shared/git-workflow.md +165 -0
- package/templates/_shared/security-fundamentals.md +173 -0
- package/templates/blockchain/.cursorrules/defi-patterns.md +520 -0
- package/templates/blockchain/.cursorrules/gas-optimization.md +339 -0
- package/templates/blockchain/.cursorrules/overview.md +130 -0
- package/templates/blockchain/.cursorrules/security.md +318 -0
- package/templates/blockchain/.cursorrules/smart-contracts.md +364 -0
- package/templates/blockchain/.cursorrules/testing.md +415 -0
- package/templates/blockchain/.cursorrules/web3-integration.md +538 -0
- package/templates/blockchain/CLAUDE.md +389 -0
- package/templates/cli-tools/.cursorrules/architecture.md +412 -0
- package/templates/cli-tools/.cursorrules/arguments.md +406 -0
- package/templates/cli-tools/.cursorrules/distribution.md +546 -0
- package/templates/cli-tools/.cursorrules/error-handling.md +455 -0
- package/templates/cli-tools/.cursorrules/overview.md +136 -0
- package/templates/cli-tools/.cursorrules/testing.md +537 -0
- package/templates/cli-tools/.cursorrules/user-experience.md +545 -0
- package/templates/cli-tools/CLAUDE.md +356 -0
- package/templates/data-engineering/.cursorrules/data-modeling.md +367 -0
- package/templates/data-engineering/.cursorrules/data-quality.md +455 -0
- package/templates/data-engineering/.cursorrules/overview.md +85 -0
- package/templates/data-engineering/.cursorrules/performance.md +339 -0
- package/templates/data-engineering/.cursorrules/pipeline-design.md +280 -0
- package/templates/data-engineering/.cursorrules/security.md +460 -0
- package/templates/data-engineering/.cursorrules/testing.md +452 -0
- package/templates/data-engineering/CLAUDE.md +974 -0
- package/templates/devops-sre/.cursorrules/capacity-planning.md +653 -0
- package/templates/devops-sre/.cursorrules/change-management.md +584 -0
- package/templates/devops-sre/.cursorrules/chaos-engineering.md +651 -0
- package/templates/devops-sre/.cursorrules/disaster-recovery.md +641 -0
- package/templates/devops-sre/.cursorrules/incident-management.md +565 -0
- package/templates/devops-sre/.cursorrules/observability.md +714 -0
- package/templates/devops-sre/.cursorrules/overview.md +230 -0
- package/templates/devops-sre/.cursorrules/postmortems.md +588 -0
- package/templates/devops-sre/.cursorrules/runbooks.md +760 -0
- package/templates/devops-sre/.cursorrules/slo-sli.md +617 -0
- package/templates/devops-sre/.cursorrules/toil-reduction.md +567 -0
- package/templates/devops-sre/CLAUDE.md +1007 -0
- package/templates/documentation/.cursorrules/adr.md +277 -0
- package/templates/documentation/.cursorrules/api-documentation.md +411 -0
- package/templates/documentation/.cursorrules/code-comments.md +253 -0
- package/templates/documentation/.cursorrules/maintenance.md +260 -0
- package/templates/documentation/.cursorrules/overview.md +82 -0
- package/templates/documentation/.cursorrules/readme-standards.md +306 -0
- package/templates/documentation/CLAUDE.md +120 -0
- package/templates/fullstack/.cursorrules/api-contracts.md +331 -0
- package/templates/fullstack/.cursorrules/architecture.md +298 -0
- package/templates/fullstack/.cursorrules/overview.md +109 -0
- package/templates/fullstack/.cursorrules/shared-types.md +348 -0
- package/templates/fullstack/.cursorrules/testing.md +386 -0
- package/templates/fullstack/CLAUDE.md +349 -0
- package/templates/ml-ai/.cursorrules/data-engineering.md +483 -0
- package/templates/ml-ai/.cursorrules/deployment.md +601 -0
- package/templates/ml-ai/.cursorrules/model-development.md +538 -0
- package/templates/ml-ai/.cursorrules/monitoring.md +658 -0
- package/templates/ml-ai/.cursorrules/overview.md +131 -0
- package/templates/ml-ai/.cursorrules/security.md +637 -0
- package/templates/ml-ai/.cursorrules/testing.md +678 -0
- package/templates/ml-ai/CLAUDE.md +1136 -0
- package/templates/mobile/.cursorrules/navigation.md +246 -0
- package/templates/mobile/.cursorrules/offline-first.md +302 -0
- package/templates/mobile/.cursorrules/overview.md +71 -0
- package/templates/mobile/.cursorrules/performance.md +345 -0
- package/templates/mobile/.cursorrules/testing.md +339 -0
- package/templates/mobile/CLAUDE.md +233 -0
- package/templates/platform-engineering/.cursorrules/ci-cd.md +778 -0
- package/templates/platform-engineering/.cursorrules/developer-experience.md +632 -0
- package/templates/platform-engineering/.cursorrules/infrastructure-as-code.md +600 -0
- package/templates/platform-engineering/.cursorrules/kubernetes.md +710 -0
- package/templates/platform-engineering/.cursorrules/observability.md +747 -0
- package/templates/platform-engineering/.cursorrules/overview.md +215 -0
- package/templates/platform-engineering/.cursorrules/security.md +855 -0
- package/templates/platform-engineering/.cursorrules/testing.md +878 -0
- package/templates/platform-engineering/CLAUDE.md +850 -0
- package/templates/utility-agent/.cursorrules/action-control.md +284 -0
- package/templates/utility-agent/.cursorrules/context-management.md +186 -0
- package/templates/utility-agent/.cursorrules/hallucination-prevention.md +253 -0
- package/templates/utility-agent/.cursorrules/overview.md +78 -0
- package/templates/utility-agent/.cursorrules/token-optimization.md +369 -0
- package/templates/utility-agent/CLAUDE.md +513 -0
- package/templates/web-backend/.cursorrules/api-design.md +255 -0
- package/templates/web-backend/.cursorrules/authentication.md +309 -0
- package/templates/web-backend/.cursorrules/database-patterns.md +298 -0
- package/templates/web-backend/.cursorrules/error-handling.md +366 -0
- package/templates/web-backend/.cursorrules/overview.md +69 -0
- package/templates/web-backend/.cursorrules/security.md +358 -0
- package/templates/web-backend/.cursorrules/testing.md +395 -0
- package/templates/web-backend/CLAUDE.md +366 -0
- package/templates/web-frontend/.cursorrules/accessibility.md +296 -0
- package/templates/web-frontend/.cursorrules/component-patterns.md +204 -0
- package/templates/web-frontend/.cursorrules/overview.md +72 -0
- package/templates/web-frontend/.cursorrules/performance.md +325 -0
- package/templates/web-frontend/.cursorrules/state-management.md +227 -0
- package/templates/web-frontend/.cursorrules/styling.md +271 -0
- package/templates/web-frontend/.cursorrules/testing.md +311 -0
- package/templates/web-frontend/CLAUDE.md +399 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# State Management
|
|
2
|
+
|
|
3
|
+
Guidelines for managing state in frontend applications.
|
|
4
|
+
|
|
5
|
+
## State Categories
|
|
6
|
+
|
|
7
|
+
### Local State
|
|
8
|
+
State that belongs to a single component.
|
|
9
|
+
- Form input values
|
|
10
|
+
- UI toggles (open/closed)
|
|
11
|
+
- Temporary data
|
|
12
|
+
|
|
13
|
+
### Shared State
|
|
14
|
+
State needed by multiple components.
|
|
15
|
+
- User authentication
|
|
16
|
+
- Theme/preferences
|
|
17
|
+
- Shopping cart
|
|
18
|
+
|
|
19
|
+
### Server State
|
|
20
|
+
Data from external sources.
|
|
21
|
+
- API responses
|
|
22
|
+
- Cached data
|
|
23
|
+
- Real-time updates
|
|
24
|
+
|
|
25
|
+
## Principles
|
|
26
|
+
|
|
27
|
+
### 1. Lift State Only When Necessary
|
|
28
|
+
|
|
29
|
+
Keep state as close to where it's used as possible.
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
// Good: State where it's needed
|
|
33
|
+
const SearchBox = () => {
|
|
34
|
+
const [query, setQuery] = useState('');
|
|
35
|
+
return <input value={query} onChange={e => setQuery(e.target.value)} />;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Only lift when siblings need it
|
|
39
|
+
const SearchPage = () => {
|
|
40
|
+
const [query, setQuery] = useState('');
|
|
41
|
+
return (
|
|
42
|
+
<>
|
|
43
|
+
<SearchBox query={query} onChange={setQuery} />
|
|
44
|
+
<SearchResults query={query} />
|
|
45
|
+
</>
|
|
46
|
+
);
|
|
47
|
+
};
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 2. Derive Don't Duplicate
|
|
51
|
+
|
|
52
|
+
Calculate values from existing state instead of storing duplicates.
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
// Good: Derived state
|
|
56
|
+
const Cart = ({ items }: { items: CartItem[] }) => {
|
|
57
|
+
const total = items.reduce((sum, item) => sum + item.price, 0);
|
|
58
|
+
const itemCount = items.length;
|
|
59
|
+
// ...
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// Bad: Duplicate state
|
|
63
|
+
const Cart = ({ items }: { items: CartItem[] }) => {
|
|
64
|
+
const [total, setTotal] = useState(0);
|
|
65
|
+
const [itemCount, setItemCount] = useState(0);
|
|
66
|
+
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
setTotal(items.reduce((sum, item) => sum + item.price, 0));
|
|
69
|
+
setItemCount(items.length);
|
|
70
|
+
}, [items]); // Now you have to keep these in sync
|
|
71
|
+
};
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 3. Immutable Updates
|
|
75
|
+
|
|
76
|
+
Never mutate state directly.
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
// Good: Immutable update
|
|
80
|
+
setItems(items => [...items, newItem]);
|
|
81
|
+
setUser(user => ({ ...user, name: newName }));
|
|
82
|
+
|
|
83
|
+
// Bad: Mutation
|
|
84
|
+
items.push(newItem);
|
|
85
|
+
setItems(items);
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Local State Patterns
|
|
89
|
+
|
|
90
|
+
### useState for Simple Values
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
const [count, setCount] = useState(0);
|
|
94
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### useReducer for Complex State
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
type State = { count: number; step: number };
|
|
101
|
+
type Action =
|
|
102
|
+
| { type: 'increment' }
|
|
103
|
+
| { type: 'decrement' }
|
|
104
|
+
| { type: 'setStep'; step: number };
|
|
105
|
+
|
|
106
|
+
const reducer = (state: State, action: Action): State => {
|
|
107
|
+
switch (action.type) {
|
|
108
|
+
case 'increment':
|
|
109
|
+
return { ...state, count: state.count + state.step };
|
|
110
|
+
case 'decrement':
|
|
111
|
+
return { ...state, count: state.count - state.step };
|
|
112
|
+
case 'setStep':
|
|
113
|
+
return { ...state, step: action.step };
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const Counter = () => {
|
|
118
|
+
const [state, dispatch] = useReducer(reducer, { count: 0, step: 1 });
|
|
119
|
+
// ...
|
|
120
|
+
};
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Shared State Patterns
|
|
124
|
+
|
|
125
|
+
### Context for Theme/Auth/Global UI
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
const ThemeContext = createContext<Theme>('light');
|
|
129
|
+
|
|
130
|
+
const ThemeProvider = ({ children }: { children: React.ReactNode }) => {
|
|
131
|
+
const [theme, setTheme] = useState<Theme>('light');
|
|
132
|
+
return (
|
|
133
|
+
<ThemeContext.Provider value={{ theme, setTheme }}>
|
|
134
|
+
{children}
|
|
135
|
+
</ThemeContext.Provider>
|
|
136
|
+
);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const useTheme = () => useContext(ThemeContext);
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### State Libraries for Complex Apps
|
|
143
|
+
|
|
144
|
+
Consider dedicated state management libraries when:
|
|
145
|
+
- Many components need the same state
|
|
146
|
+
- Complex update logic
|
|
147
|
+
- Need for devtools/debugging
|
|
148
|
+
- Time-travel debugging needed
|
|
149
|
+
|
|
150
|
+
## Server State Patterns
|
|
151
|
+
|
|
152
|
+
### Separate Server State from UI State
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
// Good: Dedicated server state handling
|
|
156
|
+
const { data: users, isLoading, error } = useQuery('users', fetchUsers);
|
|
157
|
+
|
|
158
|
+
// Use data in UI state
|
|
159
|
+
const [selectedUserId, setSelectedUserId] = useState<string | null>(null);
|
|
160
|
+
const selectedUser = users?.find(u => u.id === selectedUserId);
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Handle Loading & Error States
|
|
164
|
+
|
|
165
|
+
```tsx
|
|
166
|
+
const UserList = () => {
|
|
167
|
+
const { data, isLoading, error } = useQuery('users', fetchUsers);
|
|
168
|
+
|
|
169
|
+
if (isLoading) return <Spinner />;
|
|
170
|
+
if (error) return <Error message={error.message} />;
|
|
171
|
+
if (!data?.length) return <Empty message="No users found" />;
|
|
172
|
+
|
|
173
|
+
return <ul>{data.map(user => <UserItem key={user.id} user={user} />)}</ul>;
|
|
174
|
+
};
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Anti-Patterns
|
|
178
|
+
|
|
179
|
+
### Prop Drilling
|
|
180
|
+
|
|
181
|
+
❌ Passing props through many layers:
|
|
182
|
+
```tsx
|
|
183
|
+
<App user={user}>
|
|
184
|
+
<Layout user={user}>
|
|
185
|
+
<Sidebar user={user}>
|
|
186
|
+
<UserMenu user={user} />
|
|
187
|
+
</Sidebar>
|
|
188
|
+
</Layout>
|
|
189
|
+
</App>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
✅ Use context or composition:
|
|
193
|
+
```tsx
|
|
194
|
+
<UserProvider user={user}>
|
|
195
|
+
<App>
|
|
196
|
+
<Layout>
|
|
197
|
+
<Sidebar>
|
|
198
|
+
<UserMenu /> {/* Uses useUser() hook */}
|
|
199
|
+
</Sidebar>
|
|
200
|
+
</Layout>
|
|
201
|
+
</App>
|
|
202
|
+
</UserProvider>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Over-Centralization
|
|
206
|
+
|
|
207
|
+
❌ Putting everything in global state
|
|
208
|
+
✅ Keep local state local, only share what's needed
|
|
209
|
+
|
|
210
|
+
### Stale Closures
|
|
211
|
+
|
|
212
|
+
❌ Using outdated values in callbacks:
|
|
213
|
+
```tsx
|
|
214
|
+
const [count, setCount] = useState(0);
|
|
215
|
+
const handleClick = () => {
|
|
216
|
+
setTimeout(() => console.log(count), 1000); // Might be stale
|
|
217
|
+
};
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
✅ Use refs or functional updates:
|
|
221
|
+
```tsx
|
|
222
|
+
const countRef = useRef(count);
|
|
223
|
+
countRef.current = count;
|
|
224
|
+
const handleClick = () => {
|
|
225
|
+
setTimeout(() => console.log(countRef.current), 1000);
|
|
226
|
+
};
|
|
227
|
+
```
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
# Styling Guidelines
|
|
2
|
+
|
|
3
|
+
Best practices for styling frontend applications.
|
|
4
|
+
|
|
5
|
+
## Principles
|
|
6
|
+
|
|
7
|
+
### 1. Consistency
|
|
8
|
+
Use a design system or consistent conventions throughout the application.
|
|
9
|
+
|
|
10
|
+
### 2. Maintainability
|
|
11
|
+
Styles should be easy to find, understand, and modify.
|
|
12
|
+
|
|
13
|
+
### 3. Performance
|
|
14
|
+
Minimize CSS bundle size and avoid layout thrashing.
|
|
15
|
+
|
|
16
|
+
### 4. Responsiveness
|
|
17
|
+
Design for all screen sizes from the start.
|
|
18
|
+
|
|
19
|
+
## CSS Organization
|
|
20
|
+
|
|
21
|
+
### Component-Scoped Styles
|
|
22
|
+
|
|
23
|
+
Keep styles close to their components.
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
components/
|
|
27
|
+
├── Button/
|
|
28
|
+
│ ├── Button.tsx
|
|
29
|
+
│ ├── Button.styles.css # or .module.css
|
|
30
|
+
│ └── Button.test.tsx
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Naming Conventions
|
|
34
|
+
|
|
35
|
+
Use clear, consistent naming:
|
|
36
|
+
|
|
37
|
+
```css
|
|
38
|
+
/* BEM-style (Block Element Modifier) */
|
|
39
|
+
.card { }
|
|
40
|
+
.card__header { }
|
|
41
|
+
.card__body { }
|
|
42
|
+
.card--featured { }
|
|
43
|
+
|
|
44
|
+
/* Utility-based */
|
|
45
|
+
.flex .items-center .gap-4 .p-2
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Responsive Design
|
|
49
|
+
|
|
50
|
+
### Mobile-First
|
|
51
|
+
|
|
52
|
+
Start with mobile styles, add complexity for larger screens.
|
|
53
|
+
|
|
54
|
+
```css
|
|
55
|
+
/* Base: Mobile */
|
|
56
|
+
.container {
|
|
57
|
+
padding: 1rem;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* Tablet and up */
|
|
61
|
+
@media (min-width: 768px) {
|
|
62
|
+
.container {
|
|
63
|
+
padding: 2rem;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* Desktop */
|
|
68
|
+
@media (min-width: 1024px) {
|
|
69
|
+
.container {
|
|
70
|
+
padding: 3rem;
|
|
71
|
+
max-width: 1200px;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Flexible Units
|
|
77
|
+
|
|
78
|
+
Prefer relative units for flexibility.
|
|
79
|
+
|
|
80
|
+
```css
|
|
81
|
+
/* Good: Flexible */
|
|
82
|
+
.container {
|
|
83
|
+
max-width: 80rem; /* 1280px at default font size */
|
|
84
|
+
padding: 1rem;
|
|
85
|
+
font-size: 1rem;
|
|
86
|
+
line-height: 1.5;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/* Avoid: Fixed pixels for text/spacing */
|
|
90
|
+
.container {
|
|
91
|
+
max-width: 1280px;
|
|
92
|
+
padding: 16px;
|
|
93
|
+
font-size: 16px;
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Layout
|
|
98
|
+
|
|
99
|
+
### Modern Layout Tools
|
|
100
|
+
|
|
101
|
+
Use Flexbox and Grid for layout.
|
|
102
|
+
|
|
103
|
+
```css
|
|
104
|
+
/* Flexbox for 1D layouts */
|
|
105
|
+
.nav {
|
|
106
|
+
display: flex;
|
|
107
|
+
align-items: center;
|
|
108
|
+
gap: 1rem;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/* Grid for 2D layouts */
|
|
112
|
+
.dashboard {
|
|
113
|
+
display: grid;
|
|
114
|
+
grid-template-columns: 250px 1fr;
|
|
115
|
+
grid-template-rows: auto 1fr auto;
|
|
116
|
+
gap: 1rem;
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Avoid Layout Hacks
|
|
121
|
+
|
|
122
|
+
❌ Don't use floats for layout
|
|
123
|
+
❌ Don't use tables for layout
|
|
124
|
+
❌ Avoid excessive negative margins
|
|
125
|
+
|
|
126
|
+
## Theming
|
|
127
|
+
|
|
128
|
+
### CSS Custom Properties
|
|
129
|
+
|
|
130
|
+
Use CSS variables for theming.
|
|
131
|
+
|
|
132
|
+
```css
|
|
133
|
+
:root {
|
|
134
|
+
--color-primary: #3b82f6;
|
|
135
|
+
--color-secondary: #64748b;
|
|
136
|
+
--color-background: #ffffff;
|
|
137
|
+
--color-text: #1e293b;
|
|
138
|
+
--spacing-sm: 0.5rem;
|
|
139
|
+
--spacing-md: 1rem;
|
|
140
|
+
--spacing-lg: 2rem;
|
|
141
|
+
--radius-sm: 0.25rem;
|
|
142
|
+
--radius-md: 0.5rem;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
[data-theme="dark"] {
|
|
146
|
+
--color-background: #0f172a;
|
|
147
|
+
--color-text: #f1f5f9;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.button {
|
|
151
|
+
background: var(--color-primary);
|
|
152
|
+
padding: var(--spacing-sm) var(--spacing-md);
|
|
153
|
+
border-radius: var(--radius-md);
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Performance
|
|
158
|
+
|
|
159
|
+
### Minimize Reflows
|
|
160
|
+
|
|
161
|
+
Group DOM reads and writes.
|
|
162
|
+
|
|
163
|
+
```js
|
|
164
|
+
// Bad: Causes multiple reflows
|
|
165
|
+
element.style.width = '100px';
|
|
166
|
+
const height = element.offsetHeight; // Read forces reflow
|
|
167
|
+
element.style.height = height + 'px';
|
|
168
|
+
|
|
169
|
+
// Good: Batch reads, then writes
|
|
170
|
+
const height = element.offsetHeight;
|
|
171
|
+
element.style.width = '100px';
|
|
172
|
+
element.style.height = height + 'px';
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Use Efficient Selectors
|
|
176
|
+
|
|
177
|
+
```css
|
|
178
|
+
/* Good: Specific, efficient */
|
|
179
|
+
.nav-item { }
|
|
180
|
+
.button-primary { }
|
|
181
|
+
|
|
182
|
+
/* Avoid: Expensive selectors */
|
|
183
|
+
div > ul > li > a { }
|
|
184
|
+
*:not(.something) { }
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Reduce Bundle Size
|
|
188
|
+
|
|
189
|
+
- Remove unused CSS (PurgeCSS, etc.)
|
|
190
|
+
- Use CSS code splitting
|
|
191
|
+
- Avoid importing entire libraries for a few utilities
|
|
192
|
+
|
|
193
|
+
## Common Patterns
|
|
194
|
+
|
|
195
|
+
### Visually Hidden (Screen Reader Only)
|
|
196
|
+
|
|
197
|
+
```css
|
|
198
|
+
.sr-only {
|
|
199
|
+
position: absolute;
|
|
200
|
+
width: 1px;
|
|
201
|
+
height: 1px;
|
|
202
|
+
padding: 0;
|
|
203
|
+
margin: -1px;
|
|
204
|
+
overflow: hidden;
|
|
205
|
+
clip: rect(0, 0, 0, 0);
|
|
206
|
+
white-space: nowrap;
|
|
207
|
+
border: 0;
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Truncate Text
|
|
212
|
+
|
|
213
|
+
```css
|
|
214
|
+
.truncate {
|
|
215
|
+
overflow: hidden;
|
|
216
|
+
text-overflow: ellipsis;
|
|
217
|
+
white-space: nowrap;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.line-clamp-2 {
|
|
221
|
+
display: -webkit-box;
|
|
222
|
+
-webkit-line-clamp: 2;
|
|
223
|
+
-webkit-box-orient: vertical;
|
|
224
|
+
overflow: hidden;
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Aspect Ratio
|
|
229
|
+
|
|
230
|
+
```css
|
|
231
|
+
.aspect-video {
|
|
232
|
+
aspect-ratio: 16 / 9;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.aspect-square {
|
|
236
|
+
aspect-ratio: 1 / 1;
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Anti-Patterns
|
|
241
|
+
|
|
242
|
+
### Avoid !important
|
|
243
|
+
|
|
244
|
+
```css
|
|
245
|
+
/* Bad */
|
|
246
|
+
.button { color: red !important; }
|
|
247
|
+
|
|
248
|
+
/* Good: Use specificity correctly */
|
|
249
|
+
.button.button-danger { color: red; }
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Avoid Inline Styles for Theming
|
|
253
|
+
|
|
254
|
+
```tsx
|
|
255
|
+
// Bad
|
|
256
|
+
<div style={{ color: isError ? 'red' : 'green' }}>
|
|
257
|
+
|
|
258
|
+
// Good: Use classes/data attributes
|
|
259
|
+
<div className={isError ? 'text-error' : 'text-success'}>
|
|
260
|
+
<div data-state={isError ? 'error' : 'success'}>
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Avoid Magic Numbers
|
|
264
|
+
|
|
265
|
+
```css
|
|
266
|
+
/* Bad */
|
|
267
|
+
.header { height: 73px; }
|
|
268
|
+
|
|
269
|
+
/* Good */
|
|
270
|
+
.header { height: var(--header-height); }
|
|
271
|
+
```
|