From 6ca610d014624c4430e51d58b7a0bf5e117973f9 Mon Sep 17 00:00:00 2001 From: caadiq Date: Tue, 14 Apr 2026 17:15:55 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B3=B5=EC=A7=80=20=EC=9C=84=EC=A0=AF=20?= =?UTF-8?q?=ED=8E=BC=EC=B9=A8/=ED=83=AD=20=EC=A0=84=ED=99=98=20=EC=95=A0?= =?UTF-8?q?=EB=8B=88=EB=A9=94=EC=9D=B4=EC=85=98=20=EB=B6=80=EB=93=9C?= =?UTF-8?q?=EB=9F=BD=EA=B2=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 더보기/접기를 framer-motion height + opacity + translateY로 전환 - 탭 변경 시 AnimatePresence mode="wait"로 페이드+슬라이드 전환 Co-Authored-By: Claude Opus 4.6 (1M context) --- frontend/src/components/NoticeWidget.jsx | 65 +++++++++++++++++------- 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/frontend/src/components/NoticeWidget.jsx b/frontend/src/components/NoticeWidget.jsx index 8043be0..41df9b5 100644 --- a/frontend/src/components/NoticeWidget.jsx +++ b/frontend/src/components/NoticeWidget.jsx @@ -1,5 +1,6 @@ import { useState } from 'react' import { useQuery } from '@tanstack/react-query' +import { motion, AnimatePresence } from 'framer-motion' import { api } from '../api/client' const TABS = [ @@ -148,32 +149,58 @@ export default function NoticeWidget() { ))} ) : initialItems.length === 0 ? ( -
- {tab.filterOngoing ? `진행중인 ${tab.label}이 없습니다` : `등록된 ${tab.label}이 없습니다`} -
+ + + {tab.filterOngoing ? `진행중인 ${tab.label}이 없습니다` : `등록된 ${tab.label}이 없습니다`} + + ) : ( <> -
- {initialItems.map((notice) => ( - - ))} -
- - {/* 펼쳐지는 영역 - grid-template-rows 트릭으로 부드럽게 애니메이션 */} - {hasMore && ( -
+ -
+ {initialItems.map((notice) => ( + + ))} + + + + {/* 펼쳐지는 영역 */} + + {hasMore && expanded && ( +
{extraItems.map((notice) => ( ))}
-
-
- )} + + )} + )} @@ -189,7 +216,7 @@ export default function NoticeWidget() { height="12" viewBox="0 0 12 12" fill="none" - className={`transition-transform duration-300 ${expanded ? 'rotate-180' : ''}`} + className={`transition-transform duration-500 ease-[cubic-bezier(0.22,1,0.36,1)] ${expanded ? 'rotate-180' : ''}`} >