or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

animation-controls.mdconfiguration.mddom-utilities.mdgestures.mdindex.mdlayout-presence.mdmotion-components.mdmotion-values.mdscroll-view.md
tile.json

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