React bindings for Styletron CSS-in-JS toolkit providing styled components and hooks
—
Hook-based API for direct CSS class generation and integration with React functional components. Provides direct access to the Styletron engine for dynamic styling without creating styled components.
Returns a CSS function that generates class names from style objects, enabling direct style application within functional components.
/**
* Returns a CSS function that generates class names from style objects
* @returns Tuple containing the css function
*/
function useStyletron(): [(style: StyleObject) => string];Usage Examples:
import React, { useState } from "react";
import { useStyletron, Provider } from "styletron-react";
function DynamicComponent() {
const [css] = useStyletron();
const [isActive, setIsActive] = useState(false);
// Generate class names dynamically
const buttonClass = css({
padding: "8px 16px",
backgroundColor: isActive ? "green" : "blue",
color: "white",
border: "none",
borderRadius: "4px",
cursor: "pointer",
":hover": {
opacity: 0.8,
},
});
const containerClass = css({
display: "flex",
gap: "16px",
padding: "20px",
});
return (
<div className={containerClass}>
<button
className={buttonClass}
onClick={() => setIsActive(!isActive)}
>
{isActive ? "Active" : "Inactive"}
</button>
</div>
);
}
// Must be wrapped with Provider
function App() {
return (
<Provider value={engine}>
<DynamicComponent />
</Provider>
);
}import React, { useMemo } from "react";
import { useStyletron } from "styletron-react";
function OptimizedComponent({ theme, size }: {
theme: "light" | "dark";
size: "small" | "large";
}) {
const [css] = useStyletron();
// Memoize style objects for performance
const buttonStyles = useMemo(() => ({
padding: size === "large" ? "12px 24px" : "8px 16px",
fontSize: size === "large" ? "16px" : "14px",
backgroundColor: theme === "dark" ? "#333" : "#f0f0f0",
color: theme === "dark" ? "white" : "black",
border: `1px solid ${theme === "dark" ? "#555" : "#ccc"}`,
borderRadius: "4px",
}), [theme, size]);
const buttonClass = css(buttonStyles);
return (
<button className={buttonClass}>
Themed Button
</button>
);
}import React from "react";
import { useStyletron } from "styletron-react";
function ConditionalComponent({
variant,
disabled,
fullWidth
}: {
variant: "primary" | "secondary";
disabled?: boolean;
fullWidth?: boolean;
}) {
const [css] = useStyletron();
// Build styles conditionally
const baseStyles = {
padding: "8px 16px",
border: "none",
borderRadius: "4px",
cursor: disabled ? "not-allowed" : "pointer",
opacity: disabled ? 0.6 : 1,
width: fullWidth ? "100%" : "auto",
};
const variantStyles = variant === "primary"
? { backgroundColor: "blue", color: "white" }
: { backgroundColor: "gray", color: "black" };
const buttonClass = css({
...baseStyles,
...variantStyles,
});
return (
<button className={buttonClass} disabled={disabled}>
Conditional Button
</button>
);
}import React from "react";
import { useStyletron } from "styletron-react";
function CombinedClassComponent({ className }: { className?: string }) {
const [css] = useStyletron();
const dynamicClass = css({
padding: "16px",
backgroundColor: "lightblue",
borderRadius: "8px",
});
// Combine generated class with external className
const combinedClassName = className
? `${className} ${dynamicClass}`
: dynamicClass;
return (
<div className={combinedClassName}>
Combined Styling
</div>
);
}
// Usage
<CombinedClassComponent className="external-styles" />import React from "react";
import { useStyletron } from "styletron-react";
function ResponsiveComponent() {
const [css] = useStyletron();
const responsiveClass = css({
padding: "16px",
backgroundColor: "white",
borderRadius: "8px",
boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
":hover": {
boxShadow: "0 4px 8px rgba(0,0,0,0.15)",
transform: "translateY(-2px)",
},
":focus": {
outline: "2px solid blue",
outlineOffset: "2px",
},
"@media (max-width: 768px)": {
padding: "8px",
borderRadius: "4px",
},
"@media (max-width: 480px)": {
padding: "4px",
},
});
return (
<div className={responsiveClass} tabIndex={0}>
Responsive Component
</div>
);
}Use useMemo to prevent unnecessary style recalculations:
import React, { useMemo } from "react";
import { useStyletron } from "styletron-react";
function PerformantComponent({ color, size }: {
color: string;
size: number;
}) {
const [css] = useStyletron();
// Memoize expensive style calculations
const styles = useMemo(() => ({
backgroundColor: color,
width: `${size}px`,
height: `${size}px`,
borderRadius: "50%",
// ... complex calculations
}), [color, size]);
const className = css(styles);
return <div className={className} />;
}Extract static styles outside component for better performance:
import React from "react";
import { useStyletron } from "styletron-react";
// Static styles defined outside component
const STATIC_STYLES = {
container: {
display: "flex",
flexDirection: "column",
gap: "16px",
},
header: {
fontSize: "24px",
fontWeight: "bold",
marginBottom: "8px",
},
} as const;
function StaticStyledComponent() {
const [css] = useStyletron();
const containerClass = css(STATIC_STYLES.container);
const headerClass = css(STATIC_STYLES.header);
return (
<div className={containerClass}>
<h1 className={headerClass}>Title</h1>
<p>Content</p>
</div>
);
}type StyleObject = {
[property: string]: string | number | StyleObject;
// CSS properties
display?: string;
padding?: string | number;
margin?: string | number;
backgroundColor?: string;
color?: string;
// Pseudo-selectors
":hover"?: StyleObject;
":focus"?: StyleObject;
":active"?: StyleObject;
":disabled"?: StyleObject;
// Media queries
"@media (max-width: 768px)"?: StyleObject;
"@media (min-width: 769px)"?: StyleObject;
// ... other CSS properties and selectors
};Install with Tessl CLI
npx tessl i tessl/npm-styletron-react