fix: Finally fix top-16 gap and add dashboard redirect on exit
The Real Problem:
After removing contextual headers, SubmenuBar still used headerVisible
logic to calculate top position. This caused the persistent top-16 gap
because it thought a header existed when it did not.
Root Cause Analysis:
1. We removed contextual headers from Dashboard pages ✓
2. But SubmenuBar still had: top-16 when headerVisible=true
3. Header was being tracked but did not exist
4. Result: 64px gap at top (top-16 = 4rem = 64px)
The Solution:
Since we removed ALL contextual headers, submenu should ALWAYS be at
top-0 in fullscreen mode. No conditional logic needed.
Changes Made:
1. SubmenuBar.tsx
Before:
const topClass = fullscreen
? (headerVisible ? "top-16" : "top-0") ← Wrong!
: "top-[calc(7rem+32px)]";
After:
const topClass = fullscreen
? "top-0" ← Always top-0, no header exists!
: "top-[calc(7rem+32px)]";
2. DashboardSubmenuBar.tsx
Same fix as SubmenuBar
3. App.tsx
- Removed headerVisible prop from submenu components
- Removed isHeaderVisible state (no longer needed)
- Removed onVisibilityChange from Header (no longer tracking)
- Cleaned up unused scroll detection logic
4. More/index.tsx
- Added handleExitFullscreen function
- Exits fullscreen + navigates to dashboard (/)
- User requested: "redirect member to dashboard overview"
Why This Was Hard:
The issue was not the padding itself, but the LOGIC that calculated it.
We had multiple layers of conditional logic (fullscreen, headerVisible,
standalone) that became inconsistent after removing contextual headers.
The fix required understanding the entire flow:
- No contextual headers → No header exists
- No header → No need to offset submenu
- Submenu always at top-0 in fullscreen
Result:
✅ No top gap - submenu starts at top-0
✅ Exit fullscreen redirects to dashboard
✅ Simplified logic - removed unnecessary tracking
✅ Clean, predictable behavior
Files Modified:
- SubmenuBar.tsx
- DashboardSubmenuBar.tsx
- App.tsx
- More/index.tsx
The top-16 nightmare is finally over! 🎯
This commit is contained in:
@@ -452,7 +452,6 @@ function Shell() {
|
|||||||
const isDesktop = useIsDesktop();
|
const isDesktop = useIsDesktop();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const scrollContainerRef = React.useRef<HTMLDivElement>(null);
|
const scrollContainerRef = React.useRef<HTMLDivElement>(null);
|
||||||
const [isHeaderVisible, setIsHeaderVisible] = React.useState(true);
|
|
||||||
|
|
||||||
// Check if standalone mode - force fullscreen and hide toggle
|
// Check if standalone mode - force fullscreen and hide toggle
|
||||||
const isStandalone = window.WNW_CONFIG?.standaloneMode ?? false;
|
const isStandalone = window.WNW_CONFIG?.standaloneMode ?? false;
|
||||||
@@ -469,7 +468,7 @@ function Shell() {
|
|||||||
{!isStandalone && <ShortcutsBinder onToggle={toggle} />}
|
{!isStandalone && <ShortcutsBinder onToggle={toggle} />}
|
||||||
{!isStandalone && <CommandPalette toggleFullscreen={toggle} />}
|
{!isStandalone && <CommandPalette toggleFullscreen={toggle} />}
|
||||||
<div className={`flex flex-col min-h-screen ${fullscreen ? 'woonoow-fullscreen-root' : ''}`}>
|
<div className={`flex flex-col min-h-screen ${fullscreen ? 'woonoow-fullscreen-root' : ''}`}>
|
||||||
<Header onFullscreen={toggle} fullscreen={fullscreen} showToggle={!isStandalone} scrollContainerRef={scrollContainerRef} onVisibilityChange={setIsHeaderVisible} />
|
<Header onFullscreen={toggle} fullscreen={fullscreen} showToggle={!isStandalone} scrollContainerRef={scrollContainerRef} />
|
||||||
{fullscreen ? (
|
{fullscreen ? (
|
||||||
isDesktop ? (
|
isDesktop ? (
|
||||||
<div className="flex flex-1 min-h-0">
|
<div className="flex flex-1 min-h-0">
|
||||||
@@ -490,9 +489,9 @@ function Shell() {
|
|||||||
<div className="flex flex-1 flex-col min-h-0">
|
<div className="flex flex-1 flex-col min-h-0">
|
||||||
<PageHeader fullscreen={true} />
|
<PageHeader fullscreen={true} />
|
||||||
{!isMorePage && (isDashboardRoute ? (
|
{!isMorePage && (isDashboardRoute ? (
|
||||||
<DashboardSubmenuBar items={main.children} fullscreen={true} headerVisible={isHeaderVisible} />
|
<DashboardSubmenuBar items={main.children} fullscreen={true} />
|
||||||
) : (
|
) : (
|
||||||
<SubmenuBar items={main.children} fullscreen={true} headerVisible={isHeaderVisible} />
|
<SubmenuBar items={main.children} fullscreen={true} />
|
||||||
))}
|
))}
|
||||||
<main className="flex-1 flex flex-col min-h-0 min-w-0 pb-14">
|
<main className="flex-1 flex flex-col min-h-0 min-w-0 pb-14">
|
||||||
<div ref={scrollContainerRef} className="flex-1 overflow-auto p-4 min-w-0">
|
<div ref={scrollContainerRef} className="flex-1 overflow-auto p-4 min-w-0">
|
||||||
|
|||||||
@@ -22,11 +22,10 @@ export default function DashboardSubmenuBar({ items = [], fullscreen = false, he
|
|||||||
|
|
||||||
if (items.length === 0) return null;
|
if (items.length === 0) return null;
|
||||||
|
|
||||||
// Calculate top position based on fullscreen state and header visibility
|
// Calculate top position based on fullscreen state
|
||||||
// Fullscreen with header visible: top-16 (below 64px header)
|
// Fullscreen: top-0 (no contextual headers, submenu is first element)
|
||||||
// Fullscreen with header hidden: top-0 (replace header position)
|
|
||||||
// Normal: top-[calc(7rem+32px)] (below WP admin bar + menu bar)
|
// Normal: top-[calc(7rem+32px)] (below WP admin bar + menu bar)
|
||||||
const topClass = fullscreen ? (headerVisible ? 'top-16' : 'top-0') : 'top-[calc(7rem+32px)]';
|
const topClass = fullscreen ? 'top-0' : 'top-[calc(7rem+32px)]';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div data-submenubar className={`border-b border-border bg-background md:bg-background/95 md:backdrop-blur md:supports-[backdrop-filter]:bg-background/60 sticky ${topClass} z-20`}>
|
<div data-submenubar className={`border-b border-border bg-background md:bg-background/95 md:backdrop-blur md:supports-[backdrop-filter]:bg-background/60 sticky ${topClass} z-20`}>
|
||||||
|
|||||||
@@ -11,11 +11,10 @@ export default function SubmenuBar({ items = [], fullscreen = false, headerVisib
|
|||||||
// Single source of truth: props.items. No fallbacks, no demos, no path-based defaults
|
// Single source of truth: props.items. No fallbacks, no demos, no path-based defaults
|
||||||
if (items.length === 0) return null;
|
if (items.length === 0) return null;
|
||||||
|
|
||||||
// Calculate top position based on fullscreen state and header visibility
|
// Calculate top position based on fullscreen state
|
||||||
// Fullscreen with header visible: top-16 (below 64px header)
|
// Fullscreen: top-0 (no contextual headers, submenu is first element)
|
||||||
// Fullscreen with header hidden: top-0 (replace header position)
|
|
||||||
// Normal: top-[calc(7rem+32px)] (below WP admin bar + menu bar)
|
// Normal: top-[calc(7rem+32px)] (below WP admin bar + menu bar)
|
||||||
const topClass = fullscreen ? (headerVisible ? 'top-16' : 'top-0') : 'top-[calc(7rem+32px)]';
|
const topClass = fullscreen ? 'top-0' : 'top-[calc(7rem+32px)]';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div data-submenubar className={`border-b border-border bg-background md:bg-background/95 md:backdrop-blur md:supports-[backdrop-filter]:bg-background/60 sticky ${topClass} z-20`}>
|
<div data-submenubar className={`border-b border-border bg-background md:bg-background/95 md:backdrop-blur md:supports-[backdrop-filter]:bg-background/60 sticky ${topClass} z-20`}>
|
||||||
|
|||||||
@@ -38,6 +38,12 @@ export default function MorePage() {
|
|||||||
return () => clearPageHeader();
|
return () => clearPageHeader();
|
||||||
}, [setPageHeader, clearPageHeader]);
|
}, [setPageHeader, clearPageHeader]);
|
||||||
|
|
||||||
|
const handleExitFullscreen = () => {
|
||||||
|
exitFullscreen?.();
|
||||||
|
// Redirect to dashboard after exiting fullscreen
|
||||||
|
navigate('/');
|
||||||
|
};
|
||||||
|
|
||||||
const handleLogout = () => {
|
const handleLogout = () => {
|
||||||
// Clear auth and redirect to login
|
// Clear auth and redirect to login
|
||||||
window.location.href = window.WNW_CONFIG?.wpAdminUrl || '/wp-admin';
|
window.location.href = window.WNW_CONFIG?.wpAdminUrl || '/wp-admin';
|
||||||
@@ -87,7 +93,7 @@ export default function MorePage() {
|
|||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
onClick={exitFullscreen}
|
onClick={handleExitFullscreen}
|
||||||
variant="outline"
|
variant="outline"
|
||||||
className="w-full justify-start gap-3"
|
className="w-full justify-start gap-3"
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user