@stylix/core 6.1.1 → 6.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 +140 -280
- package/dist/index.d.ts +85 -60
- package/dist/index.js +351 -301
- package/dist/index.js.map +1 -1
- package/docs/CLAUDE_CONTEXT.md +156 -0
- package/docs/cheatsheet.md +354 -0
- package/docs/patterns.md +754 -0
- package/docs/performance.md +291 -0
- package/docs/philosophy.md +168 -0
- package/package.json +23 -20
- package/tsconfig.json +0 -0
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
# Stylix Cheatsheet
|
|
2
|
+
|
|
3
|
+
Quick reference for common Stylix patterns.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Basic Styling
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import $ from '@stylix/core';
|
|
11
|
+
|
|
12
|
+
// Style props on HTML elements
|
|
13
|
+
<$.div color="red" font-size={16} margin={12}>
|
|
14
|
+
Content
|
|
15
|
+
</$.div>
|
|
16
|
+
|
|
17
|
+
// Both formats work: hyphenated or camelCase
|
|
18
|
+
<$.div font-weight="bold" />
|
|
19
|
+
<$.div fontWeight="bold" />
|
|
20
|
+
|
|
21
|
+
// Numeric values get 'px' automatically (except unitless props)
|
|
22
|
+
<$.div margin={12} /> // margin: 12px
|
|
23
|
+
<$.div line-height={1.5} /> // line-height: 1.5 (unitless)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## The `$css` Prop
|
|
29
|
+
|
|
30
|
+
Use `$css` for pseudo-classes, selectors, media queries, and complex styles.
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
<$.div
|
|
34
|
+
$css={{
|
|
35
|
+
// Pseudo-classes
|
|
36
|
+
'&:hover': { color: 'blue' },
|
|
37
|
+
'&:focus': { outline: '2px solid blue' },
|
|
38
|
+
'&:active': { transform: 'scale(0.98)' },
|
|
39
|
+
|
|
40
|
+
// Pseudo-elements
|
|
41
|
+
'&::before': { content: '"→ "' },
|
|
42
|
+
'&::after': { content: '""', display: 'block' },
|
|
43
|
+
|
|
44
|
+
// Descendant selectors
|
|
45
|
+
'p': { margin: 0 },
|
|
46
|
+
'.child-class': { color: 'red' },
|
|
47
|
+
'& > span': { fontWeight: 'bold' },
|
|
48
|
+
|
|
49
|
+
// Media queries
|
|
50
|
+
'@media (max-width: 600px)': {
|
|
51
|
+
fontSize: 14
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
// Container queries
|
|
55
|
+
'@container (min-width: 400px)': {
|
|
56
|
+
display: 'grid'
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
// Cascade layers
|
|
60
|
+
'@layer myLayer': {
|
|
61
|
+
color: 'purple'
|
|
62
|
+
}
|
|
63
|
+
}}
|
|
64
|
+
/>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Responsive Styles (Media Objects)
|
|
70
|
+
|
|
71
|
+
### Setup in Provider
|
|
72
|
+
|
|
73
|
+
Define keywords that map to style wrappers. These can be breakpoints, theme modes, or any condition:
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
import $, { StylixProvider } from '@stylix/core';
|
|
77
|
+
|
|
78
|
+
<StylixProvider
|
|
79
|
+
media={{
|
|
80
|
+
// Breakpoints
|
|
81
|
+
mobile: styles => ({ '@media (max-width: 480px)': styles }),
|
|
82
|
+
tablet: styles => ({ '@media (max-width: 1024px)': styles }),
|
|
83
|
+
// Theme modes (assumes data-theme attribute on html/body)
|
|
84
|
+
dark: styles => ({ '[data-theme="dark"] &': styles }),
|
|
85
|
+
light: styles => ({ '[data-theme="light"] &': styles }),
|
|
86
|
+
}}
|
|
87
|
+
>
|
|
88
|
+
<App />
|
|
89
|
+
</StylixProvider>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Usage
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
// On individual props
|
|
96
|
+
<$.div
|
|
97
|
+
font-size={{ default: 16, tablet: 14, mobile: 12 }}
|
|
98
|
+
padding={{ default: 24, mobile: 12 }}
|
|
99
|
+
/>
|
|
100
|
+
|
|
101
|
+
// In $css
|
|
102
|
+
<$.div
|
|
103
|
+
$css={{
|
|
104
|
+
display: 'flex',
|
|
105
|
+
flexDirection: 'row',
|
|
106
|
+
mobile: { flexDirection: 'column' }
|
|
107
|
+
}}
|
|
108
|
+
/>
|
|
109
|
+
|
|
110
|
+
// Nested combinations (e.g., dark mode + mobile)
|
|
111
|
+
<$.div
|
|
112
|
+
color={{
|
|
113
|
+
dark: {
|
|
114
|
+
default: '#e8e8e8', // dark mode default
|
|
115
|
+
mobile: '#fff' // dark mode on mobile
|
|
116
|
+
}
|
|
117
|
+
}}
|
|
118
|
+
/>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Styled Components
|
|
124
|
+
|
|
125
|
+
### Basic Pattern
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
import $, { StylixProps } from '@stylix/core';
|
|
129
|
+
|
|
130
|
+
function Button({ children, ...styles }: StylixProps & { children: React.ReactNode }) {
|
|
131
|
+
return (
|
|
132
|
+
<$.button
|
|
133
|
+
padding="10px 20px"
|
|
134
|
+
border="none"
|
|
135
|
+
cursor="pointer"
|
|
136
|
+
{...styles}
|
|
137
|
+
>
|
|
138
|
+
{children}
|
|
139
|
+
</$.button>
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Usage - can override any style
|
|
144
|
+
<Button color="white" background="blue">Click me</Button>
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### With Variants
|
|
148
|
+
|
|
149
|
+
```tsx
|
|
150
|
+
interface ButtonProps extends StylixProps {
|
|
151
|
+
variant?: 'primary' | 'secondary';
|
|
152
|
+
children: React.ReactNode;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function Button({ variant = 'primary', children, ...styles }: ButtonProps) {
|
|
156
|
+
return (
|
|
157
|
+
<$.button
|
|
158
|
+
padding="10px 20px"
|
|
159
|
+
background={variant === 'primary' ? 'blue' : 'gray'}
|
|
160
|
+
color="white"
|
|
161
|
+
{...styles}
|
|
162
|
+
>
|
|
163
|
+
{children}
|
|
164
|
+
</$.button>
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Allowing Style Overrides via `$css`
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
function Card({ $css, ...props }: StylixProps) {
|
|
173
|
+
return (
|
|
174
|
+
<$.div
|
|
175
|
+
$css={[
|
|
176
|
+
{
|
|
177
|
+
padding: 16,
|
|
178
|
+
borderRadius: 8,
|
|
179
|
+
'&:hover': { boxShadow: '0 4px 12px rgba(0,0,0,0.1)' }
|
|
180
|
+
},
|
|
181
|
+
$css // Parent overrides come last
|
|
182
|
+
]}
|
|
183
|
+
{...props}
|
|
184
|
+
/>
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Parent can override anything:
|
|
189
|
+
<Card $css={{ '&:hover': { boxShadow: 'none' } }} />
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Arrays in `$css`
|
|
195
|
+
|
|
196
|
+
Arrays merge styles with later values taking precedence:
|
|
197
|
+
|
|
198
|
+
```tsx
|
|
199
|
+
<$.div
|
|
200
|
+
$css={[
|
|
201
|
+
{ color: 'red', fontSize: 16 },
|
|
202
|
+
{ color: 'blue' }, // Overrides red
|
|
203
|
+
condition && { fontWeight: 'bold' }, // Conditional
|
|
204
|
+
]}
|
|
205
|
+
/>
|
|
206
|
+
// Result: color: blue, fontSize: 16, fontWeight: bold (if condition)
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Keyframe Animations
|
|
212
|
+
|
|
213
|
+
```tsx
|
|
214
|
+
import { useKeyframes } from '@stylix/core';
|
|
215
|
+
|
|
216
|
+
function Spinner() {
|
|
217
|
+
// Accepts any valid CSS keyframes (from/to, percentages, etc.)
|
|
218
|
+
const spin = useKeyframes({
|
|
219
|
+
from: { transform: 'rotate(0deg)' },
|
|
220
|
+
to: { transform: 'rotate(360deg)' }
|
|
221
|
+
// e.g., '0%, 100%': { ... }, '50%': { ... }
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
return (
|
|
225
|
+
<$.div animation={`${spin} 1s linear infinite`} />
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Global Styles
|
|
233
|
+
|
|
234
|
+
> **Note:** Global styles are only applied while the component is mounted. Use sparingly—primarily when you need media keywords or plugin capabilities. For static styles (resets, base typography), use a plain CSS file instead.
|
|
235
|
+
|
|
236
|
+
```tsx
|
|
237
|
+
import { useGlobalStyles } from '@stylix/core';
|
|
238
|
+
|
|
239
|
+
// Good use case: responsive global styles using media keywords
|
|
240
|
+
function ResponsiveTypography() {
|
|
241
|
+
useGlobalStyles({
|
|
242
|
+
h1: { fontSize: { default: 32, mobile: 24 } },
|
|
243
|
+
h2: { fontSize: { default: 24, mobile: 20 } },
|
|
244
|
+
body: { fontSize: { default: 16, mobile: 14 } }
|
|
245
|
+
});
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Using with Custom Components
|
|
253
|
+
|
|
254
|
+
### With `$el`
|
|
255
|
+
|
|
256
|
+
Pass an element instance. Stylix adds a `className` prop, so the component must support it.
|
|
257
|
+
|
|
258
|
+
```tsx
|
|
259
|
+
import MyComponent from './MyComponent';
|
|
260
|
+
|
|
261
|
+
<$ $el={<MyComponent someProp="value" />} color="red" padding={16} />
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### With `$render`
|
|
265
|
+
|
|
266
|
+
```tsx
|
|
267
|
+
<$
|
|
268
|
+
color="red"
|
|
269
|
+
padding={16}
|
|
270
|
+
$render={(className, props) => (
|
|
271
|
+
<MyComponent className={className} {...props} />
|
|
272
|
+
)}
|
|
273
|
+
/>
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Cascade Layers
|
|
279
|
+
|
|
280
|
+
Control specificity for parent/child overrides:
|
|
281
|
+
|
|
282
|
+
```tsx
|
|
283
|
+
// Child component defines a layer
|
|
284
|
+
const Widget = (props) => (
|
|
285
|
+
<$.div
|
|
286
|
+
$css={[
|
|
287
|
+
{
|
|
288
|
+
'@layer WidgetStyles': {
|
|
289
|
+
'&:hover:not(.disabled)': { color: 'red' }
|
|
290
|
+
}
|
|
291
|
+
},
|
|
292
|
+
props.$css
|
|
293
|
+
]}
|
|
294
|
+
/>
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
// Parent can override despite lower specificity
|
|
298
|
+
<Widget $css={{ color: 'blue' }} />
|
|
299
|
+
|
|
300
|
+
// Explicit layer ordering
|
|
301
|
+
$css={{
|
|
302
|
+
'@layer': 'base, components, overrides',
|
|
303
|
+
'@layer overrides': { color: 'green' }
|
|
304
|
+
}}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## Utilities
|
|
310
|
+
|
|
311
|
+
### `cx()` - Class Names
|
|
312
|
+
|
|
313
|
+
```tsx
|
|
314
|
+
import { cx } from '@stylix/core';
|
|
315
|
+
|
|
316
|
+
cx('foo', 'bar') // 'foo bar'
|
|
317
|
+
cx('a', false, 'b') // 'a b'
|
|
318
|
+
cx({ active: true, disabled: false }) // 'active'
|
|
319
|
+
cx(['a', 'b'], 'c') // 'a b c'
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
## Quick Type Reference
|
|
325
|
+
|
|
326
|
+
```tsx
|
|
327
|
+
import $, {
|
|
328
|
+
StylixProps, // All CSS props + $css
|
|
329
|
+
StylixHTMLProps, // CSS props + HTML element props
|
|
330
|
+
StylixStyles, // Style object type
|
|
331
|
+
StylixValue, // Value or media object
|
|
332
|
+
Extends, // Merge prop types
|
|
333
|
+
} from '@stylix/core';
|
|
334
|
+
|
|
335
|
+
// Extend for custom components
|
|
336
|
+
type MyProps = Extends<StylixProps, { variant: 'a' | 'b' }>;
|
|
337
|
+
|
|
338
|
+
// HTML-specific props
|
|
339
|
+
type InputProps = StylixHTMLProps<'input'>;
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## Unitless Properties
|
|
345
|
+
|
|
346
|
+
These properties remain unitless when given numeric values:
|
|
347
|
+
|
|
348
|
+
```
|
|
349
|
+
aspect-ratio, column-count, columns, fill-opacity, flex, flex-grow,
|
|
350
|
+
flex-shrink, font-weight, line-height, opacity, order, orphans,
|
|
351
|
+
stroke-opacity, widows, z-index, zoom
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
All other numeric values receive `px` automatically.
|