0
# Styled Components API
1
2
The Styled Components API provides a styled-components-like interface for creating styled React components. This approach is ideal for component libraries and when you prefer component-based styling patterns.
3
4
## Capabilities
5
6
### styled Function
7
8
Creates styled components with CSS-in-JS capabilities, supporting both HTML tags and custom React components.
9
10
```typescript { .api }
11
/**
12
* Creates styled components similar to styled-components library
13
* @param tagOrComponent - HTML tag name or React component to style
14
* @param options - Configuration options for styled component creation
15
* @returns Function that accepts style definitions and returns a styled component
16
*/
17
function styled(
18
tagOrComponent: string | ComponentType<any>,
19
options?: StyledOptions
20
): (...styles: Array<CSSObject | ((props: any) => CSSObject)>) => ComponentType<any>;
21
22
interface StyledOptions extends BaseOptions {
23
/** Function to determine which props should be forwarded to the DOM */
24
shouldForwardProp?: (prop: string) => boolean;
25
/** Custom theming context */
26
theming?: Theming<any>;
27
}
28
```
29
30
**Usage Examples:**
31
32
```typescript
33
import React from 'react';
34
import { styled } from 'react-jss';
35
36
// Basic styled component
37
const StyledButton = styled('button')({
38
padding: '10px 20px',
39
backgroundColor: '#007bff',
40
color: 'white',
41
border: 'none',
42
borderRadius: '4px',
43
cursor: 'pointer',
44
'&:hover': {
45
backgroundColor: '#0056b3'
46
}
47
});
48
49
function App() {
50
return (
51
<StyledButton onClick={() => alert('Clicked!')}>
52
Click me
53
</StyledButton>
54
);
55
}
56
```
57
58
### Dynamic Styling with Props
59
60
Create styled components that respond to props:
61
62
```typescript
63
import React from 'react';
64
import { styled } from 'react-jss';
65
66
const StyledCard = styled('div')({
67
padding: '16px',
68
borderRadius: '8px',
69
border: '1px solid #dee2e6',
70
backgroundColor: (props) => {
71
switch (props.variant) {
72
case 'primary': return '#007bff';
73
case 'success': return '#28a745';
74
case 'warning': return '#ffc107';
75
case 'danger': return '#dc3545';
76
default: return '#f8f9fa';
77
}
78
},
79
color: (props) => props.variant && props.variant !== 'warning' ? 'white' : '#333',
80
width: (props) => props.fullWidth ? '100%' : 'auto',
81
opacity: (props) => props.disabled ? 0.6 : 1,
82
cursor: (props) => props.disabled ? 'not-allowed' : 'default'
83
});
84
85
const StyledTitle = styled('h2')({
86
fontSize: (props) => props.size === 'large' ? '24px' : '18px',
87
fontWeight: (props) => props.bold ? 'bold' : 'normal',
88
marginBottom: '12px',
89
textAlign: (props) => props.centered ? 'center' : 'left'
90
});
91
92
function Card({ variant, fullWidth, disabled, title, size, bold, centered, children, ...props }) {
93
return (
94
<StyledCard variant={variant} fullWidth={fullWidth} disabled={disabled} {...props}>
95
<StyledTitle size={size} bold={bold} centered={centered}>
96
{title}
97
</StyledTitle>
98
{children}
99
</StyledCard>
100
);
101
}
102
103
// Usage
104
<Card variant="primary" fullWidth title="My Card" size="large" bold centered>
105
Card content here
106
</Card>
107
```
108
109
### Multiple Style Objects
110
111
Combine multiple style objects for complex styling:
112
113
```typescript
114
import React from 'react';
115
import { styled } from 'react-jss';
116
117
const baseButtonStyles = {
118
padding: '10px 20px',
119
border: 'none',
120
borderRadius: '4px',
121
cursor: 'pointer',
122
fontSize: '16px',
123
transition: 'all 0.3s ease'
124
};
125
126
const primaryButtonStyles = {
127
backgroundColor: '#007bff',
128
color: 'white',
129
'&:hover': {
130
backgroundColor: '#0056b3'
131
}
132
};
133
134
const sizeStyles = (props) => ({
135
padding: props.size === 'large' ? '12px 24px' : props.size === 'small' ? '6px 12px' : '10px 20px',
136
fontSize: props.size === 'large' ? '18px' : props.size === 'small' ? '14px' : '16px'
137
});
138
139
const StyledButton = styled('button')(
140
baseButtonStyles,
141
primaryButtonStyles,
142
sizeStyles
143
);
144
145
function Button({ size = 'medium', children, ...props }) {
146
return (
147
<StyledButton size={size} {...props}>
148
{children}
149
</StyledButton>
150
);
151
}
152
```
153
154
### Styling Custom Components
155
156
Style existing React components:
157
158
```typescript
159
import React from 'react';
160
import { styled } from 'react-jss';
161
162
// Original component
163
const CustomInput = React.forwardRef(({ label, error, ...props }, ref) => (
164
<div>
165
{label && <label>{label}</label>}
166
<input ref={ref} {...props} />
167
{error && <span className="error">{error}</span>}
168
</div>
169
));
170
171
// Styled version
172
const StyledInput = styled(CustomInput)({
173
'& label': {
174
display: 'block',
175
marginBottom: '4px',
176
fontWeight: 'bold',
177
color: '#333'
178
},
179
'& input': {
180
width: '100%',
181
padding: '8px 12px',
182
border: '1px solid #ccc',
183
borderRadius: '4px',
184
fontSize: '16px',
185
'&:focus': {
186
outline: 'none',
187
borderColor: '#007bff',
188
boxShadow: '0 0 0 2px rgba(0, 123, 255, 0.25)'
189
}
190
},
191
'& .error': {
192
display: 'block',
193
marginTop: '4px',
194
color: '#dc3545',
195
fontSize: '14px'
196
}
197
});
198
199
// Usage
200
<StyledInput
201
label="Email"
202
type="email"
203
placeholder="Enter your email"
204
error="Please enter a valid email"
205
/>
206
```
207
208
### Theme Integration
209
210
Use themed styled components:
211
212
```typescript
213
import React from 'react';
214
import { styled, ThemeProvider } from 'react-jss';
215
216
const ThemedButton = styled('button')((props) => ({
217
padding: props.theme.spacing.medium,
218
backgroundColor: props.theme.colors.primary,
219
color: props.theme.colors.white,
220
border: 'none',
221
borderRadius: props.theme.borderRadius,
222
fontSize: props.theme.typography.button.fontSize,
223
fontWeight: props.theme.typography.button.fontWeight,
224
cursor: 'pointer',
225
transition: 'all 0.3s ease',
226
'&:hover': {
227
backgroundColor: props.theme.colors.primaryDark
228
},
229
'&:disabled': {
230
backgroundColor: props.theme.colors.disabled,
231
cursor: 'not-allowed'
232
}
233
}));
234
235
const theme = {
236
colors: {
237
primary: '#007bff',
238
primaryDark: '#0056b3',
239
white: '#ffffff',
240
disabled: '#6c757d'
241
},
242
spacing: {
243
small: '8px',
244
medium: '16px',
245
large: '24px'
246
},
247
borderRadius: '4px',
248
typography: {
249
button: {
250
fontSize: '16px',
251
fontWeight: 600
252
}
253
}
254
};
255
256
function App() {
257
return (
258
<ThemeProvider theme={theme}>
259
<ThemedButton>Themed Button</ThemedButton>
260
</ThemeProvider>
261
);
262
}
263
```
264
265
### Prop Forwarding Control
266
267
Control which props are forwarded to the DOM:
268
269
```typescript
270
import React from 'react';
271
import { styled } from 'react-jss';
272
273
// Only forward standard HTML props, not custom styling props
274
const StyledDiv = styled('div', {
275
shouldForwardProp: (prop) => !['variant', 'size', 'fullWidth'].includes(prop)
276
})({
277
padding: '16px',
278
backgroundColor: (props) => props.variant === 'dark' ? '#333' : '#f8f9fa',
279
color: (props) => props.variant === 'dark' ? 'white' : '#333',
280
width: (props) => props.fullWidth ? '100%' : 'auto',
281
fontSize: (props) => props.size === 'large' ? '18px' : '16px'
282
});
283
284
// Usage - custom props won't appear in DOM
285
<StyledDiv variant="dark" size="large" fullWidth>
286
This div gets styled but custom props aren't in the DOM
287
</StyledDiv>
288
```
289
290
### Polymorphic Components
291
292
Create components that can render as different HTML elements:
293
294
```typescript
295
import React from 'react';
296
import { styled } from 'react-jss';
297
298
const StyledBox = styled('div')({
299
padding: '16px',
300
backgroundColor: '#f8f9fa',
301
borderRadius: '8px',
302
border: '1px solid #dee2e6'
303
});
304
305
function Box({ as = 'div', children, ...props }) {
306
return (
307
<StyledBox as={as} {...props}>
308
{children}
309
</StyledBox>
310
);
311
}
312
313
// Usage
314
<Box>Default div</Box>
315
<Box as="section">Rendered as section</Box>
316
<Box as="article">Rendered as article</Box>
317
```
318
319
## Types
320
321
```typescript { .api }
322
interface CSSObject {
323
[key: string]: any;
324
}
325
326
interface BaseOptions<Theme = DefaultTheme> extends StyleSheetFactoryOptions {
327
/** Index for controlling stylesheet insertion order */
328
index?: number;
329
/** Custom theming context */
330
theming?: Theming<Theme>;
331
}
332
```