Add a responsive mobile navigation menu to the `Header` component, allowing users to easily access different sections of the portfolio on smaller screens. This includes a toggle button for opening/closing the menu and smooth animations for its appearance. Introduce a `RotatingText` component in the `Hero` section to dynamically display different professional titles, enhancing the visual appeal and conveying diverse skills. Update `package.json` to include `framer-motion` as a dependency, which is utilized for the new animations.
45 lines
1.1 KiB
TypeScript
45 lines
1.1 KiB
TypeScript
"use client";
|
|
|
|
import React, { useState, useEffect } from "react";
|
|
import { motion, AnimatePresence } from "framer-motion";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
interface RotatingTextProps {
|
|
words: string[];
|
|
className?: string;
|
|
interval?: number; // Intervalo em milissegundos para a rotação
|
|
}
|
|
|
|
export function RotatingText({
|
|
words,
|
|
className,
|
|
interval = 3000,
|
|
}: RotatingTextProps) {
|
|
const [currentIndex, setCurrentIndex] = useState(0);
|
|
|
|
useEffect(() => {
|
|
const timer = setInterval(() => {
|
|
setCurrentIndex((prevIndex) => (prevIndex + 1) % words.length);
|
|
}, interval);
|
|
|
|
return () => clearInterval(timer);
|
|
}, [words, interval]);
|
|
|
|
return (
|
|
<div className={cn("relative inline-block min-h-[1.5em]", className)}>
|
|
<AnimatePresence mode="wait">
|
|
<motion.span
|
|
key={currentIndex}
|
|
initial={{ opacity: 0, y: 20 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
exit={{ opacity: 0, y: -20 }}
|
|
transition={{ duration: 0.5 }}
|
|
className="block text-center"
|
|
>
|
|
{words[currentIndex]}
|
|
</motion.span>
|
|
</AnimatePresence>
|
|
</div>
|
|
);
|
|
}
|