feat: Add multiple UI components to the codebase

This commit includes several User Interface components such as Button, DropdownMenu, FlipWords, HeroParallax, Input, Label, NavigationMenu and ToastBox. Each component was developed individually and has different attributes and behaviors. This will significantly improve the user experience and interactivity of the application.
This commit is contained in:
2024-06-06 14:03:45 +02:00
parent 17df70947a
commit 74ec86c684
8 changed files with 729 additions and 0 deletions

View File

@@ -0,0 +1,84 @@
"use client";
import React, { useCallback, useEffect, useRef, useState } from "react";
import { AnimatePresence, motion, LayoutGroup } from "framer-motion";
import { cn } from "@/lib/utils";
export const FlipWords = ({
words,
duration = 3000,
className,
}: {
words: string[];
duration?: number;
className?: string;
}) => {
const [currentWord, setCurrentWord] = useState(words[0]);
const [isAnimating, setIsAnimating] = useState<boolean>(false);
const startAnimation = useCallback(() => {
const word = words[words.indexOf(currentWord) + 1] || words[0];
setCurrentWord(word);
setIsAnimating(true);
}, [currentWord, words]);
useEffect(() => {
if (!isAnimating)
setTimeout(() => {
startAnimation();
}, duration);
}, [isAnimating, duration, startAnimation]);
return (
<AnimatePresence
onExitComplete={() => {
setIsAnimating(false);
}}
>
<motion.div
initial={{
opacity: 0,
y: 10,
}}
animate={{
opacity: 1,
y: 0,
}}
transition={{
duration: 0.4,
ease: "easeInOut",
type: "spring",
stiffness: 100,
damping: 10,
}}
exit={{
opacity: 0,
y: -40,
x: 40,
filter: "blur(8px)",
scale: 2,
position: "absolute",
}}
className={cn(
"z-10 inline-block relative text-left text-neutral-900 dark:text-neutral-100 px-2",
className
)}
key={currentWord}
>
{currentWord.split("").map((letter, index) => (
<motion.span
key={currentWord + index}
initial={{ opacity: 0, y: 10, filter: "blur(8px)" }}
animate={{ opacity: 1, y: 0, filter: "blur(0px)" }}
transition={{
delay: index * 0.08,
duration: 0.4,
}}
className="inline-block"
>
{letter}
</motion.span>
))}
</motion.div>
</AnimatePresence>
);
};