Beta Status

This library is still in early beta and the API is subject to change and may get daily breaking changes. The documentaton may not be up to date with the latest features and include missing or outdated information. You can always create an issue on GitHub or even better a pull request to fix the documentation or add new features.

MotionConfig

MotionConfig sets global defaults for transitions and reduced motion behavior. Wrap your app or a subtree to apply configuration.

Default Transitions

Set a default transition for all motion components:

import { MotionConfig } from "motion-solid";

function App() {
  return (
    <MotionConfig transition={{ type: "spring", stiffness: 300, damping: 30 }}>
      <Layout>
        {/* All animations use this spring by default */}
        <motion.div animate={{ x: 100 }} />
        <motion.button whileHover={{ scale: 1.05 }} />
      </Layout>
    </MotionConfig>
  );
}

Individual components can still override:

<MotionConfig transition={{ type: "spring" }}>
  {/* Uses spring */}
  <motion.div animate={{ x: 100 }} />

  {/* Overrides with tween */}
  <motion.div
    animate={{ x: 100 }}
    transition={{ type: "tween", duration: 0.3 }}
  />
</MotionConfig>

Reduced Motion

Respect user preferences for reduced motion:

<MotionConfig reducedMotion="user">
  <App />
</MotionConfig>

Options:

  • "user" - Respect prefers-reduced-motion media query
  • "always" - Force reduced motion
  • "never" - Never reduce motion (default)

What Gets Reduced

When reduced motion is active:

  • Transform animations (x, y, scale, rotate, etc.) use duration: 0
  • Opacity animations still run
  • Layout animations are not automatically reduced
// With reduced motion, this animates opacity instantly
<motion.div
  initial={{ opacity: 0, x: -100 }}
  animate={{ opacity: 1, x: 0 }}
/>

// But this still animates opacity
<motion.div
  initial={{ opacity: 0 }}
  animate={{ opacity: 1 }}
/>

Nested Config

MotionConfig can be nested. Inner configs override outer:

<MotionConfig transition={{ type: "spring" }}>
  {/* Uses spring */}
  <motion.div animate={{ x: 100 }} />

  <MotionConfig transition={{ type: "tween", duration: 0.3 }}>
    {/* Uses tween */}
    <motion.div animate={{ x: 100 }} />
  </MotionConfig>
</MotionConfig>

Hooks

useMotionConfig

Access the current config context:

import { useMotionConfig } from "motion-solid";

function CustomMotion() {
  const config = useMotionConfig();

  // config.transition - current default transition
  // config.reducedMotion - current reduced motion setting
}

useReducedMotion

Direct access to the user's system preference:

import { useReducedMotion } from "motion-solid";

function AdaptiveAnimation() {
  const prefersReducedMotion = useReducedMotion();

  return (
    <motion.div
      animate={{ x: prefersReducedMotion() ? 0 : 100 }}
      transition={{ duration: prefersReducedMotion() ? 0 : 0.5 }}
    />
  );
}

useReducedMotion returns the actual prefers-reduced-motion value, regardless of MotionConfig settings.

Example: Accessible Animations

function App() {
  return (
    <MotionConfig reducedMotion="user">
      <main>
        {/* Animations respect user preference */}
        <Hero />
        <Features />
      </main>
    </MotionConfig>
  );
}

function FeatureCard(props) {
  const reduced = useReducedMotion();

  return (
    <motion.article
      initial={{ opacity: 0, y: reduced() ? 0 : 30 }}
      whileInView={{ opacity: 1, y: 0 }}
      viewport={{ once: true }}
    >
      {props.children}
    </motion.article>
  );
}