From 5035a6ba7985e21bf5c8d2bef978ab4cbfdfecc0 Mon Sep 17 00:00:00 2001 From: jamunatg2006-sys Date: Tue, 2 Jun 2026 22:38:27 +0530 Subject: [PATCH 1/3] Improve Mobile Responsiveness Across All Pages #129 --- src/index.css | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/index.css b/src/index.css index 62a28405..5c4a4401 100644 --- a/src/index.css +++ b/src/index.css @@ -139,3 +139,18 @@ pre { code { font-family: 'JetBrains Mono', 'Fira Code', monospace; } + +/* Responsive media */ +img, video { + max-width: 100%; + height: auto; +} + +/* Prevent horizontal scroll on mobile */ +html, body { + overflow-x: hidden; +} + +* { + min-width: 0; +} From d91accdb9ada42956d1926bd2c0536e233bfc3a9 Mon Sep 17 00:00:00 2001 From: jamunatg2006-sys Date: Tue, 2 Jun 2026 23:10:48 +0530 Subject: [PATCH 2/3] fix(routing): Integrate react-router-dom and resolve navigation issues (#131) --- package-lock.json | 60 ++++++++++++++++++- package.json | 3 +- src/App.tsx | 19 +++++- src/components/NotFound.tsx | 7 +++ .../ResponsiveMultiLevelNavigation.tsx | 12 ++-- 5 files changed, 93 insertions(+), 8 deletions(-) create mode 100644 src/components/NotFound.tsx diff --git a/package-lock.json b/package-lock.json index 91854f7c..a51e0bf4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,8 @@ "version": "0.0.0", "dependencies": { "react": "^19.2.6", - "react-dom": "^19.2.6" + "react-dom": "^19.2.6", + "react-router-dom": "^7.16.0" }, "devDependencies": { "@eslint/js": "^10.0.1", @@ -1632,6 +1633,19 @@ "dev": true, "license": "MIT" }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -2762,6 +2776,44 @@ "react": "^19.2.6" } }, + "node_modules/react-router": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.16.0.tgz", + "integrity": "sha512-wArC8lVyJb3+jM9OpDyW6hLCizACWkvQR/sSGqSs+o5uEXEtGlqdZ4v8hENR3Jad6i+LRkK93q/+bQAcvl6V1A==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.16.0.tgz", + "integrity": "sha512-kMUAbimWB5FVbF4Bce4bJsiKJWLIUHq/mEG8+CFDnCSgltptBiG5nguducmsJeGKytlCvQud9Qhzpn49iduTlA==", + "license": "MIT", + "dependencies": { + "react-router": "7.16.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, "node_modules/rolldown": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.1.tgz", @@ -2812,6 +2864,12 @@ "semver": "bin/semver.js" } }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "license": "MIT" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", diff --git a/package.json b/package.json index 5e6932db..76a4588b 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ }, "dependencies": { "react": "^19.2.6", - "react-dom": "^19.2.6" + "react-dom": "^19.2.6", + "react-router-dom": "^7.16.0" }, "devDependencies": { "@eslint/js": "^10.0.1", diff --git a/src/App.tsx b/src/App.tsx index 3e552dd5..40ea263a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,5 @@ import React, { useState, useMemo, useEffect } from 'react'; +import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'; import { Search, Copy, @@ -25,6 +26,8 @@ import { } from 'lucide-react'; import { CATEGORIES, ALL_COMPONENTS as COMPONENTS } from './data/components'; import { InteractivePreview } from './components/InteractivePreview'; +import ResponsiveMultiLevelNavigation from './components/ResponsiveMultiLevelNavigation'; +import NotFound from './components/NotFound'; type TechFramework = 'html' | 'react' | 'nextjs' | 'vue' | 'angular'; type ColorAccent = 'violet' | 'emerald' | 'rose' | 'blue' | 'amber'; @@ -191,7 +194,10 @@ export default function App() { ]; return ( -
+ + + {/* Background Mesh Gradients */}
@@ -722,6 +728,15 @@ export default function App() {
)} - + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + ); } diff --git a/src/components/NotFound.tsx b/src/components/NotFound.tsx new file mode 100644 index 00000000..225707a3 --- /dev/null +++ b/src/components/NotFound.tsx @@ -0,0 +1,7 @@ +export default function NotFound() { + return ( +
+

404 - Page Not Found

+
+ ); +} diff --git a/src/components/ResponsiveMultiLevelNavigation.tsx b/src/components/ResponsiveMultiLevelNavigation.tsx index eaa48dcb..16a49dc1 100644 --- a/src/components/ResponsiveMultiLevelNavigation.tsx +++ b/src/components/ResponsiveMultiLevelNavigation.tsx @@ -1,4 +1,5 @@ -import React, { useEffect, useMemo, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; +import { Link, useNavigate, useLocation } from "react-router-dom"; type NavItem = { id: string; @@ -112,7 +113,7 @@ function NavNode({ ) : null} {item.path ? ( -
{item.path}
+ onSelect(item.path!)}>{item.path} ) : null} {hasChildren ? ( @@ -140,7 +141,9 @@ function NavNode({ export default function ResponsiveMultiLevelNavigation() { const allPaths = useMemo(() => flattenPaths(navTree), []); - const [activePath, setActivePath] = useState(allPaths[0] ?? "/dashboard"); + const location = useLocation(); + const navigate = useNavigate(); + const activePath = location.pathname; const [expanded, setExpanded] = useState>({ workspace: true, reports: true, @@ -155,6 +158,7 @@ export default function ResponsiveMultiLevelNavigation() { return () => window.removeEventListener("resize", onResize); }, []); + // Ensure expanded groups reflect the current path useEffect(() => { const activeTrail = findPath(navTree, activePath); if (activeTrail) { @@ -173,7 +177,7 @@ export default function ResponsiveMultiLevelNavigation() { }; const selectPath = (path: string) => { - setActivePath(path); + navigate(path); if (compact) setMobileOpen(false); }; From 5b38144b9903e74d096cb5a68da5cc2cb967bfdb Mon Sep 17 00:00:00 2001 From: jamunatg2006-sys Date: Wed, 3 Jun 2026 23:54:05 +0530 Subject: [PATCH 3/3] feat(navigation): Add dark mode toggle and localStorage theme persistence #130 --- src/App.tsx | 15 ++- .../ResponsiveMultiLevelNavigation.tsx | 105 ++++++++++++------ 2 files changed, 84 insertions(+), 36 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 40ea263a..6fb7ffa6 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -40,8 +40,15 @@ export default function App() { const [previewSizes, setPreviewSizes] = useState>({}); const [copiedId, setCopiedId] = useState(null); - // Theme state (dark mode by default) - const [darkMode, setDarkMode] = useState(true); + // Theme state (dark mode by default, persisted in localStorage) + const [darkMode, setDarkMode] = useState(() => { + if (typeof window !== 'undefined') { + const stored = localStorage.getItem('theme'); + if (stored) return stored === 'dark'; + return document.documentElement.classList.contains('dark') || !stored; + } + return true; + }); // Playground workspace state const [showPlayground, setShowPlayground] = useState(false); @@ -51,15 +58,17 @@ export default function App() { `); - // Sync dark class on body + // Sync dark class on root and save theme preference in localStorage useEffect(() => { const root = window.document.documentElement; if (darkMode) { root.classList.add('dark'); root.classList.remove('light'); + localStorage.setItem('theme', 'dark'); } else { root.classList.add('light'); root.classList.remove('dark'); + localStorage.setItem('theme', 'light'); } }, [darkMode]); diff --git a/src/components/ResponsiveMultiLevelNavigation.tsx b/src/components/ResponsiveMultiLevelNavigation.tsx index 16a49dc1..2d9338cf 100644 --- a/src/components/ResponsiveMultiLevelNavigation.tsx +++ b/src/components/ResponsiveMultiLevelNavigation.tsx @@ -1,5 +1,6 @@ import { useEffect, useMemo, useState } from "react"; import { Link, useNavigate, useLocation } from "react-router-dom"; +import { Sun, Moon } from "lucide-react"; type NavItem = { id: string; @@ -99,7 +100,9 @@ function NavNode({ if (item.path) onSelect(item.path); }} className={`flex w-full items-center justify-between gap-2 rounded-2xl px-4 py-3 text-left transition ${ - isActive ? "bg-slate-900 text-white" : "bg-white hover:bg-slate-50" + isActive + ? "bg-slate-900 text-white dark:bg-white dark:text-slate-900" + : "bg-white text-slate-700 hover:bg-slate-50 dark:bg-slate-800 dark:text-slate-200 dark:hover:bg-slate-700/80" }`} style={{ paddingLeft: `${16 + depth * 18}px` }} > @@ -107,17 +110,17 @@ function NavNode({
{item.label} {item.badge ? ( - + {item.badge} ) : null}
{item.path ? ( - onSelect(item.path!)}>{item.path} + onSelect(item.path!)}>{item.path} ) : null} {hasChildren ? ( - {isOpen ? "−" : "+"} + {isOpen ? "−" : "+"} ) : null} {hasChildren && isOpen ? ( @@ -151,6 +154,29 @@ export default function ResponsiveMultiLevelNavigation() { const [mobileOpen, setMobileOpen] = useState(false); const [compact, setCompact] = useState(false); + // Sync dark mode state with localStorage and document element + const [isDark, setIsDark] = useState(() => { + if (typeof window !== 'undefined') { + const stored = localStorage.getItem('theme'); + if (stored) return stored === 'dark'; + return document.documentElement.classList.contains('dark') || !stored; + } + return true; + }); + + useEffect(() => { + const root = window.document.documentElement; + if (isDark) { + root.classList.add('dark'); + root.classList.remove('light'); + localStorage.setItem('theme', 'dark'); + } else { + root.classList.add('light'); + root.classList.remove('dark'); + localStorage.setItem('theme', 'light'); + } + }, [isDark]); + useEffect(() => { const onResize = () => setCompact(window.innerWidth < 900); onResize(); @@ -182,38 +208,49 @@ export default function ResponsiveMultiLevelNavigation() { }; return ( -
-
+
+
-

Responsive Multi-Level Navigation

-

Nested routes, adaptive collapse, and route awareness.

+

Responsive Multi-Level Navigation

+

Nested routes, adaptive collapse, and route awareness.

- {compact ? ( +
+ {/* Theme Toggle Button */} - ) : null} + + {compact ? ( + + ) : null} +
-
+
-

Active route

-

+

Active route

+

The current selection is highlighted in the tree and the matching ancestor groups stay open so users never lose context inside a dense information hierarchy.

-
-
Route
-
{activePath}
+
+
Route
+
{activePath}
-
-
Presentation
-
{compact ? "Mobile drawer" : "Desktop sidebar"}
+
+
Presentation
+
{compact ? "Mobile drawer" : "Desktop sidebar"}
-
-
Open sections
-
+
+
Open sections
+
{Object.values(expanded).filter(Boolean).length}
-
-

Preview content

-

+

+

Preview content

+

This layout is designed for admin panels and content-heavy applications. The recursive tree can support additional levels without changing the rendering model, and the mobile drawer preserves usable navigation in narrow screens. @@ -276,7 +313,9 @@ export default function ResponsiveMultiLevelNavigation() { key={path} onClick={() => selectPath(path)} className={`rounded-2xl px-4 py-3 text-left text-sm transition ${ - path === activePath ? "bg-slate-900 text-white" : "bg-slate-50 hover:bg-slate-100" + path === activePath + ? "bg-slate-900 text-white dark:bg-white dark:text-slate-900" + : "bg-slate-50 hover:bg-slate-100 dark:bg-slate-800 dark:hover:bg-slate-700/80 text-slate-700 dark:text-slate-200" }`} > {path}