Page Animations
SmartCommon uses Framer Motion to animate transitions between pages. Animations are configurable per route.
Basic Configuration
In the Provider configuration:
const config = {
pages: {
"*": "fade" // Default animation for all pages
}
};
Available Animations
| Animation | Description | Effect |
|---|---|---|
fade |
Crossfade | Opacity 0 -> 1 |
slideLeft |
Slide left | Enters from the right |
slideRight |
Slide right | Enters from the left |
zoom |
Zoom effect | Scale 0.9 -> 1 |
Configuration by Route
You can define different animations based on the source and destination routes:
const config = {
pages: {
// From home page
"/": {
"/dashboard": "slideLeft", // To dashboard: slides left
"/settings": "slideLeft", // To settings: slides left
"*": "fade" // To others: fade
},
// From dashboard
"/dashboard": {
"/": "slideRight", // Back to home: slides right
"/details": "slideLeft", // To details: slides left
"*": "fade"
},
// From settings
"/settings": {
"/": "slideRight",
"*": "fade"
},
// For all other pages
"*": "fade"
}
};
Navigation Logic
Animations are chosen according to this scheme:
- Look for a config for the current page
- If found, look for an animation for the previous page
- If not found, use
*for the current page - If no config for the current page, use global
*
Example
Navigation from /dashboard to /:
pages: {
"/": {
"/dashboard": "slideRight", // <- This animation will be used
"*": "fade"
},
"/dashboard": {
"/": "slideRight",
"*": "fade"
}
}
The page / displays with slideRight because we came from /dashboard.
Disable Slide Animations on Desktop
By default, slide animations are replaced by fade on desktop for better UX:
// In the Page component (internal behavior)
if (device?.type === "desktop") {
return "fade";
}
Using the Page Component
The Page component automatically manages animations:
import { Page, Block } from '@cap-rel/smartcommon';
import { useLocation } from 'react-router-dom';
const Dashboard = () => {
const location = useLocation();
return (
<Page location={location}>
<Block>
Dashboard content
</Block>
</Page>
);
};
Important
The location prop is required for animations to work correctly.
Customizing Animations
You can create custom animations by modifying Framer Motion variants:
// Default animations in SmartCommon
const animations = {
slideRight: {
initial: { x: "50%", opacity: 0 },
animate: { x: 0, opacity: 1, transition: { duration: 0.15, ease: "easeInOut" } },
exit: { x: "50%", opacity: 0, transition: { duration: 0.15, ease: "easeInOut" } }
},
slideLeft: {
initial: { x: "-50%", opacity: 0 },
animate: { x: 0, opacity: 1, transition: { duration: 0.15, ease: "easeInOut" } },
exit: { x: "-50%", opacity: 0, transition: { duration: 0.15, ease: "easeInOut" } }
},
fade: {
initial: { opacity: 0 },
animate: { opacity: 1, transition: { duration: 0.15, ease: "easeOut" } },
exit: { opacity: 0, transition: { duration: 0.15, ease: "easeOut" } }
},
zoom: {
initial: { scale: 0.9, opacity: 0 },
animate: { scale: 1, opacity: 1 },
exit: { scale: 0.9, opacity: 0 },
transition: { duration: 0.2, ease: "easeOut" }
}
};
useAnimation Hook
For custom animations in your components:
import { useAnimation } from '@cap-rel/smartcommon';
const MyComponent = () => {
const { start, animations, setAnimations } = useAnimation({
fadeIn: { value: false, state: null },
slideIn: { value: false, state: null }
});
useEffect(() => {
if (start) {
// Trigger animation after first render
setAnimations(prev => ({
...prev,
fadeIn: { ...prev.fadeIn, state: 'visible' }
}));
}
}, [start]);
return (
<motion.div
initial={{ opacity: 0 }}
animate={animations.fadeIn.value ? { opacity: 1 } : {}}
>
Animated content
</motion.div>
);
};
Animations with Framer Motion
For more complex animations, use Framer Motion directly:
import { motion, AnimatePresence } from 'framer-motion';
const MyList = ({ items }) => (
<AnimatePresence>
{items.map(item => (
<motion.div
key={item.id}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
transition={{ duration: 0.2 }}
>
{item.name}
</motion.div>
))}
</AnimatePresence>
);
Configuration Examples
Classic Mobile Application
Hierarchical navigation (list -> detail -> sub-detail):
pages: {
"/": {
"*": "slideLeft"
},
"/items": {
"/": "slideRight",
"/items/*": "slideLeft",
"*": "fade"
},
"/items/*": {
"/items": "slideRight",
"*": "fade"
},
"*": "fade"
}
Tab-based Application
Navigation between tabs without slide animations:
pages: {
"/home": { "*": "fade" },
"/search": { "*": "fade" },
"/profile": { "*": "fade" },
"/settings": {
"*": "slideLeft" // Only settings has a different animation
},
"*": "fade"
}
Disable All Animations
pages: {
"*": "fade" // Use only fade (most subtle)
}
// Or set duration to 0
// (requires modifying animations in code)
See Also
- Configuration - Provider Configuration
- SmartCommon - Page Component
- Framer Motion - Official Documentation