refactor: replace preset detail modal layoutId morph with bottom sheet slide-up + category crossfade
- Remove layoutId from preset card in game-page-client.tsx and modal in preset-detail-modal.tsx to eliminate text smearing during morph animation. - Replace modal scale/opacity spring animation with bottom sheet y-slide spring (y: 100% → 0). - Wrap settings table content in AnimatePresence mode='wait' with keyed motion.div for crossfade when switching categories.
This commit is contained in:
@@ -751,7 +751,6 @@ export function GamePageClient({
|
||||
return (
|
||||
<motion.div
|
||||
key={preset.id}
|
||||
layoutId={preset.id}
|
||||
onClick={() => setSelectedPresetId(preset.id)}
|
||||
className={`shrink-0 w-72 flex flex-col gap-3 p-4 rounded-xl border transition-colors cursor-pointer hover:border-primary/30 ${
|
||||
raw
|
||||
|
||||
@@ -164,14 +164,13 @@ export function PresetDetailModal({
|
||||
>
|
||||
{/* Modal card */}
|
||||
<motion.div
|
||||
layoutId={preset.id}
|
||||
className="relative w-full max-w-4xl max-h-[90vh] overflow-hidden rounded-xl border border-border bg-background flex flex-col"
|
||||
initial={{ scale: 0.95, opacity: 0 }}
|
||||
animate={{ scale: 1, opacity: 1 }}
|
||||
exit={{ scale: 0.95, opacity: 0 }}
|
||||
initial={{ y: "100%", opacity: 0 }}
|
||||
animate={{ y: 0, opacity: 1 }}
|
||||
exit={{ y: "100%", opacity: 0 }}
|
||||
transition={{
|
||||
type: "spring",
|
||||
damping: 25,
|
||||
damping: 30,
|
||||
stiffness: 300,
|
||||
}}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
@@ -427,7 +426,15 @@ export function PresetDetailModal({
|
||||
{/* Right panel */}
|
||||
<div className="flex-1 overflow-y-auto p-5">
|
||||
{hasCategories ? (
|
||||
<div className="flex flex-col gap-4">
|
||||
<AnimatePresence mode="wait">
|
||||
<motion.div
|
||||
key={currentCategory?.category ?? "empty"}
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.15 }}
|
||||
className="flex flex-col gap-4"
|
||||
>
|
||||
{/* Category navigation */}
|
||||
<div className="flex items-center justify-between">
|
||||
<button
|
||||
@@ -482,7 +489,8 @@ export function PresetDetailModal({
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
) : (
|
||||
<div className="flex flex-col items-center justify-center py-16 gap-3 rounded-lg border border-border bg-text/2">
|
||||
<p className="text-sm text-text/40">
|
||||
|
||||
Reference in New Issue
Block a user