SmartCommon utilise Framer Motion pour animer les transitions entre pages. Les animations sont configurables par route.
Dans la configuration du Provider :
const config = {
pages: {
"*": "fade" // Animation par défaut pour toutes les pages
}
};
| Animation | Description | Effet |
|---|---|---|
fade | Fondu enchaîné | Opacité 0 → 1 |
slideLeft | Glissement gauche | Entrée par la droite |
slideRight | Glissement droite | Entrée par la gauche |
zoom | Effet de zoom | Scale 0.9 → 1 |
Vous pouvez définir des animations différentes selon la route d'origine et de destination :
const config = {
pages: {
// Depuis la page d'accueil
"/": {
"/dashboard": "slideLeft", // Vers dashboard: glisse à gauche
"/settings": "slideLeft", // Vers settings: glisse à gauche
"*": "fade" // Vers autres: fondu
},
// Depuis le dashboard
"/dashboard": {
"/": "slideRight", // Retour accueil: glisse à droite
"/details": "slideLeft", // Vers détails: glisse à gauche
"*": "fade"
},
// Depuis les paramètres
"/settings": {
"/": "slideRight",
"*": "fade"
},
// Pour toutes les autres pages
"*": "fade"
}
};
L'animation est choisie selon ce schéma :
de la page actuelle
4. Si pas de config pour la page actuelle, utilise global
Navigation de /dashboard vers / :
pages: {
"/": {
"/dashboard": "slideRight", // <- Cette animation sera utilisée
"*": "fade"
},
"/dashboard": {
"/": "slideRight",
"*": "fade"
}
}
La page / s'affiche avec slideRight car on vient de /dashboard.
Par défaut, les animations de glissement sont remplacées par fade sur desktop pour une meilleure UX :
// Dans le composant Page (comportement interne)
if (device?.type === "desktop") {
return "fade";
}
Le composant Page gère automatiquement les animations :
import { Page, Block } from '@cap-rel/smartcommon';
import { useLocation } from 'react-router-dom';
const Dashboard = () => {
const location = useLocation();
return (
<Page location={location}>
<Block>
Contenu du dashboard
</Block>
</Page>
);
};
<note important>Le prop location est requis pour que les animations fonctionnent correctement.</note>
Vous pouvez créer des animations personnalisées en modifiant les variants Framer Motion :
// Animations par défaut dans 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" }
}
};
Pour des animations personnalisées dans vos composants :
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) {
// Déclencher l'animation après le premier rendu
setAnimations(prev => ({
...prev,
fadeIn: { ...prev.fadeIn, state: 'visible' }
}));
}
}, [start]);
return (
<motion.div
initial={{ opacity: 0 }}
animate={animations.fadeIn.value ? { opacity: 1 } : {}}
>
Contenu animé
</motion.div>
);
};
Pour des animations plus complexes, utilisez directement Framer Motion :
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>
);
Navigation hiérarchique (liste → détail → sous-détail) :
pages: {
"/": {
"*": "slideLeft"
},
"/items": {
"/": "slideRight",
"/items/*": "slideLeft",
"*": "fade"
},
"/items/*": {
"/items": "slideRight",
"*": "fade"
},
"*": "fade"
}
Navigation entre onglets sans animation de glissement :
pages: {
"/home": { "*": "fade" },
"/search": { "*": "fade" },
"/profile": { "*": "fade" },
"/settings": {
"*": "slideLeft" // Seul settings a une animation différente
},
"*": "fade"
}
pages: {
"*": "fade" // Utiliser uniquement fade (le plus discret)
}
// Ou modifier la durée à 0
// (nécessite de modifier les animations dans le code)