feat(layout): full-screen mobile menu drawer matching Figma 4164-5733
Rebuild the mobile hamburger menu as a full-screen drawer that matches the Figma design 1:1 — five nav items (全部资料 / 资料分类 / 官方推荐 / 最新更新 / 热门资料), transparent item backgrounds over the ark-bg drawer, hairline dividers at #2B2B37, gold text on the active route, and the existing WalletButton compact pill as the bottom CTA. Drop the chevron-right indicators per the rendered Figma frame and remove the old 收藏 row since it's not in the design. Also move the drawer JSX out of <header sticky top-0 z-40> and render it as a sibling at the layout root. The sticky+z-index header was creating a stacking context that trapped the drawer's z-50 fixed below the bottom nav at z-40 global, so the drawer never reached the foreground. Add the same iOS-safe body scroll lock used for the search overlay so the underlying page doesn't drift while the drawer is open.
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
---
|
||||
title: "Mobile menu drawer invisible — Quick Fix"
|
||||
type: quick-fix
|
||||
date: 2026-06-03
|
||||
---
|
||||
|
||||
# Mobile menu drawer invisible — Quick Fix
|
||||
|
||||
## Bug
|
||||
After redesigning the mobile menu to the full-screen Figma drawer (`4164-5336` → `ARK V2 - 導航菜單`), tapping the hamburger toggled the icon to `X` but the drawer overlay never appeared on screen. Page content stayed fully visible and the bottom nav stayed on top.
|
||||
|
||||
## Root Cause
|
||||
The drawer was rendered as a child of `<header className="sticky top-0 z-40 …">`. A `position: sticky` element with a `z-index` creates its own stacking context, which traps the drawer's `position: fixed; z-50` inside that context. Globally, the drawer ends up bound to the header's `z-40` layer, while the unrelated bottom navigation (`<nav className="fixed inset-x-0 bottom-0 z-40 …">`) lives in the root stacking context at `z-40`. With equal global `z`, source order wins — the bottom nav paints later and the drawer never reaches the foreground.
|
||||
|
||||
## Fix
|
||||
Move the drawer JSX out of `<header>` and render it as a sibling at the layout root, so its `fixed`/`z-50` positioning lives in the root stacking context and stacks above both the header and the bottom nav.
|
||||
|
||||
### Files Modified
|
||||
- `src/layouts/PublicLayout.tsx` — relocated the `{open ? (…) : null}` mobile drawer block from inside `<header>` to immediately after `</header>`. Logic unchanged; the `menuRef`, click-outside handler, body scroll lock, and inner nav/CTA structure all keep working because they reference the element by ref/state, not by DOM position.
|
||||
|
||||
## Verification
|
||||
- `npx tsc --noEmit` — clean.
|
||||
- `npm run format` then `npm run format:check` — clean.
|
||||
- `npm test` — 49/49 passing.
|
||||
- Expected on device: tapping the hamburger now reveals the dark full-screen drawer with the 5 nav items, active item in gold, and the bottom `链接钱包` CTA (or the connected-wallet pill).
|
||||
|
||||
## Notes
|
||||
- This is the same class of issue any future fullscreen overlay should avoid: do not nest `position: fixed` overlays inside a `position: sticky + z-index` ancestor. Either render them at the layout root or use a React Portal.
|
||||
- `position: sticky` *without* `z-index` does not create a stacking context, but adding any `z-index` to it does. The header here uses both because it needs to sit above the content while scrolled.
|
||||
Reference in New Issue
Block a user