StaggerGroup 파라미터를 프로미스나인 사이트와 동일하게 맞춤 + 보스 리스트 애니메이션

- StaggerGroup 기본값: y 30px / duration 0.4s / 간격 0.1s, default ease
  (프로미스나인 AlbumDetail 패턴과 일치)
- staggerDelay / yOffset / duration prop 받도록 커스터마이즈 가능
- BossCrystal fade-in 파라미터도 동일하게 맞춤
- BossSelector 보스 리스트에 StaggerGroup 적용 (항목 많으므로 간격 0.04s,
  y 20px, duration 0.3s 로 가볍게)
- CharacterPanel 은 Reorder.Group 드래그 로직과 충돌하므로 제외

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
caadiq 2026-04-22 00:16:56 +09:00
parent d1764dea94
commit 1344a2f7a9
3 changed files with 38 additions and 21 deletions

View file

@ -1,26 +1,36 @@
import { Children } from 'react'
import { motion } from 'framer-motion'
const containerVariants = {
hidden: {},
show: { transition: { staggerChildren: 0.07 } },
}
const itemVariants = {
hidden: { opacity: 0, y: 10 },
show: {
opacity: 1,
y: 0,
transition: { duration: 0.35, ease: [0.22, 1, 0.36, 1] },
},
}
/**
* 자식을 motion.div 감싸 순차 페이드인.
* 레이아웃에 영향 주지 않도록 wrapper div flex/grid 특성이 없어야 하는 자리에서만 사용.
* space-y-* 같은 Tailwind 유틸은 그대로 className 넘겨 유지.
* 기본값은 프로미스나인 사이트와 동일 (y 30, duration 0.4, 간격 0.1s).
*
* @param {number} staggerDelay - 자식 간격 ()
* @param {number} yOffset - 시작 y 오프셋 (px)
* @param {number} duration - 자식 애니메이션 지속시간 ()
*/
export default function StaggerGroup({ children, className, style }) {
export default function StaggerGroup({
children,
className,
style,
staggerDelay = 0.1,
yOffset = 30,
duration = 0.4,
}) {
const containerVariants = {
hidden: {},
show: { transition: { staggerChildren: staggerDelay } },
}
const itemVariants = {
hidden: { opacity: 0, y: yOffset },
show: {
opacity: 1,
y: 0,
transition: { duration },
},
}
return (
<motion.div
className={className}

View file

@ -73,9 +73,9 @@ export default function BossCrystal() {
return (
<motion.div
className="h-full"
initial={{ opacity: 0, y: 10 }}
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.35, ease: [0.22, 1, 0.36, 1] }}
transition={{ duration: 0.4 }}
>
{isLoading ? (
<div

View file

@ -1,5 +1,6 @@
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react'
import Select from '../../../../components/common/Select'
import StaggerGroup from '../../../../components/common/StaggerGroup'
import { DIFFICULTIES, formatMeso } from '../admin/constants'
const LABEL_EN = { easy: 'EASY', normal: 'NORMAL', hard: 'HARD', chaos: 'CHAOS', extreme: 'EXTREME' }
@ -67,7 +68,13 @@ export default function BossSelector({ characterName, bosses, selections, onChan
}}
defer
>
<div className="divide-y px-2" style={{ '--tw-divide-opacity': 1 }}>
<StaggerGroup
className="divide-y px-2"
style={{ '--tw-divide-opacity': 1 }}
staggerDelay={0.04}
yOffset={20}
duration={0.3}
>
{bosses.map((boss) => {
const availableDiffs = DIFFICULTIES.filter((d) =>
boss.difficulties.some((bd) => bd.difficulty === d.key)
@ -168,7 +175,7 @@ export default function BossSelector({ characterName, bosses, selections, onChan
</div>
)
})}
</div>
</StaggerGroup>
</OverlayScrollbarsComponent>
</div>
)