From b653749151f004aa830a261e07b20e0fa4869b6a Mon Sep 17 00:00:00 2001 From: JManion32 Date: Thu, 5 Mar 2026 23:52:33 -0500 Subject: [PATCH 1/2] Add page component transitions --- package-lock.json | 49 ++++++++++++++++++++++++++++ package.json | 1 + src/components/AppLayout.tsx | 23 +++++++------ src/components/Carousel.tsx | 32 +++++++++--------- src/components/navbar/NavbarLink.tsx | 41 ++++++++++++++++++----- src/css/app-layout.css | 10 +++++- src/css/carousel.css | 6 ++++ 7 files changed, 125 insertions(+), 37 deletions(-) diff --git a/package-lock.json b/package-lock.json index bb2870c..3537aa8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "dependencies": { "@heroicons/react": "^2.2.0", + "framer-motion": "^12.35.0", "gsap": "^3.14.2", "lucide-react": "^0.564.0", "react": "^19.2.0", @@ -3851,6 +3852,39 @@ "node": ">= 6" } }, + "node_modules/framer-motion": { + "version": "12.35.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.35.0.tgz", + "integrity": "sha512-w8hghCMQ4oq10j6aZh3U2yeEQv5K69O/seDI/41PK4HtgkLrcBovUNc0ayBC3UyyU7V1mrY2yLzvYdWJX9pGZQ==", + "license": "MIT", + "dependencies": { + "motion-dom": "^12.35.0", + "motion-utils": "^12.29.2", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/framer-motion/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, "node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -5000,6 +5034,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/motion-dom": { + "version": "12.35.0", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.35.0.tgz", + "integrity": "sha512-FFMLEnIejK/zDABn+vqGVAUN4T0+3fw+cVAY8MMT65yR+j5uMuvWdd4npACWhh94OVWQs79CrBBuwOwGRZAQiA==", + "license": "MIT", + "dependencies": { + "motion-utils": "^12.29.2" + } + }, + "node_modules/motion-utils": { + "version": "12.29.2", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.29.2.tgz", + "integrity": "sha512-G3kc34H2cX2gI63RqU+cZq+zWRRPSsNIOjpdl9TN4AQwC4sgwYPl/Q/Obf/d53nOm569T0fYK+tcoSV50BWx8A==", + "license": "MIT" + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", diff --git a/package.json b/package.json index da94634..a674676 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ }, "dependencies": { "@heroicons/react": "^2.2.0", + "framer-motion": "^12.35.0", "gsap": "^3.14.2", "lucide-react": "^0.564.0", "react": "^19.2.0", diff --git a/src/components/AppLayout.tsx b/src/components/AppLayout.tsx index d665fa8..be116a0 100644 --- a/src/components/AppLayout.tsx +++ b/src/components/AppLayout.tsx @@ -1,16 +1,15 @@ -/* Layout that each page will follow */ import '../css/app-layout.css'; import { Outlet } from 'react-router-dom'; - -import Navbar from './navbar/Navbar.tsx'; +import Navbar from './navbar/Navbar'; export default function AppLayout() { - return ( -
- -
- -
-
- ); -} + + return ( +
+ +
+ +
+
+ ); +} \ No newline at end of file diff --git a/src/components/Carousel.tsx b/src/components/Carousel.tsx index 1b02341..c8ec2a4 100644 --- a/src/components/Carousel.tsx +++ b/src/components/Carousel.tsx @@ -8,21 +8,23 @@ type CarouselProps = { export default function Carousel({ type }: CarouselProps) { return ( <> -
-

{type}

-
- - - +
+
+ {type} +
+ + + +
diff --git a/src/components/navbar/NavbarLink.tsx b/src/components/navbar/NavbarLink.tsx index 4ace121..6db770b 100644 --- a/src/components/navbar/NavbarLink.tsx +++ b/src/components/navbar/NavbarLink.tsx @@ -1,14 +1,37 @@ -import { NavLink } from 'react-router-dom'; +import { NavLink, useNavigate } from 'react-router-dom'; +import type { MouseEvent } from 'react'; type NavbarLinkProps = { - label: string; - nav: string; + label: string; + nav: string; }; export default function NavbarLink({ label, nav }: NavbarLinkProps) { - return ( - `navlink ${isActive ? 'active-navlink' : ''}`}> - {label} - - ); -} + const navigate = useNavigate(); + + const handleClick = (e: MouseEvent) => { + e.preventDefault(); + + const content = document.querySelector('.app-content'); + if (!content) { + navigate(nav); + return; + } + + content.classList.add('page-transition'); + setTimeout(() => { navigate(nav); }, 300); + setTimeout(() => { content.classList.remove('page-transition'); }, 400); + }; + + return ( + + `navlink ${isActive ? 'active-navlink' : ''}` + } + > + {label} + + ); +} \ No newline at end of file diff --git a/src/css/app-layout.css b/src/css/app-layout.css index 9b489f3..023676b 100644 --- a/src/css/app-layout.css +++ b/src/css/app-layout.css @@ -8,5 +8,13 @@ .app-content { padding: 3rem; - width: 75%; + width: 100%; + position: relative; + overflow: hidden; + transition: transform 0.4s ease, opacity 0.4s ease; } + +.app-content.page-transition { + transform: scale(0.95); + opacity: 0.10; +} \ No newline at end of file diff --git a/src/css/carousel.css b/src/css/carousel.css index 9cb6043..7803865 100644 --- a/src/css/carousel.css +++ b/src/css/carousel.css @@ -4,6 +4,12 @@ gap: 4rem; } +.carousel-container { + display: flex; + flex-direction: column; + align-items: center; +} + .carousel { width: 100%; background: var(--carousel-bg); From 1b43a1c1f48c4bd5ce9d943afe1379930b28a45a Mon Sep 17 00:00:00 2001 From: JManion32 Date: Thu, 5 Mar 2026 23:54:50 -0500 Subject: [PATCH 2/2] Linter --- src/components/AppLayout.tsx | 19 +++++----- src/components/navbar/NavbarLink.tsx | 54 ++++++++++++++-------------- src/css/app-layout.css | 10 +++--- 3 files changed, 43 insertions(+), 40 deletions(-) diff --git a/src/components/AppLayout.tsx b/src/components/AppLayout.tsx index be116a0..0058023 100644 --- a/src/components/AppLayout.tsx +++ b/src/components/AppLayout.tsx @@ -3,13 +3,12 @@ import { Outlet } from 'react-router-dom'; import Navbar from './navbar/Navbar'; export default function AppLayout() { - - return ( -
- -
- -
-
- ); -} \ No newline at end of file + return ( +
+ +
+ +
+
+ ); +} diff --git a/src/components/navbar/NavbarLink.tsx b/src/components/navbar/NavbarLink.tsx index 6db770b..7a4f920 100644 --- a/src/components/navbar/NavbarLink.tsx +++ b/src/components/navbar/NavbarLink.tsx @@ -2,36 +2,38 @@ import { NavLink, useNavigate } from 'react-router-dom'; import type { MouseEvent } from 'react'; type NavbarLinkProps = { - label: string; - nav: string; + label: string; + nav: string; }; export default function NavbarLink({ label, nav }: NavbarLinkProps) { - const navigate = useNavigate(); + const navigate = useNavigate(); - const handleClick = (e: MouseEvent) => { - e.preventDefault(); + const handleClick = (e: MouseEvent) => { + e.preventDefault(); - const content = document.querySelector('.app-content'); - if (!content) { - navigate(nav); - return; - } + const content = document.querySelector('.app-content'); + if (!content) { + navigate(nav); + return; + } - content.classList.add('page-transition'); - setTimeout(() => { navigate(nav); }, 300); - setTimeout(() => { content.classList.remove('page-transition'); }, 400); - }; + content.classList.add('page-transition'); + setTimeout(() => { + navigate(nav); + }, 300); + setTimeout(() => { + content.classList.remove('page-transition'); + }, 400); + }; - return ( - - `navlink ${isActive ? 'active-navlink' : ''}` - } - > - {label} - - ); -} \ No newline at end of file + return ( + `navlink ${isActive ? 'active-navlink' : ''}`} + > + {label} + + ); +} diff --git a/src/css/app-layout.css b/src/css/app-layout.css index 023676b..979d6af 100644 --- a/src/css/app-layout.css +++ b/src/css/app-layout.css @@ -11,10 +11,12 @@ width: 100%; position: relative; overflow: hidden; - transition: transform 0.4s ease, opacity 0.4s ease; + transition: + transform 0.4s ease, + opacity 0.4s ease; } .app-content.page-transition { - transform: scale(0.95); - opacity: 0.10; -} \ No newline at end of file + transform: scale(0.95); + opacity: 0.1; +}