add: route transitions

This commit is contained in:
Franek 2024-05-31 20:00:10 +02:00
parent 4131de8692
commit 262b8ebc15
No known key found for this signature in database
GPG Key ID: 0329F871B2079351
7 changed files with 71 additions and 13 deletions

View File

@ -9,6 +9,7 @@
"lint": "next lint" "lint": "next lint"
}, },
"dependencies": { "dependencies": {
"framer-motion": "^11.2.10",
"next": "14.2.3", "next": "14.2.3",
"react": "^18", "react": "^18",
"react-dom": "^18", "react-dom": "^18",
@ -18,6 +19,7 @@
"@types/node": "^20", "@types/node": "^20",
"@types/react": "^18", "@types/react": "^18",
"@types/react-dom": "^18", "@types/react-dom": "^18",
"@types/react-transition-group": "^4.4.10",
"@types/styled-components": "^5.1.34", "@types/styled-components": "^5.1.34",
"eslint": "^8", "eslint": "^8",
"eslint-config-next": "14.2.3", "eslint-config-next": "14.2.3",

View File

@ -1,14 +1,17 @@
"use client" "use client"
import { AnimatePresence } from "framer-motion";
import { Montserrat } from "next/font/google"; import { Montserrat } from "next/font/google";
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import NavigationBar from "@/components/navigation_bar.component"; import NavigationBar from "@/components/navigation_bar.component";
import { ThemeProvider } from "@/providers/theme.provider"; import Transitioned from "@/components/transition.component";
import { GlobalLayout, MainBlock } from "@/styles";
import Loader from "@/components/loader.component"; import Loader from "@/components/loader.component";
const inter = Montserrat({ subsets: ["latin"] }); import { ThemeProvider } from "@/providers/theme.provider";
import { GlobalLayout } from "@/styles";
const font = Montserrat({ subsets: ["latin"] });
export default function RootLayout({ export default function RootLayout({
children, children,
@ -20,7 +23,6 @@ export default function RootLayout({
useEffect(() => { useEffect(() => {
const handleComplete = () => setLoading(false); const handleComplete = () => setLoading(false);
// simulate loading delay
const timer = setTimeout(handleComplete, 1000); const timer = setTimeout(handleComplete, 1000);
return () => clearTimeout(timer); return () => clearTimeout(timer);
}, []); }, []);
@ -38,17 +40,15 @@ export default function RootLayout({
<title>Parafia pw. Niepokalanego Serca NMP w Borzęcie</title> <title>Parafia pw. Niepokalanego Serca NMP w Borzęcie</title>
<meta name="description" content="Strona parafii pod wezwaniem Niepokalanego Serca Najświętszej Maryi Panny w Borzęcie." /> <meta name="description" content="Strona parafii pod wezwaniem Niepokalanego Serca Najświętszej Maryi Panny w Borzęcie." />
</head> </head>
<body className={inter.className}> <body className={font.className}>
<ThemeProvider> <ThemeProvider>
<GlobalLayout /> <GlobalLayout />
{loading {loading
? <Loader /> ? <Loader />
: <> : <AnimatePresence mode="wait">
<MainBlock> <NavigationBar />
<NavigationBar /> <Transitioned>{children}</Transitioned>
{children} </AnimatePresence>}
</MainBlock>
</>}
</ThemeProvider> </ThemeProvider>
</body> </body>
</html> </html>

View File

@ -10,7 +10,7 @@ export default function Home() {
<h1>Parafia w Borzęcie</h1> <h1>Parafia w Borzęcie</h1>
<p>Już wkrótce powstanie tutaj świeża strona parafii pod wezwaniem Niepokalanego Serca Maryi w Borzęcie.</p> <p>Już wkrótce powstanie tutaj świeża strona parafii pod wezwaniem Niepokalanego Serca Maryi w Borzęcie.</p>
<a href="tel:+48123456789">zadzwoń do proboszcza</a> <a href="tel:+48123456789">zadzwoń do proboszcza</a>
<hr />
<h2>Aktualny motyw: {theme}</h2> <h2>Aktualny motyw: {theme}</h2>
<Button onClick={toggleTheme}>Przełącz motyw</Button> <Button onClick={toggleTheme}>Przełącz motyw</Button>
</>; </>;

View File

@ -0,0 +1,42 @@
import { usePathname } from "next/navigation";
import { PropsWithChildren } from "react";
import { motion } from "framer-motion";
import { MainBlock } from "@/styles";
const transitionVariants = {
initial: {
scale: 0.8,
opacity: 0
},
animate: {
scale: 1,
opacity: 1
},
exit: {
scale: 1.2,
opacity: 0
}
};
const pageTransition = {
type: "spring",
ease: "anticipate",
duration: 0.5
};
export default function Transitioned({ children }: PropsWithChildren) {
const pathName = usePathname();
return <motion.div
key={pathName}
variants={transitionVariants}
transition={pageTransition}
initial="initial"
animate="animate"
exit="exit"
>
<MainBlock>
{children}
</MainBlock>
</motion.div>;
}

View File

@ -2,7 +2,7 @@ import { createContext, useContext, useMemo, PropsWithChildren } from "react";
import { ThemeProvider as StyledThemeProvider } from "styled-components"; import { ThemeProvider as StyledThemeProvider } from "styled-components";
import { ThemeMode, lightTheme, darkTheme } from "@/app/themes"; import { ThemeMode, lightTheme, darkTheme } from "@/app/themes";
import useLocalStorage from "@/utils/local_storage"; import useLocalStorage from "@/hooks/local_storage";
const ThemeContext = createContext({ const ThemeContext = createContext({
theme: "light", theme: "light",

View File

@ -222,6 +222,13 @@
dependencies: dependencies:
"@types/react" "*" "@types/react" "*"
"@types/react-transition-group@^4.4.10":
version "4.4.10"
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.10.tgz#6ee71127bdab1f18f11ad8fb3322c6da27c327ac"
integrity sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==
dependencies:
"@types/react" "*"
"@types/react@*", "@types/react@^18": "@types/react@*", "@types/react@^18":
version "18.3.3" version "18.3.3"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.3.tgz#9679020895318b0915d7a3ab004d92d33375c45f" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.3.tgz#9679020895318b0915d7a3ab004d92d33375c45f"
@ -1126,6 +1133,13 @@ foreground-child@^3.1.0:
cross-spawn "^7.0.0" cross-spawn "^7.0.0"
signal-exit "^4.0.1" signal-exit "^4.0.1"
framer-motion@^11.2.10:
version "11.2.10"
resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-11.2.10.tgz#c8671e33e8f8d4abbd95efd20d3b8a888f457ed7"
integrity sha512-/gr3PLZUVFCc86a9MqCUboVrALscrdluzTb3yew+2/qKBU8CX6nzs918/SRBRCqaPbx0TZP10CB6yFgK2C5cYQ==
dependencies:
tslib "^2.4.0"
fs.realpath@^1.0.0: fs.realpath@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"