From cecb3ecc2394ca29c163060c474140f97780254e Mon Sep 17 00:00:00 2001 From: Yugal Date: Fri, 19 Jun 2026 00:27:17 +0530 Subject: [PATCH] feat: Add ScrollToTop button component for better navigation UX --- client/src/App.js | 2 ++ client/src/components/ScrollToTop.css | 25 ++++++++++++++++ client/src/components/ScrollToTop.jsx | 43 +++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 client/src/components/ScrollToTop.css create mode 100644 client/src/components/ScrollToTop.jsx diff --git a/client/src/App.js b/client/src/App.js index b1205b0..be69733 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -22,6 +22,7 @@ import Todo from "./pages/Todo"; import Login from "./pages/Login"; import Register from "./pages/Register"; import ProtectedRoute from "./components/ProtectedRoute"; +import ScrollToTop from "./components/ScrollToTop"; const App = () => { return ( @@ -31,6 +32,7 @@ const App = () => { {/* Navbar is hidden on login/register via CSS — it checks the route */} + {/* ── Public routes ── */} } /> diff --git a/client/src/components/ScrollToTop.css b/client/src/components/ScrollToTop.css new file mode 100644 index 0000000..4e5eaaf --- /dev/null +++ b/client/src/components/ScrollToTop.css @@ -0,0 +1,25 @@ +.scroll-to-top-btn { + position: fixed; + bottom: 30px; + right: 30px; + width: 45px; + height: 45px; + border-radius: 50%; + background-color: #4f46e5; + color: #ffffff; + border: none; + font-size: 20px; + font-weight: bold; + cursor: pointer; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); + transition: opacity 0.3s ease, transform 0.2s ease; + z-index: 9999; + display: flex; + align-items: center; + justify-content: center; +} + +.scroll-to-top-btn:hover { + background-color: #4338ca; + transform: translateY(-3px); +} \ No newline at end of file diff --git a/client/src/components/ScrollToTop.jsx b/client/src/components/ScrollToTop.jsx new file mode 100644 index 0000000..25ed394 --- /dev/null +++ b/client/src/components/ScrollToTop.jsx @@ -0,0 +1,43 @@ +import React, { useState, useEffect } from "react"; +import "./ScrollToTop.css"; + +const ScrollToTop = () => { + const [isVisible, setIsVisible] = useState(false); + + useEffect(() => { + const toggleVisibility = () => { + if (window.scrollY > 300) { + setIsVisible(true); + } else { + setIsVisible(false); + } + }; + + window.addEventListener("scroll", toggleVisibility); + return () => window.removeEventListener("scroll", toggleVisibility); + }, []); + + const scrollToTop = () => { + window.scrollTo({ + top: 0, + behavior: "smooth", + }); + }; + + return ( + <> + {isVisible && ( + + )} + + ); +}; + +export default ScrollToTop; \ No newline at end of file