Accessibility
Respect the OS prefers-reduced-motion setting.
The reducedMotion prop controls how the library responds to the user's OS-level reduced-motion preference (prefers-reduced-motion: reduce). Default is "system", which respects the OS setting.
Three modes
<Heart reducedMotion="system" /> // default — respect OS setting
<Heart reducedMotion="always" /> // force animation off
<Heart reducedMotion="never" /> // force animation on (use carefully)"system" (default)"always""never"How it works
When reduced motion is active (either by OS setting with "system", or by the "always" override):
- All trigger effects (
mount,in-view,parent-hover) become no-ops hoverandclicktriggers don't fire their animation- The icon renders in its rest state — fully drawn, identical to a static
lucide-reacticon
The component is functionally identical to a static SVG icon in this mode. Layout, sizing, colors, and click handlers all still work.
Testing it
macOS — System Settings → Accessibility → Display → "Reduce motion"
Windows — Settings → Accessibility → Visual effects → Animation effects → Off
iOS — Settings → Accessibility → Motion → Reduce Motion
Chrome DevTools — Open DevTools → Rendering panel (⌘⇧P → "Show Rendering") → Emulate CSS media feature → prefers-reduced-motion: reduce
After toggling, refresh the page. The "system" and "always" demos above should now be static; the "never" demo still animates on hover.
App-wide
Set it once via the <MotionIconConfig> provider:
<MotionIconConfig reducedMotion="system">
<App />
</MotionIconConfig>Or override globally to keep animations on for an internal tool where you've validated motion is fine:
<MotionIconConfig reducedMotion="never">
<App />
</MotionIconConfig>Use 'never' sparingly
Overriding the OS preference disrespects an explicit accessibility choice your user made. Default to "system" unless you have a specific reason.