곡 상세 페이지 트랙 변경 시 스크롤/애니메이션 개선
- ScrollToTop: PC 레이아웃의 main 요소 스크롤 초기화 추가 - TrackDetail: key prop으로 트랙 변경 시 컴포넌트 리마운트 - TrackDetail: main 요소 스크롤 초기화 (PC는 main에서 스크롤) - 수록곡 선택 시 Link 대신 button + navigate 사용 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
eae56df146
commit
a7bc2e9800
3 changed files with 41 additions and 9 deletions
|
|
@ -16,6 +16,12 @@ function ScrollToTop() {
|
|||
if (mobileContent) {
|
||||
mobileContent.scrollTop = 0;
|
||||
}
|
||||
|
||||
// PC 레이아웃 스크롤 컨테이너 초기화
|
||||
const main = document.querySelector('main');
|
||||
if (main) {
|
||||
main.scrollTop = 0;
|
||||
}
|
||||
}, [pathname]);
|
||||
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useState, useMemo, useEffect } from 'react';
|
||||
import { useState, useMemo, useEffect, useLayoutEffect } from 'react';
|
||||
import { useParams, useNavigate, Link } from 'react-router-dom';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { motion } from 'framer-motion';
|
||||
|
|
@ -40,6 +40,11 @@ function MobileTrackDetail() {
|
|||
const youtubeVideoId = useMemo(() => getYoutubeVideoId(track?.video_url), [track?.video_url]);
|
||||
const videoLabel = track?.video_type === 'special' ? '스페셜 영상' : '뮤직비디오';
|
||||
|
||||
// 트랙 변경 시 스크롤 맨 위로
|
||||
useLayoutEffect(() => {
|
||||
window.scrollTo({ top: 0, behavior: 'instant' });
|
||||
}, [trackTitle]);
|
||||
|
||||
// 가사 펼침 상태
|
||||
const [showFullLyrics, setShowFullLyrics] = useState(false);
|
||||
|
||||
|
|
@ -93,7 +98,7 @@ function MobileTrackDetail() {
|
|||
}
|
||||
|
||||
return (
|
||||
<div className="pb-4">
|
||||
<div key={trackTitle} className="pb-4">
|
||||
{/* 트랙 정보 헤더 */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useMemo } from 'react';
|
||||
import { useMemo, useLayoutEffect } from 'react';
|
||||
import { useParams, useNavigate, Link } from 'react-router-dom';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { motion } from 'framer-motion';
|
||||
|
|
@ -40,6 +40,14 @@ function PCTrackDetail() {
|
|||
const youtubeVideoId = useMemo(() => getYoutubeVideoId(track?.video_url), [track?.video_url]);
|
||||
const videoLabel = track?.video_type === 'special' ? '스페셜 영상' : '뮤직비디오';
|
||||
|
||||
// 트랙 변경 시 스크롤 맨 위로
|
||||
useLayoutEffect(() => {
|
||||
const main = document.querySelector('main');
|
||||
if (main) {
|
||||
main.scrollTop = 0;
|
||||
}
|
||||
}, [trackTitle]);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<motion.div
|
||||
|
|
@ -61,7 +69,13 @@ function PCTrackDetail() {
|
|||
}
|
||||
|
||||
return (
|
||||
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ duration: 0.3 }} className="py-12">
|
||||
<motion.div
|
||||
key={trackTitle}
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
className="py-12"
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-6">
|
||||
{/* 브레드크럼 네비게이션 */}
|
||||
<div className="flex items-center gap-2 text-sm text-gray-500 mb-8">
|
||||
|
|
@ -218,11 +232,18 @@ function PCTrackDetail() {
|
|||
{track.otherTracks?.map((t) => {
|
||||
const isCurrent = t.title === track.title;
|
||||
return (
|
||||
<Link
|
||||
<button
|
||||
key={t.id}
|
||||
to={`/album/${encodeURIComponent(track.album?.title || albumName)}/track/${encodeURIComponent(t.title)}`}
|
||||
replace={!isCurrent}
|
||||
className={`group flex items-center gap-3 px-3 py-2.5 rounded-xl transition-all ${
|
||||
type="button"
|
||||
onClick={() => {
|
||||
if (!isCurrent) {
|
||||
navigate(
|
||||
`/album/${encodeURIComponent(track.album?.title || albumName)}/track/${encodeURIComponent(t.title)}`,
|
||||
{ replace: true }
|
||||
);
|
||||
}
|
||||
}}
|
||||
className={`w-full group flex items-center gap-3 px-3 py-2.5 rounded-xl transition-all ${
|
||||
isCurrent ? 'bg-primary text-white' : 'hover:bg-gray-50'
|
||||
}`}
|
||||
>
|
||||
|
|
@ -259,7 +280,7 @@ function PCTrackDetail() {
|
|||
<span className={`text-xs tabular-nums ${isCurrent ? 'text-white/70' : 'text-gray-400'}`}>
|
||||
{t.duration || ''}
|
||||
</span>
|
||||
</Link>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue