feat: add unique keys to motion components for improved rendering
This commit is contained in:
@@ -39,6 +39,7 @@ const About = () => {
|
|||||||
<section id="about" className="about">
|
<section id="about" className="about">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<motion.div
|
<motion.div
|
||||||
|
key="about-header"
|
||||||
className="section-header"
|
className="section-header"
|
||||||
initial={{ opacity: 0, y: 50 }}
|
initial={{ opacity: 0, y: 50 }}
|
||||||
whileInView={{ opacity: 1, y: 0 }}
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
@@ -53,6 +54,7 @@ const About = () => {
|
|||||||
|
|
||||||
<div className="about-content">
|
<div className="about-content">
|
||||||
<motion.div
|
<motion.div
|
||||||
|
key="about-text"
|
||||||
className="about-text"
|
className="about-text"
|
||||||
variants={containerVariants}
|
variants={containerVariants}
|
||||||
initial="hidden"
|
initial="hidden"
|
||||||
@@ -82,6 +84,7 @@ const About = () => {
|
|||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
<motion.div
|
<motion.div
|
||||||
|
key="about-stats"
|
||||||
className="about-stats"
|
className="about-stats"
|
||||||
variants={containerVariants}
|
variants={containerVariants}
|
||||||
initial="hidden"
|
initial="hidden"
|
||||||
@@ -90,7 +93,7 @@ const About = () => {
|
|||||||
>
|
>
|
||||||
{stats.map((stat, index) => (
|
{stats.map((stat, index) => (
|
||||||
<motion.div
|
<motion.div
|
||||||
key={index}
|
key={`stat-${index}`}
|
||||||
className="stat-card"
|
className="stat-card"
|
||||||
variants={itemVariants}
|
variants={itemVariants}
|
||||||
whileHover={{
|
whileHover={{
|
||||||
@@ -110,6 +113,7 @@ const About = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<motion.div
|
<motion.div
|
||||||
|
key="about-highlight"
|
||||||
className="about-highlight"
|
className="about-highlight"
|
||||||
initial={{ opacity: 0, scale: 0.9 }}
|
initial={{ opacity: 0, scale: 0.9 }}
|
||||||
whileInView={{ opacity: 1, scale: 1 }}
|
whileInView={{ opacity: 1, scale: 1 }}
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ const Contact = () => {
|
|||||||
<section id="contact" className="contact">
|
<section id="contact" className="contact">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<motion.div
|
<motion.div
|
||||||
|
key="contact-header"
|
||||||
className="section-header"
|
className="section-header"
|
||||||
initial={{ opacity: 0, y: 50 }}
|
initial={{ opacity: 0, y: 50 }}
|
||||||
whileInView={{ opacity: 1, y: 0 }}
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
@@ -140,6 +141,7 @@ const Contact = () => {
|
|||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
<motion.div
|
<motion.div
|
||||||
|
key="contact-content"
|
||||||
className="contact-content"
|
className="contact-content"
|
||||||
variants={containerVariants}
|
variants={containerVariants}
|
||||||
initial="hidden"
|
initial="hidden"
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ const Education = () => {
|
|||||||
<section id="education" className="education">
|
<section id="education" className="education">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<motion.div
|
<motion.div
|
||||||
|
key="education-header"
|
||||||
className="section-header"
|
className="section-header"
|
||||||
initial={{ opacity: 0, y: 50 }}
|
initial={{ opacity: 0, y: 50 }}
|
||||||
whileInView={{ opacity: 1, y: 0 }}
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
@@ -86,6 +87,7 @@ const Education = () => {
|
|||||||
<div className="education-content">
|
<div className="education-content">
|
||||||
{/* Formation principale */}
|
{/* Formation principale */}
|
||||||
<motion.div
|
<motion.div
|
||||||
|
key="education-main"
|
||||||
className="education-main"
|
className="education-main"
|
||||||
variants={containerVariants}
|
variants={containerVariants}
|
||||||
initial="hidden"
|
initial="hidden"
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ const Header = ({ darkMode, toggleDarkMode }: HeaderProps) => {
|
|||||||
const { language, setLanguage, t } = useLanguage();
|
const { language, setLanguage, t } = useLanguage();
|
||||||
|
|
||||||
const menuItems = [
|
const menuItems = [
|
||||||
{ name: t('nav.home'), href: '#hero' },
|
{ id: 'home', name: t('nav.home'), href: '#hero' },
|
||||||
{ name: t('nav.about'), href: '#about' },
|
{ id: 'about', name: t('nav.about'), href: '#about' },
|
||||||
{ name: t('nav.skills'), href: '#skills' },
|
{ id: 'skills', name: t('nav.skills'), href: '#skills' },
|
||||||
{ name: t('nav.projects'), href: '#projects' },
|
{ id: 'projects', name: t('nav.projects'), href: '#projects' },
|
||||||
{ name: t('nav.education'), href: '#education' },
|
{ id: 'education', name: t('nav.education'), href: '#education' },
|
||||||
{ name: t('nav.contact'), href: '#contact' }
|
{ id: 'contact', name: t('nav.contact'), href: '#contact' }
|
||||||
];
|
];
|
||||||
|
|
||||||
const scrollToSection = (href: string) => {
|
const scrollToSection = (href: string) => {
|
||||||
@@ -55,7 +55,7 @@ const Header = ({ darkMode, toggleDarkMode }: HeaderProps) => {
|
|||||||
<ul className="nav-menu desktop-menu">
|
<ul className="nav-menu desktop-menu">
|
||||||
{menuItems.map((item, index) => (
|
{menuItems.map((item, index) => (
|
||||||
<motion.li
|
<motion.li
|
||||||
key={item.name}
|
key={item.id}
|
||||||
initial={{ opacity: 0, y: -20 }}
|
initial={{ opacity: 0, y: -20 }}
|
||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
transition={{ duration: 0.5, delay: index * 0.1 }}
|
transition={{ duration: 0.5, delay: index * 0.1 }}
|
||||||
@@ -118,7 +118,7 @@ const Header = ({ darkMode, toggleDarkMode }: HeaderProps) => {
|
|||||||
transition={{ duration: 0.3 }}
|
transition={{ duration: 0.3 }}
|
||||||
>
|
>
|
||||||
{menuItems.map((item) => (
|
{menuItems.map((item) => (
|
||||||
<li key={item.name}>
|
<li key={item.id}>
|
||||||
<a
|
<a
|
||||||
href={item.href}
|
href={item.href}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ const Hero = () => {
|
|||||||
<section id="hero" className="hero">
|
<section id="hero" className="hero">
|
||||||
<div className="hero-content">
|
<div className="hero-content">
|
||||||
<motion.div
|
<motion.div
|
||||||
|
key="hero-text"
|
||||||
className="hero-text"
|
className="hero-text"
|
||||||
initial={{ opacity: 0, y: 50 }}
|
initial={{ opacity: 0, y: 50 }}
|
||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
@@ -111,6 +112,7 @@ const Hero = () => {
|
|||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
<motion.div
|
<motion.div
|
||||||
|
key="hero-image"
|
||||||
className="hero-image"
|
className="hero-image"
|
||||||
initial={{ opacity: 0, scale: 0.8 }}
|
initial={{ opacity: 0, scale: 0.8 }}
|
||||||
animate={{ opacity: 1, scale: 1 }}
|
animate={{ opacity: 1, scale: 1 }}
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ const Projects = () => {
|
|||||||
<section id="projects" className="projects">
|
<section id="projects" className="projects">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<motion.div
|
<motion.div
|
||||||
|
key="projects-header"
|
||||||
className="section-header"
|
className="section-header"
|
||||||
initial={{ opacity: 0, y: 50 }}
|
initial={{ opacity: 0, y: 50 }}
|
||||||
whileInView={{ opacity: 1, y: 0 }}
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
@@ -86,6 +87,7 @@ const Projects = () => {
|
|||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
<motion.div
|
<motion.div
|
||||||
|
key="projects-grid"
|
||||||
className="projects-grid"
|
className="projects-grid"
|
||||||
variants={containerVariants}
|
variants={containerVariants}
|
||||||
initial="hidden"
|
initial="hidden"
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ const Skills = () => {
|
|||||||
const { t } = useLanguage();
|
const { t } = useLanguage();
|
||||||
const skillCategories = [
|
const skillCategories = [
|
||||||
{
|
{
|
||||||
|
id: 'mobile',
|
||||||
icon: <Smartphone size={32} />,
|
icon: <Smartphone size={32} />,
|
||||||
title: t('skills.category.mobile'),
|
title: t('skills.category.mobile'),
|
||||||
color: "#4FC3F7",
|
color: "#4FC3F7",
|
||||||
@@ -15,6 +16,7 @@ const Skills = () => {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: 'frontend',
|
||||||
icon: <Globe size={32} />,
|
icon: <Globe size={32} />,
|
||||||
title: t('skills.category.frontend'),
|
title: t('skills.category.frontend'),
|
||||||
color: "#42A5F5",
|
color: "#42A5F5",
|
||||||
@@ -25,6 +27,7 @@ const Skills = () => {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: 'backend',
|
||||||
icon: <Server size={32} />,
|
icon: <Server size={32} />,
|
||||||
title: t('skills.category.backend'),
|
title: t('skills.category.backend'),
|
||||||
color: "#66BB6A",
|
color: "#66BB6A",
|
||||||
@@ -34,7 +37,8 @@ const Skills = () => {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: <Database size={32} />,
|
id: 'tools',
|
||||||
|
icon: <Wrench size={32} />,
|
||||||
title: t('skills.category.tools'),
|
title: t('skills.category.tools'),
|
||||||
color: "#AB47BC",
|
color: "#AB47BC",
|
||||||
skills: [
|
skills: [
|
||||||
@@ -72,6 +76,7 @@ const Skills = () => {
|
|||||||
<section id="skills" className="skills">
|
<section id="skills" className="skills">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<motion.div
|
<motion.div
|
||||||
|
key="skills-header"
|
||||||
className="section-header"
|
className="section-header"
|
||||||
initial={{ opacity: 0, y: 50 }}
|
initial={{ opacity: 0, y: 50 }}
|
||||||
whileInView={{ opacity: 1, y: 0 }}
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
@@ -85,6 +90,7 @@ const Skills = () => {
|
|||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
<motion.div
|
<motion.div
|
||||||
|
key="skills-grid"
|
||||||
className="skills-grid"
|
className="skills-grid"
|
||||||
variants={containerVariants}
|
variants={containerVariants}
|
||||||
initial="hidden"
|
initial="hidden"
|
||||||
@@ -93,7 +99,7 @@ const Skills = () => {
|
|||||||
>
|
>
|
||||||
{skillCategories.map((category, categoryIndex) => (
|
{skillCategories.map((category, categoryIndex) => (
|
||||||
<motion.div
|
<motion.div
|
||||||
key={category.title}
|
key={category.id}
|
||||||
className="skill-category"
|
className="skill-category"
|
||||||
variants={categoryVariants}
|
variants={categoryVariants}
|
||||||
whileHover={{
|
whileHover={{
|
||||||
|
|||||||
Reference in New Issue
Block a user