CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-framer-motion

A production-ready motion library for React that provides comprehensive animation and gesture APIs for creating fluid, performant interactions.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

configuration.mddocs/

Configuration

Global configuration and feature bundle system for code splitting and performance optimization.

Capabilities

MotionConfig Component

Provides global configuration for all motion components within its context.

/**
 * Global configuration provider for motion components
 * @param props - Configuration options
 * @returns JSX element providing motion configuration context
 */
function MotionConfig(props: MotionConfigProps): JSX.Element;

interface MotionConfigProps {
  /**
   * Child components to apply configuration to
   */
  children: React.ReactNode;
  
  /**
   * Default transition for all animations
   */
  transition?: Transition;
  
  /**
   * Transform page coordinates (useful for zoom/pan interfaces)
   */
  transformPagePoint?: (point: Point) => Point;
  
  /**
   * Reduced motion preference override
   * - "always": Always reduce motion
   * - "never": Never reduce motion  
   * - "user": Respect user's system preference (default)
   */
  reducedMotion?: "always" | "never" | "user";
  
  /**
   * Custom prop validation function
   */
  isValidProp?: (key: string) => boolean;
  
  /**
   * Enable/disable features globally
   */
  features?: {
    /**
     * Enable layout animations (default: true)
     */
    layout?: boolean;
    
    /**
     * Enable gesture handling (default: true)
     */
    gestures?: boolean;
    
    /**
     * Enable exit animations (default: true)
     */
    animations?: boolean;
  };
}

interface Transition {
  /**
   * Animation duration in seconds
   */
  duration?: number;
  
  /**
   * Delay before animation starts in seconds
   */
  delay?: number;
  
  /**
   * Easing function or array for keyframes
   */
  ease?: Easing | Easing[];
  
  /**
   * Animation type
   */
  type?: "tween" | "spring" | "keyframes" | "inertia";
  
  /**
   * Number of times to repeat
   */
  repeat?: number;
  
  /**
   * Type of repeat behavior
   */
  repeatType?: "loop" | "reverse" | "mirror";
  
  /**
   * Delay between repeats
   */
  repeatDelay?: number;
  
  // Spring-specific options
  bounce?: number;
  damping?: number;
  mass?: number;
  stiffness?: number;
  velocity?: number;
  restSpeed?: number;
  restDelta?: number;
}

interface Point {
  x: number;
  y: number;
}

Usage Examples:

import { MotionConfig, motion } from "framer-motion";

// Global transition configuration
function GlobalTransitionExample() {
  return (
    <MotionConfig
      transition={{
        type: "spring",
        stiffness: 260,
        damping: 20
      }}
    >
      <div className="space-y-4">
        <motion.div
          whileHover={{ scale: 1.1 }}
          className="w-32 h-32 bg-blue-500 rounded"
        >
          Uses global spring config
        </motion.div>
        
        <motion.div
          whileHover={{ scale: 1.1 }}
          transition={{ type: "tween", duration: 0.2 }} // Override global
          className="w-32 h-32 bg-red-500 rounded"
        >
          Overrides with tween
        </motion.div>
      </div>
    </MotionConfig>
  );
}

// Reduced motion configuration
function ReducedMotionExample() {
  return (
    <MotionConfig reducedMotion="user">
      <motion.div
        initial={{ opacity: 0, y: 50 }}
        animate={{ opacity: 1, y: 0 }}
        className="p-4 bg-green-500 text-white rounded"
      >
        Respects user's motion preferences
      </motion.div>
    </MotionConfig>
  );
}

// Custom coordinate transformation
function TransformPointExample() {
  const transformPagePoint = (point: Point) => ({
    x: point.x * 0.5, // Scale down x coordinates
    y: point.y * 0.5  // Scale down y coordinates
  });
  
  return (
    <MotionConfig transformPagePoint={transformPagePoint}>
      <motion.div
        drag
        className="w-32 h-32 bg-purple-500 rounded cursor-grab"
      >
        Drag coordinates are scaled
      </motion.div>
    </MotionConfig>
  );
}

LazyMotion Component

Enables code splitting by loading animation features on demand.

/**
 * Lazy loading wrapper for motion features
 * @param props - LazyMotion configuration
 * @returns JSX element providing lazy-loaded features
 */
function LazyMotion(props: LazyMotionProps): JSX.Element;

interface LazyMotionProps {
  /**
   * Child components that will use lazy-loaded features
   */
  children: React.ReactNode;
  
  /**
   * Feature bundle to load (sync or async)
   */
  features: FeatureBundle | (() => Promise<FeatureBundle>);
  
  /**
   * Strict mode - only allow features defined in bundle (default: true)
   */
  strict?: boolean;
}

interface FeatureBundle {
  /**
   * Animation feature definitions
   */
  animation?: FeatureDefinition;
  
  /**
   * Exit animation features
   */
  exit?: FeatureDefinition;
  
  /**
   * Gesture handling features  
   */
  gestures?: FeatureDefinition;
  
  /**
   * Drag interaction features
   */
  drag?: FeatureDefinition;
  
  /**
   * Layout animation features
   */
  layout?: FeatureDefinition;
  
  /**
   * Measurement and projection features
   */
  measureLayout?: FeatureDefinition;
}

interface FeatureDefinition {
  /**
   * Feature implementation functions
   */
  [key: string]: any;
}

Pre-built Feature Bundles:

/**
 * Minimal DOM features bundle (animations only)
 */
const domMin: FeatureBundle;

/**
 * DOM animation features bundle (animations + gestures)
 */
const domAnimation: FeatureBundle;

/**
 * Maximum DOM features bundle (all features)
 */
const domMax: FeatureBundle;

Usage Examples:

import { LazyMotion, domAnimation, domMax, m } from "framer-motion";

// Synchronous feature loading
function SyncLazyMotionExample() {
  return (
    <LazyMotion features={domAnimation}>
      <m.div
        whileHover={{ scale: 1.1 }}
        whileTap={{ scale: 0.95 }}
        className="w-32 h-32 bg-blue-500 rounded cursor-pointer"
      >
        Lazy loaded gestures
      </m.div>
    </LazyMotion>
  );
}

// Asynchronous feature loading
function AsyncLazyMotionExample() {
  return (
    <LazyMotion
      features={() => import("framer-motion").then(mod => mod.domMax)}
      strict={false}
    >
      <m.div
        drag
        whileHover={{ scale: 1.1 }}
        className="w-32 h-32 bg-green-500 rounded cursor-grab"
      >
        Async loaded features
      </m.div>
    </LazyMotion>
  );
}

// Custom feature bundle
function CustomFeatureExample() {
  const customFeatures = async () => {
    // Load only specific features
    const { domAnimation } = await import("framer-motion");
    return domAnimation;
  };
  
  return (
    <LazyMotion features={customFeatures}>
      <m.div
        animate={{ rotate: 360 }}
        transition={{ duration: 2, repeat: Infinity, ease: "linear" }}
        className="w-16 h-16 bg-purple-500 rounded"
      >
        Custom bundle
      </m.div>
    </LazyMotion>
  );
}

Global Configuration

Global configuration utilities that affect all Framer Motion instances.

/**
 * Global motion configuration object from motion-utils
 */
interface MotionGlobalConfig {
  /**
   * Skip animations entirely (useful for testing)
   */
  skipAnimations?: boolean;
  
  /**
   * Use reduced motion globally
   */
  useManualTiming?: boolean;
  
  /**
   * Custom easing functions
   */
  easing?: {
    [key: string]: (t: number) => number;
  };
}

/**
 * Access to global motion configuration
 */
const MotionGlobalConfig: MotionGlobalConfig;

Usage Example:

import { MotionGlobalConfig } from "framer-motion";

// Configure globally (typically in app setup)
MotionGlobalConfig.skipAnimations = process.env.NODE_ENV === "test";

// Custom easing functions
MotionGlobalConfig.easing = {
  ...MotionGlobalConfig.easing,
  customEase: (t: number) => t * t * (3 - 2 * t) // Smoothstep
};

function GlobalConfigExample() {
  return (
    <motion.div
      animate={{ x: 100 }}
      transition={{ ease: "customEase", duration: 1 }}
    >
      Uses custom global easing
    </motion.div>
  );
}

Reduced Motion Hooks

Hooks for detecting and responding to reduced motion preferences.

/**
 * Detect user's reduced motion preference
 * @returns Boolean indicating if reduced motion is preferred
 */
function useReducedMotion(): boolean;

/**
 * Configure reduced motion behavior for components
 * @returns Configuration object for reduced motion
 */
function useReducedMotionConfig(): {
  /**
   * Whether reduced motion is currently active
   */
  shouldReduceMotion: boolean;
  
  /**
   * Override reduced motion setting
   */
  setReducedMotion: (reduce: boolean | "user") => void;
};

Usage Examples:

import { motion, useReducedMotion, useReducedMotionConfig } from "framer-motion";

// Basic reduced motion detection
function ReducedMotionExample() {
  const shouldReduceMotion = useReducedMotion();
  
  return (
    <motion.div
      animate={{ 
        x: shouldReduceMotion ? 0 : 100,
        transition: { 
          duration: shouldReduceMotion ? 0 : 1
        }
      }}
      className="w-32 h-32 bg-blue-500 rounded"
    >
      Motion respects user preference
    </motion.div>
  );
}

// Advanced reduced motion configuration
function AdvancedReducedMotionExample() {
  const { shouldReduceMotion, setReducedMotion } = useReducedMotionConfig();
  
  return (
    <div>
      <div className="mb-4 space-x-2">
        <button 
          onClick={() => setReducedMotion(false)}
          className="px-4 py-2 bg-blue-500 text-white rounded"
        >
          Enable Motion
        </button>
        <button 
          onClick={() => setReducedMotion(true)}
          className="px-4 py-2 bg-red-500 text-white rounded"
        >
          Disable Motion
        </button>
        <button 
          onClick={() => setReducedMotion("user")}
          className="px-4 py-2 bg-gray-500 text-white rounded"
        >
          Respect User Preference
        </button>
      </div>
      
      <motion.div
        animate={{ 
          rotate: shouldReduceMotion ? 0 : 360,
          scale: shouldReduceMotion ? 1 : [1, 1.2, 1]
        }}
        transition={{
          duration: shouldReduceMotion ? 0 : 2,
          repeat: shouldReduceMotion ? 0 : Infinity
        }}
        className="w-32 h-32 bg-green-500 rounded"
      >
        Configurable motion
      </motion.div>
      
      <p className="mt-2 text-sm">
        Reduced motion: {shouldReduceMotion ? "Active" : "Inactive"}
      </p>
    </div>
  );
}

Feature Detection

Utilities for detecting available features and capabilities.

/**
 * Check if running in browser environment
 * @returns Boolean indicating browser environment
 */
function isBrowser(): boolean;

/**
 * Detect available animation features
 * @returns Object describing available features
 */
interface FeatureDetection {
  /**
   * Web Animations API support
   */
  waapi: boolean;
  
  /**
   * CSS transforms support
   */
  transforms: boolean;
  
  /**
   * Touch/pointer events support
   */
  touch: boolean;
  
  /**
   * Reduced motion preference
   */
  reducedMotion: boolean;
}

/**
 * Browser environment detection
 */
const isBrowser: boolean;

Usage Example:

import { isBrowser } from "framer-motion";
import { useEffect, useState } from "react";

function FeatureDetectionExample() {
  const [features, setFeatures] = useState<any>(null);
  
  useEffect(() => {
    if (isBrowser()) {
      // Detect browser capabilities
      const detection = {
        waapi: "animate" in document.createElement("div"),
        transforms: "transform" in document.createElement("div").style,
        touch: "ontouchstart" in window,
        reducedMotion: window.matchMedia("(prefers-reduced-motion: reduce)").matches
      };
      setFeatures(detection);
    }
  }, []);
  
  if (!isBrowser()) {
    return <div>Server-side rendering</div>;
  }
  
  return (
    <div>
      <h3>Browser Capabilities:</h3>
      {features && (
        <ul className="list-disc pl-6">
          <li>Web Animations API: {features.waapi ? "✅" : "❌"}</li>
          <li>CSS Transforms: {features.transforms ? "✅" : "❌"}</li>
          <li>Touch Support: {features.touch ? "✅" : "❌"}</li>
          <li>Reduced Motion: {features.reducedMotion ? "✅" : "❌"}</li>
        </ul>
      )}
    </div>
  );
}

Performance Configuration

Configuration options for optimizing animation performance.

/**
 * Configure performance settings
 */
interface PerformanceConfig {
  /**
   * Enable GPU acceleration hints
   */
  useGPUAcceleration?: boolean;
  
  /**
   * Batch DOM updates
   */
  batchUpdates?: boolean;
  
  /**
   * Throttle animation frame rate
   */
  maxFrameRate?: number;
  
  /**
   * Enable transform optimization
   */
  optimizeTransforms?: boolean;
}

Usage Example:

// Configure performance at app level
function App() {
  return (
    <MotionConfig
      transition={{
        type: "spring",
        stiffness: 260,
        damping: 20
      }}
    >
      <LazyMotion features={domAnimation}>
        <div className="app">
          {/* App content with optimized motion */}
        </div>
      </LazyMotion>
    </MotionConfig>
  );
}

// Environment-specific configuration
const getMotionConfig = () => {
  if (process.env.NODE_ENV === "development") {
    return { reducedMotion: "never" }; // Always animate in dev
  }
  
  if (process.env.NODE_ENV === "test") {
    MotionGlobalConfig.skipAnimations = true; // Skip in tests
  }
  
  return { reducedMotion: "user" }; // Respect user preference in production
};

Configuration Patterns

Responsive Motion:

function ResponsiveMotion() {
  const [isMobile, setIsMobile] = useState(false);
  
  useEffect(() => {
    const checkMobile = () => setIsMobile(window.innerWidth < 768);
    checkMobile();
    window.addEventListener("resize", checkMobile);
    return () => window.removeEventListener("resize", checkMobile);
  }, []);
  
  return (
    <MotionConfig
      transition={{
        type: isMobile ? "tween" : "spring",
        duration: isMobile ? 0.2 : 0.6
      }}
    >
      {/* Motion components adapt to screen size */}
    </MotionConfig>
  );
}

Theme-based Configuration:

function ThemedMotion({ theme, children }: { theme: "light" | "dark", children: React.ReactNode }) {
  const config = {
    light: {
      transition: { type: "spring", stiffness: 300 },
      reducedMotion: "user"
    },
    dark: {
      transition: { type: "tween", duration: 0.3 },
      reducedMotion: "never"
    }
  };
  
  return (
    <MotionConfig {...config[theme]}>
      {children}
    </MotionConfig>
  );
}

Progressive Enhancement:

function ProgressiveMotion({ children }: { children: React.ReactNode }) {
  const [features, setFeatures] = useState(domMin);
  
  useEffect(() => {
    // Progressively load more features
    const loadFullFeatures = async () => {
      const { domMax } = await import("framer-motion");
      setFeatures(domMax);
    };
    
    // Load after initial render
    const timer = setTimeout(loadFullFeatures, 100);
    return () => clearTimeout(timer);
  }, []);
  
  return (
    <LazyMotion features={features}>
      {children}
    </LazyMotion>
  );
}

docs

animation-controls.md

configuration.md

dom-utilities.md

gestures.md

index.md

layout-presence.md

motion-components.md

motion-values.md

scroll-view.md

tile.json