JSS integration with React providing CSS-in-JS styling solutions with theming support
—
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.
Creates styled components with CSS-in-JS capabilities, supporting both HTML tags and custom React components.
/**
* Creates styled components similar to styled-components library
* @param tagOrComponent - HTML tag name or React component to style
* @param options - Configuration options for styled component creation
* @returns Function that accepts style definitions and returns a styled component
*/
function styled(
tagOrComponent: string | ComponentType<any>,
options?: StyledOptions
): (...styles: Array<CSSObject | ((props: any) => CSSObject)>) => ComponentType<any>;
interface StyledOptions extends BaseOptions {
/** Function to determine which props should be forwarded to the DOM */
shouldForwardProp?: (prop: string) => boolean;
/** Custom theming context */
theming?: Theming<any>;
}Usage Examples:
import React from 'react';
import { styled } from 'react-jss';
// Basic styled component
const StyledButton = styled('button')({
padding: '10px 20px',
backgroundColor: '#007bff',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
'&:hover': {
backgroundColor: '#0056b3'
}
});
function App() {
return (
<StyledButton onClick={() => alert('Clicked!')}>
Click me
</StyledButton>
);
}Create styled components that respond to props:
import React from 'react';
import { styled } from 'react-jss';
const StyledCard = styled('div')({
padding: '16px',
borderRadius: '8px',
border: '1px solid #dee2e6',
backgroundColor: (props) => {
switch (props.variant) {
case 'primary': return '#007bff';
case 'success': return '#28a745';
case 'warning': return '#ffc107';
case 'danger': return '#dc3545';
default: return '#f8f9fa';
}
},
color: (props) => props.variant && props.variant !== 'warning' ? 'white' : '#333',
width: (props) => props.fullWidth ? '100%' : 'auto',
opacity: (props) => props.disabled ? 0.6 : 1,
cursor: (props) => props.disabled ? 'not-allowed' : 'default'
});
const StyledTitle = styled('h2')({
fontSize: (props) => props.size === 'large' ? '24px' : '18px',
fontWeight: (props) => props.bold ? 'bold' : 'normal',
marginBottom: '12px',
textAlign: (props) => props.centered ? 'center' : 'left'
});
function Card({ variant, fullWidth, disabled, title, size, bold, centered, children, ...props }) {
return (
<StyledCard variant={variant} fullWidth={fullWidth} disabled={disabled} {...props}>
<StyledTitle size={size} bold={bold} centered={centered}>
{title}
</StyledTitle>
{children}
</StyledCard>
);
}
// Usage
<Card variant="primary" fullWidth title="My Card" size="large" bold centered>
Card content here
</Card>Combine multiple style objects for complex styling:
import React from 'react';
import { styled } from 'react-jss';
const baseButtonStyles = {
padding: '10px 20px',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
fontSize: '16px',
transition: 'all 0.3s ease'
};
const primaryButtonStyles = {
backgroundColor: '#007bff',
color: 'white',
'&:hover': {
backgroundColor: '#0056b3'
}
};
const sizeStyles = (props) => ({
padding: props.size === 'large' ? '12px 24px' : props.size === 'small' ? '6px 12px' : '10px 20px',
fontSize: props.size === 'large' ? '18px' : props.size === 'small' ? '14px' : '16px'
});
const StyledButton = styled('button')(
baseButtonStyles,
primaryButtonStyles,
sizeStyles
);
function Button({ size = 'medium', children, ...props }) {
return (
<StyledButton size={size} {...props}>
{children}
</StyledButton>
);
}Style existing React components:
import React from 'react';
import { styled } from 'react-jss';
// Original component
const CustomInput = React.forwardRef(({ label, error, ...props }, ref) => (
<div>
{label && <label>{label}</label>}
<input ref={ref} {...props} />
{error && <span className="error">{error}</span>}
</div>
));
// Styled version
const StyledInput = styled(CustomInput)({
'& label': {
display: 'block',
marginBottom: '4px',
fontWeight: 'bold',
color: '#333'
},
'& input': {
width: '100%',
padding: '8px 12px',
border: '1px solid #ccc',
borderRadius: '4px',
fontSize: '16px',
'&:focus': {
outline: 'none',
borderColor: '#007bff',
boxShadow: '0 0 0 2px rgba(0, 123, 255, 0.25)'
}
},
'& .error': {
display: 'block',
marginTop: '4px',
color: '#dc3545',
fontSize: '14px'
}
});
// Usage
<StyledInput
label="Email"
type="email"
placeholder="Enter your email"
error="Please enter a valid email"
/>Use themed styled components:
import React from 'react';
import { styled, ThemeProvider } from 'react-jss';
const ThemedButton = styled('button')((props) => ({
padding: props.theme.spacing.medium,
backgroundColor: props.theme.colors.primary,
color: props.theme.colors.white,
border: 'none',
borderRadius: props.theme.borderRadius,
fontSize: props.theme.typography.button.fontSize,
fontWeight: props.theme.typography.button.fontWeight,
cursor: 'pointer',
transition: 'all 0.3s ease',
'&:hover': {
backgroundColor: props.theme.colors.primaryDark
},
'&:disabled': {
backgroundColor: props.theme.colors.disabled,
cursor: 'not-allowed'
}
}));
const theme = {
colors: {
primary: '#007bff',
primaryDark: '#0056b3',
white: '#ffffff',
disabled: '#6c757d'
},
spacing: {
small: '8px',
medium: '16px',
large: '24px'
},
borderRadius: '4px',
typography: {
button: {
fontSize: '16px',
fontWeight: 600
}
}
};
function App() {
return (
<ThemeProvider theme={theme}>
<ThemedButton>Themed Button</ThemedButton>
</ThemeProvider>
);
}Control which props are forwarded to the DOM:
import React from 'react';
import { styled } from 'react-jss';
// Only forward standard HTML props, not custom styling props
const StyledDiv = styled('div', {
shouldForwardProp: (prop) => !['variant', 'size', 'fullWidth'].includes(prop)
})({
padding: '16px',
backgroundColor: (props) => props.variant === 'dark' ? '#333' : '#f8f9fa',
color: (props) => props.variant === 'dark' ? 'white' : '#333',
width: (props) => props.fullWidth ? '100%' : 'auto',
fontSize: (props) => props.size === 'large' ? '18px' : '16px'
});
// Usage - custom props won't appear in DOM
<StyledDiv variant="dark" size="large" fullWidth>
This div gets styled but custom props aren't in the DOM
</StyledDiv>Create components that can render as different HTML elements:
import React from 'react';
import { styled } from 'react-jss';
const StyledBox = styled('div')({
padding: '16px',
backgroundColor: '#f8f9fa',
borderRadius: '8px',
border: '1px solid #dee2e6'
});
function Box({ as = 'div', children, ...props }) {
return (
<StyledBox as={as} {...props}>
{children}
</StyledBox>
);
}
// Usage
<Box>Default div</Box>
<Box as="section">Rendered as section</Box>
<Box as="article">Rendered as article</Box>interface CSSObject {
[key: string]: any;
}
interface BaseOptions<Theme = DefaultTheme> extends StyleSheetFactoryOptions {
/** Index for controlling stylesheet insertion order */
index?: number;
/** Custom theming context */
theming?: Theming<Theme>;
}Install with Tessl CLI
npx tessl i tessl/npm-react-jss