A set of tools to manage inline styles on React elements with support for pseudo-classes, media queries, and keyframe animations.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
System for creating and managing CSS keyframe animations in Radium with automatic vendor prefixing and global style injection.
Creates keyframe animation objects that can be used with the animationName CSS property.
/**
* Create a keyframes animation for use in inline styles
* @param keyframeRules - Object defining animation keyframes with percentages as keys
* @param name - Optional name prefix for debugging (added to generated animation name)
* @returns Keyframes object for use with animationName property
*/
function keyframes(
keyframeRules: { [percentage: string]: CSSProperties },
name?: string
): KeyframesObject;
interface KeyframesObject {
/** Internal marker identifying this as a keyframes object */
__radiumKeyframes: boolean;
/** Internal processing function for CSS generation */
__process(userAgent?: string): { animationName: string; css: string };
}
interface CSSProperties {
[property: string]: string | number;
}Usage Examples:
import Radium, { keyframes, StyleRoot } from 'radium';
// Basic keyframe animation
const fadeIn = keyframes({
'0%': { opacity: 0 },
'100%': { opacity: 1 }
});
// Complex animation with multiple properties
const slideAndFade = keyframes({
'0%': {
opacity: 0,
transform: 'translateX(-100px)'
},
'50%': {
opacity: 0.5,
transform: 'translateX(-50px)'
},
'100%': {
opacity: 1,
transform: 'translateX(0)'
}
}, 'slideAndFade'); // Optional name for debugging
// Use in component styles
const AnimatedComponent = () => (
<div style={styles.animated}>
Animated content
</div>
);
const styles = {
animated: {
// Use placeholder name in animation property
animation: 'x 2s ease-in-out',
// Assign keyframes object to animationName
animationName: fadeIn,
backgroundColor: 'blue',
height: '100px',
width: '100px'
}
};Keyframe animations require components to be wrapped in StyleRoot for proper CSS injection.
/**
* Required wrapper for keyframe animations
* Provides context for global style management
*/
const StyleRoot: React.ComponentType<{
children: React.ReactNode;
radiumConfig?: RadiumConfig;
}>;Usage Examples:
import { StyleRoot } from 'radium';
function App() {
return (
<StyleRoot>
<AnimatedComponent />
<AnotherAnimatedComponent />
</StyleRoot>
);
}Chain multiple keyframe animations by passing an array to animationName.
interface MultipleAnimations {
animationName: KeyframesObject[];
animationDuration: string;
animationTimingFunction?: string;
animationIterationCount?: string;
animationDelay?: string;
}Usage Examples:
const pulseAnimation = keyframes({
'0%': { width: '10%' },
'50%': { width: '50%' },
'100%': { width: '10%' }
}, 'pulse');
const colorAnimation = keyframes({
'0%': { backgroundColor: 'red' },
'25%': { backgroundColor: 'yellow' },
'50%': { backgroundColor: 'green' },
'75%': { backgroundColor: 'blue' },
'100%': { backgroundColor: 'red' }
}, 'colorCycle');
const multiAnimationStyles = {
element: {
// Multiple animations
animationName: [pulseAnimation, colorAnimation],
animationDuration: '2s, 4s',
animationTimingFunction: 'ease-in-out, linear',
animationIterationCount: 'infinite, infinite',
height: '50px',
margin: '0 auto'
}
};Keyframe rules support various percentage formats and special keywords.
interface KeyframePercentages {
/** Numeric percentages */
'0%': CSSProperties;
'25%': CSSProperties;
'50%': CSSProperties;
'100%': CSSProperties;
/** Special keywords */
'from': CSSProperties; // Same as 0%
'to': CSSProperties; // Same as 100%
}Usage Examples:
// Using percentages
const growAnimation = keyframes({
'0%': { transform: 'scale(1)' },
'25%': { transform: 'scale(1.1)' },
'50%': { transform: 'scale(1.2)' },
'75%': { transform: 'scale(1.1)' },
'100%': { transform: 'scale(1)' }
});
// Using from/to keywords
const simpleSlide = keyframes({
'from': { transform: 'translateX(0)' },
'to': { transform: 'translateX(100px)' }
});
// Mixed percentages
const complexBounce = keyframes({
'from': { transform: 'translateY(0)' },
'20%': { transform: 'translateY(-20px)' },
'40%': { transform: 'translateY(0)' },
'60%': { transform: 'translateY(-10px)' },
'80%': { transform: 'translateY(0)' },
'to': { transform: 'translateY(0)' }
});Keyframes are automatically vendor-prefixed based on the browser environment or provided user agent.
Usage Examples:
// Animation with properties that need prefixing
const prefixedAnimation = keyframes({
'0%': {
transform: 'rotate(0deg)',
filter: 'blur(0px)'
},
'100%': {
transform: 'rotate(360deg)',
filter: 'blur(5px)'
}
});
// Generates vendor-prefixed CSS automatically:
// @-webkit-keyframes radium-animation-xyz { ... }
// @-moz-keyframes radium-animation-xyz { ... }
// @keyframes radium-animation-xyz { ... }For server-side rendering, provide user agent through configuration.
Usage Examples:
// Server-side keyframes with user agent
const serverConfig = {
userAgent: req.headers['user-agent']
};
const ServerApp = () => (
<StyleRoot radiumConfig={serverConfig}>
<AnimatedComponent />
</StyleRoot>
);Use standard CSS animation properties alongside animationName.
interface AnimationProperties {
animationName: KeyframesObject | KeyframesObject[];
animationDuration?: string;
animationTimingFunction?: string;
animationDelay?: string;
animationIterationCount?: string | number;
animationDirection?: 'normal' | 'reverse' | 'alternate' | 'alternate-reverse';
animationFillMode?: 'none' | 'forwards' | 'backwards' | 'both';
animationPlayState?: 'running' | 'paused';
}Usage Examples:
const rotateAnimation = keyframes({
'0%': { transform: 'rotate(0deg)' },
'100%': { transform: 'rotate(360deg)' }
});
const animationStyles = {
spinner: {
animationName: rotateAnimation,
animationDuration: '2s',
animationTimingFunction: 'linear',
animationIterationCount: 'infinite',
animationDirection: 'normal',
animationFillMode: 'none',
width: '50px',
height: '50px',
border: '3px solid #333'
}
};Radium automatically generates unique animation names and injects CSS into the document.
Example Generated CSS:
@keyframes radium-animation-abc123 {
0% { opacity: 0; transform: translateX(-100px); }
50% { opacity: 0.5; transform: translateX(-50px); }
100% { opacity: 1; transform: translateX(0); }
}interface KeyframesObject {
__radiumKeyframes: boolean;
__process(userAgent?: string): { animationName: string; css: string };
}
type KeyframeRules = {
[percentage: string]: CSSProperties;
};
interface AnimationConfig {
animationName: KeyframesObject | KeyframesObject[];
animationDuration?: string;
animationTimingFunction?: string;
animationDelay?: string;
animationIterationCount?: string | number;
animationDirection?: 'normal' | 'reverse' | 'alternate' | 'alternate-reverse';
animationFillMode?: 'none' | 'forwards' | 'backwards' | 'both';
animationPlayState?: 'running' | 'paused';
}Install with Tessl CLI
npx tessl i tessl/npm-radium