diff --git a/bun.lockb b/bun.lockb index 51a98af..5ee83fb 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/packages/webui/package.json b/packages/webui/package.json index b47c5c7..139d200 100644 --- a/packages/webui/package.json +++ b/packages/webui/package.json @@ -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", diff --git a/packages/webui/src/AnimatedOutlet.tsx b/packages/webui/src/AnimatedOutlet.tsx new file mode 100644 index 0000000..9f19ef0 --- /dev/null +++ b/packages/webui/src/AnimatedOutlet.tsx @@ -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((props, ref) => { + + const RouterContext = getRouterContext() + const routerContext = useContext(RouterContext) + const renderedContext = useRef(routerContext) + + const isPresent = useIsPresent() + if (isPresent) + renderedContext.current = cloneDeep(routerContext) + + + return ( + + + + + + ) + +}) diff --git a/packages/webui/src/routes/__root.tsx b/packages/webui/src/routes/__root.tsx index 9ffcb49..ceaa5c9 100644 --- a/packages/webui/src/routes/__root.tsx +++ b/packages/webui/src/routes/__root.tsx @@ -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 <>
@@ -22,11 +30,18 @@ export function Root() {
- + + +
+ } export const Route = createRootRoute({ component: Root })