0
# JSX Factory
1
2
The JSX Factory provides a custom JSX factory that supports inline CSS via the `css` prop. This approach is useful for quick styling and prototyping without defining separate style objects.
3
4
## Capabilities
5
6
### jsx Factory Function
7
8
Custom JSX factory that processes `css` prop and converts it to class names using css-jss.
9
10
```typescript { .api }
11
/**
12
* JSX factory function that supports inline CSS via css prop
13
* @param type - Element type (string or component)
14
* @param props - Element props including optional css prop
15
* @param children - Child elements
16
* @returns React element with processed CSS
17
*/
18
function jsx(type: any, props: any, ...children: any[]): ReactElement;
19
```
20
21
**Usage Examples:**
22
23
```typescript
24
import React from 'react';
25
import { jsx } from 'react-jss';
26
27
// Configure JSX pragma to use react-jss jsx factory
28
/* @jsx jsx */
29
30
function MyComponent() {
31
return (
32
<div
33
css={{
34
padding: '20px',
35
backgroundColor: '#f5f5f5',
36
borderRadius: '8px',
37
boxShadow: '0 2px 4px rgba(0,0,0,0.1)'
38
}}
39
>
40
<h1
41
css={{
42
fontSize: '24px',
43
color: '#333',
44
marginBottom: '16px',
45
fontWeight: 'bold'
46
}}
47
>
48
Hello World
49
</h1>
50
<button
51
css={{
52
padding: '10px 20px',
53
backgroundColor: '#007bff',
54
color: 'white',
55
border: 'none',
56
borderRadius: '4px',
57
cursor: 'pointer',
58
'&:hover': {
59
backgroundColor: '#0056b3'
60
}
61
}}
62
>
63
Click me
64
</button>
65
</div>
66
);
67
}
68
```
69
70
### createJsx Function
71
72
Creates a custom JSX factory with a custom CSS processor.
73
74
```typescript { .api }
75
/**
76
* Creates a custom JSX factory with custom CSS processor
77
* @param css - Optional custom CSS processor function
78
* @returns JSX factory function
79
*/
80
function createJsx(css?: CSSProcessor): typeof jsx;
81
82
interface CSSProcessor {
83
(styles: CSSObject): string;
84
}
85
```
86
87
**Usage Examples:**
88
89
```typescript
90
import React from 'react';
91
import { createJsx } from 'react-jss';
92
import customCssProcessor from 'my-css-processor';
93
94
// Create custom JSX factory with custom CSS processor
95
const jsx = createJsx(customCssProcessor);
96
97
/* @jsx jsx */
98
99
function MyComponent() {
100
return (
101
<div
102
css={{
103
padding: '20px',
104
backgroundColor: 'primary' // Custom processor might handle theme tokens
105
}}
106
>
107
Content with custom CSS processing
108
</div>
109
);
110
}
111
```
112
113
### Combining css prop with className
114
115
The `css` prop works alongside regular `className` prop:
116
117
```typescript
118
/* @jsx jsx */
119
120
function MyComponent() {
121
return (
122
<div
123
className="existing-class"
124
css={{
125
padding: '20px',
126
backgroundColor: '#f5f5f5'
127
}}
128
>
129
This div has both existing classes and css prop styles
130
</div>
131
);
132
}
133
// Results in className="existing-class generated-css-class"
134
```
135
136
### Dynamic CSS with Props
137
138
Use function-based CSS that responds to component state or props:
139
140
```typescript
141
import React, { useState } from 'react';
142
import { jsx } from 'react-jss';
143
144
/* @jsx jsx */
145
146
function InteractiveButton() {
147
const [isActive, setIsActive] = useState(false);
148
const [variant, setVariant] = useState('primary');
149
150
return (
151
<button
152
css={{
153
padding: '10px 20px',
154
border: 'none',
155
borderRadius: '4px',
156
cursor: 'pointer',
157
backgroundColor: isActive
158
? '#28a745'
159
: variant === 'primary'
160
? '#007bff'
161
: '#6c757d',
162
color: 'white',
163
transform: isActive ? 'scale(1.05)' : 'scale(1)',
164
transition: 'all 0.3s ease',
165
'&:hover': {
166
opacity: 0.8
167
},
168
'&:active': {
169
transform: 'scale(0.95)'
170
}
171
}}
172
onClick={() => setIsActive(!isActive)}
173
>
174
{isActive ? 'Active' : 'Inactive'}
175
</button>
176
);
177
}
178
```
179
180
### Nested and Complex Styles
181
182
Support for nested selectors and complex CSS:
183
184
```typescript
185
/* @jsx jsx */
186
187
function Card() {
188
return (
189
<div
190
css={{
191
padding: '20px',
192
backgroundColor: 'white',
193
borderRadius: '8px',
194
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
195
transition: 'all 0.3s ease',
196
'&:hover': {
197
boxShadow: '0 4px 16px rgba(0,0,0,0.15)',
198
transform: 'translateY(-2px)'
199
},
200
'& .card-title': {
201
fontSize: '20px',
202
fontWeight: 'bold',
203
marginBottom: '12px',
204
color: '#333'
205
},
206
'& .card-content': {
207
lineHeight: 1.6,
208
color: '#666'
209
},
210
'& .card-footer': {
211
marginTop: '16px',
212
paddingTop: '16px',
213
borderTop: '1px solid #eee',
214
'& button': {
215
marginRight: '8px',
216
'&:last-child': {
217
marginRight: 0
218
}
219
}
220
}
221
}}
222
>
223
<div className="card-title">Card Title</div>
224
<div className="card-content">
225
This is the card content with some text.
226
</div>
227
<div className="card-footer">
228
<button>Action 1</button>
229
<button>Action 2</button>
230
</div>
231
</div>
232
);
233
}
234
```
235
236
### Media Queries and Responsive Design
237
238
CSS prop supports media queries and responsive styling:
239
240
```typescript
241
/* @jsx jsx */
242
243
function ResponsiveLayout() {
244
return (
245
<div
246
css={{
247
display: 'grid',
248
gap: '20px',
249
padding: '20px',
250
gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
251
'@media (max-width: 768px)': {
252
gridTemplateColumns: '1fr',
253
padding: '10px',
254
gap: '10px'
255
},
256
'@media (max-width: 480px)': {
257
padding: '5px',
258
gap: '5px'
259
}
260
}}
261
>
262
<div
263
css={{
264
backgroundColor: '#f8f9fa',
265
padding: '16px',
266
borderRadius: '8px',
267
'@media (max-width: 768px)': {
268
padding: '12px'
269
}
270
}}
271
>
272
Item 1
273
</div>
274
<div
275
css={{
276
backgroundColor: '#e9ecef',
277
padding: '16px',
278
borderRadius: '8px',
279
'@media (max-width: 768px)': {
280
padding: '12px'
281
}
282
}}
283
>
284
Item 2
285
</div>
286
</div>
287
);
288
}
289
```
290
291
### Using with TypeScript
292
293
TypeScript configuration for jsx factory:
294
295
```typescript
296
// tsconfig.json
297
{
298
"compilerOptions": {
299
"jsx": "react-jsx",
300
"jsxImportSource": "react-jss"
301
}
302
}
303
304
// Or use pragma comment in individual files
305
/* @jsx jsx */
306
/* @jsxImportSource react-jss */
307
```
308
309
### CSS Object Interface
310
311
```typescript { .api }
312
interface CSSObject {
313
[key: string]: any;
314
}
315
316
interface CSSProps {
317
/** Inline CSS styles object */
318
css?: CSSObject;
319
/** Regular className prop */
320
className?: string;
321
}
322
```
323
324
## Configuration
325
326
### Babel Configuration
327
328
For proper JSX transformation with Babel:
329
330
```javascript
331
// babel.config.js
332
module.exports = {
333
presets: [
334
['@babel/preset-react', {
335
pragma: 'jsx',
336
pragmaFrag: 'React.Fragment'
337
}]
338
]
339
};
340
```
341
342
### Webpack Configuration
343
344
Configure webpack to handle the jsx factory:
345
346
```javascript
347
// webpack.config.js
348
module.exports = {
349
module: {
350
rules: [
351
{
352
test: /\.(js|jsx|ts|tsx)$/,
353
use: {
354
loader: 'babel-loader',
355
options: {
356
presets: [
357
['@babel/preset-react', {
358
pragma: 'jsx'
359
}]
360
]
361
}
362
}
363
}
364
]
365
}
366
};
367
```