From 99748ca202f30467c92c2c7881d1b087afd46d3c Mon Sep 17 00:00:00 2001 From: dwindown Date: Thu, 6 Nov 2025 15:25:55 +0700 Subject: [PATCH] refactor: Move overflow-auto to content wrapper for proper sticky behavior MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: Trying to make sticky work inside a scrollable container is complex: - Different offsets for fullscreen vs WP-Admin - MutationObserver to detect mode changes - Fragile and hard to maintain Root Cause:
← Scrollable container ← Sticky inside scrollable
← Nested sticky, complex offsets Better Approach: Move overflow-auto from
to content wrapper: Before:
After:
← Sticky outside scrollable ✅
← Only content scrolls ✅ Benefits: ✅ Submenu always sticky (outside scroll container) ✅ Sticky header simple: just top-0 ✅ No mode detection needed ✅ No MutationObserver ✅ Works everywhere: fullscreen, WP-Admin, standalone ✅ Cleaner, more maintainable code Changes: 1. App.tsx: -
: overflow-auto → flex flex-col min-h-0 - Content wrapper: p-4 → flex-1 overflow-auto p-4 2. SettingsLayout.tsx: - Removed fullscreen detection - Removed MutationObserver - Simplified to: sticky top-0 (always) Layout Structure (All Modes): ┌─────────────────────────────────────┐ │ Header / TopNav │ ├─────────────────────────────────────┤ │
│ │ ┌─────────────────────────────┐ │ │ │ SubmenuBar (sticky) │ │ ← Always sticky │ ├─────────────────────────────┤ │ │ │
│ │ ← Scroll here │ │ Sticky Header (top-0) │ │ ← Simple! │ │ Gap (mb-6) │ │ │ │ Content... │ │ │ └─────────────────────────────┘ │ └─────────────────────────────────────┘ Result: ✅ Simpler code (removed 20+ lines) ✅ More reliable behavior ✅ Easier to understand ✅ Works in all modes without special cases Files Modified: - App.tsx: Restructured scroll containers - SettingsLayout.tsx: Simplified sticky logic --- admin-spa/src/App.tsx | 16 +++++++++----- .../Settings/components/SettingsLayout.tsx | 22 +------------------ 2 files changed, 11 insertions(+), 27 deletions(-) diff --git a/admin-spa/src/App.tsx b/admin-spa/src/App.tsx index ebe74bc..40ca763 100644 --- a/admin-spa/src/App.tsx +++ b/admin-spa/src/App.tsx @@ -414,13 +414,13 @@ function Shell() { isDesktop ? (
-
+
{isDashboardRoute ? ( ) : ( )} -
+
@@ -433,8 +433,10 @@ function Shell() { ) : ( )} -
- +
+
+ +
) @@ -446,8 +448,10 @@ function Shell() { ) : ( )} -
- +
+
+ +
)} diff --git a/admin-spa/src/routes/Settings/components/SettingsLayout.tsx b/admin-spa/src/routes/Settings/components/SettingsLayout.tsx index fe0d036..a771052 100644 --- a/admin-spa/src/routes/Settings/components/SettingsLayout.tsx +++ b/admin-spa/src/routes/Settings/components/SettingsLayout.tsx @@ -33,31 +33,11 @@ export function SettingsLayout({ } }; - // Detect fullscreen mode - const [isFullscreen, setIsFullscreen] = React.useState(false); - - React.useEffect(() => { - const checkFullscreen = () => { - setIsFullscreen(document.querySelector('.woonoow-fullscreen-root') !== null); - }; - - checkFullscreen(); - // Re-check on route changes or mode toggles - const observer = new MutationObserver(checkFullscreen); - observer.observe(document.body, { attributes: true, attributeFilter: ['class'], subtree: true }); - - return () => observer.disconnect(); - }, []); - - // In fullscreen: submenu is inside scrollable area, so offset by submenu height (49px) - // In WP-Admin: submenu is outside scrollable area, so no offset needed (top-0) - const stickyTop = isFullscreen ? 'top-[49px]' : 'top-0'; - return (
{/* Sticky Header with Save Button - Edge to edge */} {onSave && ( -
+

{title}