Working AnimatedOutlet

This commit is contained in:
Julien Valverdé
2024-07-18 03:10:14 +02:00
parent 0b695506cf
commit d07ba927f9
4 changed files with 56 additions and 3 deletions

BIN
bun.lockb

Binary file not shown.

View File

@@ -21,15 +21,19 @@
"@trpc/client": "^10.45.2",
"@trpc/react-query": "^10.45.2",
"effect": "^3.4.7",
"framer-motion": "^11.3.6",
"lodash-es": "^4.17.21",
"mobx": "^6.13.0",
"mobx-react-lite": "^4.0.7",
"primereact": "^10.7.0",
"react": "^18.3.1",
"react-dom": "^18.3.1"
"react-dom": "^18.3.1",
"remeda": "^2.6.0"
},
"devDependencies": {
"@tanstack/router-devtools": "^1.44.2",
"@tanstack/router-plugin": "^1.44.3",
"@types/lodash-es": "^4.17.12",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^7.15.0",

View File

@@ -0,0 +1,34 @@
import { getRouterContext, Outlet } from "@tanstack/react-router"
import { motion, useIsPresent, type HTMLMotionProps } from "framer-motion"
import { cloneDeep } from "lodash-es"
import { forwardRef, useContext, useRef } from "react"
export module AnimatedOutlet {
export interface Props extends HTMLMotionProps<"div"> {}
}
export const AnimatedOutlet = forwardRef<HTMLDivElement, AnimatedOutlet.Props>((props, ref) => {
const RouterContext = getRouterContext()
const routerContext = useContext(RouterContext)
const renderedContext = useRef(routerContext)
const isPresent = useIsPresent()
if (isPresent)
renderedContext.current = cloneDeep(routerContext)
return (
<motion.div
ref={ref}
{...props}
>
<RouterContext.Provider value={renderedContext.current}>
<Outlet />
</RouterContext.Provider>
</motion.div>
)
})

View File

@@ -1,5 +1,7 @@
import { Link, Outlet, createRootRoute } from "@tanstack/react-router"
import { Link, createRootRoute, useMatch, useMatches } from "@tanstack/react-router"
import { AnimatePresence } from "framer-motion"
import { Suspense, lazy } from "react"
import { AnimatedOutlet } from "../AnimatedOutlet"
const TanStackRouterDevtools = process.env.NODE_ENV === "production"
@@ -10,6 +12,12 @@ const TanStackRouterDevtools = process.env.NODE_ENV === "production"
export function Root() {
const matches = useMatches()
const match = useMatch({ strict: false })
const nextMatch = matches[ matches.findIndex(d => d.id === match.id) + 1 ]
return <>
<div className="container mx-auto mt-8">
<div className="flex flex-row gap-2 justify-center content-center">
@@ -22,11 +30,18 @@ export function Root() {
</Link>
</div>
<Outlet />
<AnimatePresence mode="popLayout">
<AnimatedOutlet
key={nextMatch.id}
initial={{ x: "100%" }}
animate={{ x: "0" }}
/>
</AnimatePresence>
</div>
<Suspense><TanStackRouterDevtools /></Suspense>
</>
}
export const Route = createRootRoute({ component: Root })