CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-radium

A set of tools to manage inline styles on React elements with support for pseudo-classes, media queries, and keyframe animations.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

keyframes.mddocs/

Keyframe Animations

System for creating and managing CSS keyframe animations in Radium with automatic vendor prefixing and global style injection.

Capabilities

keyframes Function

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'
  }
};

StyleRoot Requirement

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>
  );
}

Multiple Animations

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 Percentages

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)' }
});

Vendor Prefixing

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 { ... }

Server-Side Rendering

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>
);

Animation Properties

Standard Animation Properties

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'
  }
};

Generated CSS

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); }
}

Types

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

docs

component-enhancement.md

index.md

keyframes.md

plugins.md

state-management.md

style-components.md

tile.json