React implementation of Stitches CSS-in-JS library with type-safe styling and variants
—
Create React components with CSS-in-JS styling, variants, responsive design support, and full TypeScript integration. Styled components offer polymorphic as prop support, forwarded refs, and CSS prop overrides.
Creates styled React components from HTML elements or existing React components.
/**
* Creates a styled React component with CSS-in-JS styling
* @param type - HTML element tag name or React component
* @param composers - Style objects, strings, functions, or other components to compose
* @returns Styled React component with forwardRef support and variant props
*/
function styled<
Type extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
Composers extends Array<string | React.ComponentType<any> | Function | { [name: string]: unknown }>
>(
type: Type,
...composers: Composers
): StyledComponent<Type, StyledComponentProps<Composers>, {}, CSS>;
interface StyledComponent<Type, Props = {}, Media = {}, CSS = {}>
extends React.ForwardRefExoticComponent<
ComponentProps<Type> & TransformProps<Props, Media> & { css?: CSS }
> {
/** Standard component call with variant props */
(props: ComponentProps<Type> & TransformProps<Props, Media> & { css?: CSS }): React.ReactElement | null;
/** Polymorphic 'as' prop call to change the rendered element type */
<As extends keyof JSX.IntrinsicElements | React.ComponentType<any>>(
props: ComponentProps<As> & TransformProps<Props, Media> & { as: As; css?: CSS }
): React.ReactElement | null;
/** CSS class name generated for this component */
className: string;
/** CSS selector for targeting this component */
selector: string;
/** Internal symbols for type extraction */
[$$StyledComponentType]: Type;
[$$StyledComponentProps]: Props;
[$$StyledComponentMedia]: Media;
}
type StyledComponentProps<Composers extends readonly unknown[]> =
Composers extends readonly [infer First, ...infer Rest]
? First extends { variants?: infer V }
? V & StyledComponentProps<Rest>
: StyledComponentProps<Rest>
: {};
type TransformProps<Props, Media> = {
[K in keyof Props]: (
| Props[K]
| (
& { [KMedia in `@${keyof Media | 'initial'}`]?: Props[K] }
& { [KMedia in string]: Props[K] }
)
);
};Usage Examples:
import { styled, ComponentProps, CSS, $$StyledComponentType, $$StyledComponentProps, $$StyledComponentMedia } from "@stitches/react";
// Style HTML elements
const Button = styled('button', {
backgroundColor: 'blue',
color: 'white',
padding: '12px 16px',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
'&:hover': {
backgroundColor: 'darkblue'
}
});
// Style existing React components
const CustomInput = styled(ExistingComponent, {
border: '1px solid gray',
padding: '8px'
});
// Use polymorphic 'as' prop
function App() {
return (
<>
<Button>Regular button</Button>
<Button as="a" href="/link">Link styled as button</Button>
</>
);
}Define multiple style variations that can be controlled via props.
interface VariantConfig<T = any> {
variants?: {
[variantName: string]: {
[variantValue: string | number]: StyleObject;
};
};
compoundVariants?: Array<{
[variantName: string]: string | number;
css: StyleObject;
}>;
defaultVariants?: {
[variantName: string]: string | number;
};
}Usage Examples:
const Button = styled('button', {
padding: '12px 16px',
border: 'none',
borderRadius: '4px',
variants: {
color: {
primary: { backgroundColor: 'blue', color: 'white' },
secondary: { backgroundColor: 'gray', color: 'black' },
danger: { backgroundColor: 'red', color: 'white' }
},
size: {
small: { padding: '8px 12px', fontSize: '14px' },
medium: { padding: '12px 16px', fontSize: '16px' },
large: { padding: '16px 24px', fontSize: '18px' }
},
outline: {
true: { backgroundColor: 'transparent', border: '2px solid' }
}
},
compoundVariants: [
{
color: 'primary',
outline: true,
css: { borderColor: 'blue', color: 'blue' }
}
],
defaultVariants: {
color: 'primary',
size: 'medium'
}
});
// Usage with variant props
<Button color="danger" size="large">Delete</Button>
<Button color="primary" outline>Outlined Primary</Button>Override component styles on individual instances using the css prop.
interface StyledComponentProps {
/** Override styles for this specific instance */
css?: StyleObject;
}Usage Examples:
const Card = styled('div', {
padding: '16px',
backgroundColor: 'white',
borderRadius: '8px'
});
// Override styles with css prop
<Card css={{ backgroundColor: 'lightgray', padding: '24px' }}>
Custom styled card
</Card>Apply different styles based on configured media queries.
Usage Examples:
const ResponsiveBox = styled('div', {
padding: '16px',
// Apply styles at different breakpoints
'@media (min-width: 768px)': {
padding: '24px'
},
// Or use configured media queries
'@bp2': {
padding: '32px'
}
});
// Responsive variants
const ResponsiveText = styled('p', {
variants: {
size: {
small: {
fontSize: '14px',
'@bp2': { fontSize: '16px' }
},
large: {
fontSize: '18px',
'@bp2': { fontSize: '24px' }
}
}
}
});Compose styled components together for inheritance and extension.
Usage Examples:
// Base button
const BaseButton = styled('button', {
padding: '12px 16px',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
});
// Extend base button
const PrimaryButton = styled(BaseButton, {
backgroundColor: 'blue',
color: 'white'
});
// Further extend
const LargePrimaryButton = styled(PrimaryButton, {
padding: '16px 24px',
fontSize: '18px'
});All styled components automatically support React.forwardRef for ref forwarding.
Usage Examples:
import { useRef } from 'react';
const Input = styled('input', {
padding: '8px',
border: '1px solid gray',
borderRadius: '4px'
});
function App() {
const inputRef = useRef<HTMLInputElement>(null);
const focusInput = () => {
inputRef.current?.focus();
};
return (
<>
<Input ref={inputRef} placeholder="Type here..." />
<button onClick={focusInput}>Focus Input</button>
</>
);
}// Extract variant props from styled component
type VariantProps<Component extends { [key: string]: any }> =
TransformProps<
Component[$$StyledComponentProps],
Component[$$StyledComponentMedia]
>;
// Transform props with media query support
type TransformProps<Props, Media> = {
[K in keyof Props]: Props[K] | {
[MediaQuery in keyof Media | '@initial']?: Props[K];
};
};
// Component props with styling support
type StyledComponentProps<Type, Props, Media, CSS> =
React.ComponentPropsWithRef<Type> &
TransformProps<Props, Media> &
{ css?: CSS; as?: never };Usage Examples:
// Extract props type from styled component
const StyledButton = styled('button', {
variants: {
size: { small: {}, large: {} },
color: { primary: {}, secondary: {} }
}
});
type ButtonProps = VariantProps<typeof StyledButton>;
// ButtonProps = { size?: 'small' | 'large'; color?: 'primary' | 'secondary' }
// Use in other components
function CustomButton(props: ButtonProps) {
return <StyledButton {...props} />;
}Install with Tessl CLI
npx tessl i tessl/npm-stitches--react