Files
omniai-web/src/components/PageTransition.tsx
T

78 lines
2.1 KiB
TypeScript
Raw Normal View History

2026-06-02 12:38:01 +08:00
import { useEffect, useRef, useState, type ReactNode } from "react";
interface PageTransitionProps {
viewKey: string;
children: ReactNode;
}
const EXIT_DURATION_MS = 180;
const NAV_ORDER: string[] = [
"home",
"workbench",
"ecommerce",
"ecommerceTemplates",
"sizeTemplate",
"canvas",
"scriptTokens",
"tokenUsage",
"community",
"assets",
"more",
"imageWorkbench",
"resolutionUpscale",
"watermarkRemoval",
"subtitleRemoval",
"digitalHuman",
"avatarConsole",
"characterMix",
"agent",
"settings",
"login",
"profile",
"report",
];
function getNavIndex(key: string): number {
return NAV_ORDER.indexOf(key);
}
2026-06-02 12:38:01 +08:00
export default function PageTransition({ viewKey, children }: PageTransitionProps) {
const [displayedChildren, setDisplayedChildren] = useState(children);
const [phase, setPhase] = useState<"idle" | "exit">("idle");
const [direction, setDirection] = useState<"forward" | "backward" | "neutral">("neutral");
2026-06-02 12:38:01 +08:00
const prevKeyRef = useRef(viewKey);
const timerRef = useRef<ReturnType<typeof setTimeout>>();
useEffect(() => {
if (viewKey === prevKeyRef.current) {
setDisplayedChildren(children);
return;
}
const prevIndex = getNavIndex(prevKeyRef.current);
const nextIndex = getNavIndex(viewKey);
if (prevIndex < nextIndex) {
setDirection("forward");
} else if (prevIndex > nextIndex) {
setDirection("backward");
} else {
setDirection("neutral");
}
2026-06-02 12:38:01 +08:00
prevKeyRef.current = viewKey;
setPhase("exit");
timerRef.current = setTimeout(() => {
setDisplayedChildren(children);
setPhase("idle");
}, EXIT_DURATION_MS);
return () => clearTimeout(timerRef.current);
}, [viewKey, children]);
const dirClass = direction === "forward" ? " is-forward" : direction === "backward" ? " is-backward" : "";
2026-06-02 12:38:01 +08:00
return (
<div className={phase === "exit" ? `page-transition-wrap page-motion--exit${dirClass}` : `page-transition-wrap${phase === "idle" && direction !== "neutral" ? ` page-motion--enter${dirClass}` : ""}`}>
2026-06-02 12:38:01 +08:00
{displayedChildren}
</div>
);
}