JSS integration with React providing CSS-in-JS styling solutions with theming support
—
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.
Custom JSX factory that processes css prop and converts it to class names using css-jss.
/**
* JSX factory function that supports inline CSS via css prop
* @param type - Element type (string or component)
* @param props - Element props including optional css prop
* @param children - Child elements
* @returns React element with processed CSS
*/
function jsx(type: any, props: any, ...children: any[]): ReactElement;Usage Examples:
import React from 'react';
import { jsx } from 'react-jss';
// Configure JSX pragma to use react-jss jsx factory
/* @jsx jsx */
function MyComponent() {
return (
<div
css={{
padding: '20px',
backgroundColor: '#f5f5f5',
borderRadius: '8px',
boxShadow: '0 2px 4px rgba(0,0,0,0.1)'
}}
>
<h1
css={{
fontSize: '24px',
color: '#333',
marginBottom: '16px',
fontWeight: 'bold'
}}
>
Hello World
</h1>
<button
css={{
padding: '10px 20px',
backgroundColor: '#007bff',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
'&:hover': {
backgroundColor: '#0056b3'
}
}}
>
Click me
</button>
</div>
);
}Creates a custom JSX factory with a custom CSS processor.
/**
* Creates a custom JSX factory with custom CSS processor
* @param css - Optional custom CSS processor function
* @returns JSX factory function
*/
function createJsx(css?: CSSProcessor): typeof jsx;
interface CSSProcessor {
(styles: CSSObject): string;
}Usage Examples:
import React from 'react';
import { createJsx } from 'react-jss';
import customCssProcessor from 'my-css-processor';
// Create custom JSX factory with custom CSS processor
const jsx = createJsx(customCssProcessor);
/* @jsx jsx */
function MyComponent() {
return (
<div
css={{
padding: '20px',
backgroundColor: 'primary' // Custom processor might handle theme tokens
}}
>
Content with custom CSS processing
</div>
);
}The css prop works alongside regular className prop:
/* @jsx jsx */
function MyComponent() {
return (
<div
className="existing-class"
css={{
padding: '20px',
backgroundColor: '#f5f5f5'
}}
>
This div has both existing classes and css prop styles
</div>
);
}
// Results in className="existing-class generated-css-class"Use function-based CSS that responds to component state or props:
import React, { useState } from 'react';
import { jsx } from 'react-jss';
/* @jsx jsx */
function InteractiveButton() {
const [isActive, setIsActive] = useState(false);
const [variant, setVariant] = useState('primary');
return (
<button
css={{
padding: '10px 20px',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
backgroundColor: isActive
? '#28a745'
: variant === 'primary'
? '#007bff'
: '#6c757d',
color: 'white',
transform: isActive ? 'scale(1.05)' : 'scale(1)',
transition: 'all 0.3s ease',
'&:hover': {
opacity: 0.8
},
'&:active': {
transform: 'scale(0.95)'
}
}}
onClick={() => setIsActive(!isActive)}
>
{isActive ? 'Active' : 'Inactive'}
</button>
);
}Support for nested selectors and complex CSS:
/* @jsx jsx */
function Card() {
return (
<div
css={{
padding: '20px',
backgroundColor: 'white',
borderRadius: '8px',
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
transition: 'all 0.3s ease',
'&:hover': {
boxShadow: '0 4px 16px rgba(0,0,0,0.15)',
transform: 'translateY(-2px)'
},
'& .card-title': {
fontSize: '20px',
fontWeight: 'bold',
marginBottom: '12px',
color: '#333'
},
'& .card-content': {
lineHeight: 1.6,
color: '#666'
},
'& .card-footer': {
marginTop: '16px',
paddingTop: '16px',
borderTop: '1px solid #eee',
'& button': {
marginRight: '8px',
'&:last-child': {
marginRight: 0
}
}
}
}}
>
<div className="card-title">Card Title</div>
<div className="card-content">
This is the card content with some text.
</div>
<div className="card-footer">
<button>Action 1</button>
<button>Action 2</button>
</div>
</div>
);
}CSS prop supports media queries and responsive styling:
/* @jsx jsx */
function ResponsiveLayout() {
return (
<div
css={{
display: 'grid',
gap: '20px',
padding: '20px',
gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
'@media (max-width: 768px)': {
gridTemplateColumns: '1fr',
padding: '10px',
gap: '10px'
},
'@media (max-width: 480px)': {
padding: '5px',
gap: '5px'
}
}}
>
<div
css={{
backgroundColor: '#f8f9fa',
padding: '16px',
borderRadius: '8px',
'@media (max-width: 768px)': {
padding: '12px'
}
}}
>
Item 1
</div>
<div
css={{
backgroundColor: '#e9ecef',
padding: '16px',
borderRadius: '8px',
'@media (max-width: 768px)': {
padding: '12px'
}
}}
>
Item 2
</div>
</div>
);
}TypeScript configuration for jsx factory:
// tsconfig.json
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "react-jss"
}
}
// Or use pragma comment in individual files
/* @jsx jsx */
/* @jsxImportSource react-jss */interface CSSObject {
[key: string]: any;
}
interface CSSProps {
/** Inline CSS styles object */
css?: CSSObject;
/** Regular className prop */
className?: string;
}For proper JSX transformation with Babel:
// babel.config.js
module.exports = {
presets: [
['@babel/preset-react', {
pragma: 'jsx',
pragmaFrag: 'React.Fragment'
}]
]
};Configure webpack to handle the jsx factory:
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(js|jsx|ts|tsx)$/,
use: {
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-react', {
pragma: 'jsx'
}]
]
}
}
}
]
}
};Install with Tessl CLI
npx tessl i tessl/npm-react-jss