diff --git a/src/components/typewriter-effect.jsx b/src/components/typewriter-effect.jsx
new file mode 100644
index 0000000..44cf2f3
--- /dev/null
+++ b/src/components/typewriter-effect.jsx
@@ -0,0 +1,81 @@
+import { cn } from "@/lib/utils";
+import { motion, stagger, useAnimate, useInView } from "framer-motion";
+import { useEffect } from "react";
+import { FaStar } from "react-icons/fa";
+
+export const TypewriterEffect = ({
+ words,
+ className,
+ cursorClassName,
+ setCursorVariant,
+}) => {
+ // split text inside of words into array of characters
+ const wordsArray = words.map((word) => {
+ return {
+ ...word,
+ text: word.text.split(""),
+ };
+ });
+
+ const [scope, animate] = useAnimate();
+ const isInView = useInView(scope);
+ useEffect(() => {
+ if (isInView) {
+ animate(
+ "span",
+ {
+ display: "inline-block",
+ opacity: 1,
+ width: "fit-content",
+ },
+ {
+ duration: 0.3,
+ delay: stagger(0.1),
+ ease: "easeInOut",
+ },
+ );
+ }
+ }, [isInView]);
+
+ const renderWords = () => {
+ return (
+
+ {wordsArray.map((word, idx) => {
+ const wordClassName = cn(
+ `text-foreground opacity-0 hidden`,
+ word.className,
+ );
+ const isPrimary =
+ word.className && word.className.includes("primary");
+ const spanProps = {
+ initial: {},
+ className: wordClassName,
+ };
+ if (isPrimary) {
+ spanProps.onMouseEnter = handleMouseEnter;
+ spanProps.onMouseLeave = handleMouseLeave;
+ }
+ return (
+
+ {word.text.map((char, index) => (
+
+ {char}
+
+ ))}
+
+
+ );
+ })}
+
+ );
+ };
+
+ const handleMouseEnter = () => setCursorVariant("bigText");
+ const handleMouseLeave = () => setCursorVariant("default");
+
+ return (
+
+ {renderWords()}
+
+ );
+};
diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx
index f9f6ad3..05bd4d3 100644
--- a/src/pages/Home.jsx
+++ b/src/pages/Home.jsx
@@ -1,8 +1,29 @@
+import { TypewriterEffect } from "@/components/typewriter-effect";
import { projects } from "@/data/projects";
import { FaStar } from "react-icons/fa";
import { Link } from "react-router-dom";
+import { motion } from "framer-motion";
function Home({ setCursorVariant }) {
+ const words = [
+ {
+ text: "Discover",
+ },
+ {
+ text: "Awesome",
+ },
+ {
+ text: "React",
+ },
+ {
+ text: "js",
+ },
+ {
+ text: "Projects",
+ className: "primary text-primary dark:text-primary font-bold",
+ },
+ ];
+
const renderProjectLinks = () => {
return projects.map((item) => (
-
-
-
+ {["1", "2", "3"].map((item) => (
+
+ ))}
Hello world
-
- Discover Awesome React.js{" "}
- setCursorVariant("bigText")}
- onMouseLeave={() => setCursorVariant("default")}
- className="relative inline-flex justify-center whitespace-nowrap font-bold text-primary"
- >
- Projects
-
-
+
Explore a curated collection of open-source projects, components,
React hooks, and more, all in one place.