From d8ebd9099036d98604002b0068d94e8121245ebf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=84=EB=AF=BC=EC=98=A4?= Date: Tue, 10 Dec 2024 11:05:19 +0900 Subject: [PATCH] feat: optimize school activity button --- .../home/SchoolActivityButton/index.tsx | 263 ++++++++++++++---- .../home/SchoolActivityButton/style.ts | 69 ++++- 2 files changed, 263 insertions(+), 69 deletions(-) diff --git a/src/components/home/SchoolActivityButton/index.tsx b/src/components/home/SchoolActivityButton/index.tsx index 636d4e1..36ef8f2 100644 --- a/src/components/home/SchoolActivityButton/index.tsx +++ b/src/components/home/SchoolActivityButton/index.tsx @@ -1,104 +1,215 @@ -import { useState } from "react"; +import { useState, useCallback, memo, useEffect, useRef } from "react"; import { IoArrowForward } from "react-icons/io5"; import { BiCodeAlt, BiMath } from "react-icons/bi"; import { HiOutlineAcademicCap } from "react-icons/hi"; import { DiDatabase } from "react-icons/di"; -import * as S from "./style"; -import { AnimatePresence } from "framer-motion"; import { AiFillRobot } from "react-icons/ai"; +import { AnimatePresence } from "framer-motion"; +import * as S from "./style"; +// Types interface Activity { - id: string; - name: string; - description: string; - path: string; - icon: JSX.Element; + readonly id: string; + readonly name: string; + readonly description: string; + readonly path: string; + readonly icon: JSX.Element; } -const activities: Activity[] = [ +interface ActivityItemProps extends Omit { + onClick?: () => void; +} + +// Constants +const EMPHASIS_THRESHOLD = 0.9; // 90% for emphasis + +// Animation variants +const menuVariants = { + hidden: { opacity: 0, y: 20, scale: 0.95 }, + visible: { + opacity: 1, + y: 0, + scale: 1, + transition: { duration: 0.2 }, + }, + exit: { + opacity: 0, + y: 20, + scale: 0.95, + transition: { duration: 0.2 }, + }, +}; + +const arrowVariants = { + hidden: { opacity: 0, x: 0 }, + visible: { opacity: 1, x: 4 }, +}; + +const emphasisVariants = { + normal: { + scale: 1, + boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)", + }, + emphasis: { + scale: 1.05, + boxShadow: "0 8px 12px rgba(0, 0, 0, 0.15)", + transition: { + duration: 0.3, + ease: "easeOut", + }, + }, +}; + +const activities: readonly Activity[] = [ { id: "narsha", name: "나르샤", description: "교내 IT 프로젝트", path: "/narsha", - icon: , + icon: