Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement router transitions #358

Merged
merged 6 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 9 additions & 18 deletions dapp/src/DApp.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,26 @@
import React from "react"
import { Box, ChakraProvider } from "@chakra-ui/react"
import { ChakraProvider } from "@chakra-ui/react"
import { Provider as ReduxProvider } from "react-redux"
import { RouterProvider } from "react-router-dom"
import { useInitApp } from "./hooks"
import { store } from "./store"
import theme from "./theme"
import { AcreSdkProvider } from "./acre-react/contexts"
import GlobalStyles from "./components/GlobalStyles"
import {
DocsDrawerContextProvider,
LedgerWalletAPIProvider,
SidebarContextProvider,
WalletContextProvider,
} from "./contexts"
import { AcreSdkProvider } from "./acre-react/contexts"
import Header from "./components/Header"
import Sidebar from "./components/Sidebar"
import DocsDrawer from "./components/DocsDrawer"
import GlobalStyles from "./components/GlobalStyles"
import { router } from "./router"
import { useInitApp } from "./hooks"
import { Router } from "./router"
import { store } from "./store"
import theme from "./theme"

function DApp() {
useInitApp()

return (
<>
<Header />
<Box as="main">
<RouterProvider router={router} />
</Box>
<Sidebar />
<DocsDrawer />
<GlobalStyles />
<Router />
</>
)
}
Expand All @@ -42,7 +34,6 @@ function DAppProviders() {
<SidebarContextProvider>
<ReduxProvider store={store}>
<ChakraProvider theme={theme}>
<GlobalStyles />
<DApp />
</ChakraProvider>
</ReduxProvider>
Expand Down
45 changes: 45 additions & 0 deletions dapp/src/components/shared/Layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React, { useState } from "react"
import { AnimatePresence, motion, Variants } from "framer-motion"
import { useLocation, useOutlet } from "react-router-dom"
import Header from "../Header"
import DocsDrawer from "../DocsDrawer"
import Sidebar from "../Sidebar"

const wrapperVariants: Variants = {
in: { opacity: 0, y: 48 },
out: { opacity: 0, y: -48 },
visible: { opacity: 1, y: 0 },
}

// This tricky component makes Outlet persistent so React and Framer Motion can
// distinguish wheather it should be rerendered between routes.
// Ref: https://github.com/remix-run/react-router/discussions/8008#discussioncomment-1280897
function PersistentOutlet() {
const [outlet] = useState(useOutlet())
ioay marked this conversation as resolved.
Show resolved Hide resolved
return outlet
}

function Layout() {
const location = useLocation()
return (
<>
<Header />
<AnimatePresence mode="popLayout">
<motion.main
key={location.pathname}
variants={wrapperVariants}
transition={{ type: "spring", damping: 12, stiffness: 120 }}
initial="in"
animate="visible"
exit="out"
>
<PersistentOutlet />
</motion.main>
</AnimatePresence>
<Sidebar />
<DocsDrawer />
</>
)
}

export default Layout
34 changes: 18 additions & 16 deletions dapp/src/router/index.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import React from "react"
import { createBrowserRouter } from "react-router-dom"
import { BrowserRouter, Route, Routes } from "react-router-dom"
import LandingPage from "#/pages/LandingPage"
import ActivityPage from "#/pages/ActivityPage"
import DashboardPage from "#/pages/DashboardPage"
import Layout from "#/components/shared/Layout"
import { routerPath } from "./path"

export const router = createBrowserRouter([
{
path: routerPath.home,
element: <LandingPage />,
index: true,
},
{
path: routerPath.dashboard,
element: <DashboardPage />,
},
{
path: `${routerPath.activity}/:activityId`,
element: <ActivityPage />,
},
])
export function Router() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Layout />}>
<Route index path={routerPath.home} element={<LandingPage />} />
<Route path={routerPath.dashboard} element={<DashboardPage />} />
<Route
path={`${routerPath.activity}/:activityId`}
element={<ActivityPage />}
/>
</Route>
</Routes>
</BrowserRouter>
)
}
Loading