Skip to content

Conversation

@crutch12
Copy link
Contributor

@crutch12 crutch12 commented Dec 3, 2025

Summary

Fixes #6608

Hide MenuBar buttons on mobile using css (media query)

Initial render screenshot:
image

cow.fi:
image

To Test

On Mobile:

  1. Open /limit

  2. See initial site rendering, or reload page

Should see no desktop buttons in MenuBar

Background

  • the problem is caused because of runtime conditional rendering (useMediaQuery usage). by default isMobile = false , thus mobile user sees desktop buttons
  • extracted isMobile query into isMobileQuery to share this logic between conditional rendering (isMobile = ...) and media query displaying (const HideMobile = ...)

Summary by CodeRabbit

  • Refactor
    • Improved navigation responsiveness by updating mobile-detection logic for different screen sizes.
    • Desktop navigation items are now hidden on smaller screens to streamline the mobile layout and reduce visual clutter.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 3, 2025

Walkthrough

Replaces JavaScript-based media checks with CSS media-query helpers by introducing isMobileQuery and HideMobile, and updates AppMenu and MenuBar to use them so desktop-only elements are hidden via CSS at initial render.

Changes

Cohort / File(s) Summary
Responsive styled helpers
apps/cowswap-frontend/src/modules/application/containers/AppMenu/styled.ts, libs/ui/src/pure/MenuBar/styled.ts
Add isMobileQuery (alias to Media.upTo*) and HideMobile (styled div) that applies isMobileQuery(true) to set display: none on mobile breakpoints.
AppMenu component
apps/cowswap-frontend/src/modules/application/containers/AppMenu/index.tsx
Replace Media.upToMedium(false) with isMobileQuery(false); wrap persistentAdditionalContent children with HideMobile for non-mobile rendering; update imports.
MenuBar component
libs/ui/src/pure/MenuBar/index.tsx
Replace Media.upToLarge(false) with isMobileQuery(false); wrap desktop NavItems in HideMobile so they are hidden on mobile from initial paint; export HideMobile/isMobileQuery.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

  • Check consistency of breakpoint choices (upToMedium vs upToLarge) between components.
  • Verify HideMobile CSS scope and that it prevents desktop content flash on initial render.
  • Confirm exports in libs/ui's styled module don't introduce name collisions.

Suggested reviewers

  • shoom3301

Poem

🐰
I hopped through styles, soft and spry,
Hid big bits when the screen is tiny,
No more flashing desktop surprise,
CSS did the trick — what a prize! 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: fixing mobile menu bar broken buttons by hiding them, which directly addresses the core problem in the changeset.
Description check ✅ Passed The description includes issue reference, clear explanation of the problem and solution, screenshots, testing steps for mobile, and background context on why the fix was needed.
Linked Issues check ✅ Passed The PR addresses all objectives from issue #6608: hiding desktop MenuBar buttons on mobile using CSS media queries to prevent broken initial render by extracting isMobileQuery for both conditional and CSS-based hiding.
Out of Scope Changes check ✅ Passed All changes are scoped to the mobile menu bar fix: new styled components (HideMobile, isMobileQuery) and refactored rendering logic remain focused on the stated objective.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@vercel
Copy link

vercel bot commented Dec 3, 2025

@crutch12 is attempting to deploy a commit to the cow-dev Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/cowswap-frontend/src/modules/application/containers/AppMenu/styled.ts (1)

1-11: Clarify that this isMobileQuery uses a different breakpoint than the MenuBar one

Here isMobileQuery is Media.upToMedium, while libs/ui’s MenuBar/styled.ts defines its own isMobileQuery = Media.upToLarge. Using the same name for different ranges can be confusing when reading code across modules.

Consider either documenting this difference inline or giving this helper a more specific name (e.g. isMobileMenuQuery or similar) to reflect that AppMenu’s notion of “mobile” is narrower than MenuBar’s.

Before renaming or documenting, please verify that AppMenu is intentionally using the up‑to‑medium breakpoint and that this divergence from MenuBar’s up‑to‑large threshold matches the desired UX across devices.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dd05bb7 and ea3d4aa.

📒 Files selected for processing (4)
  • apps/cowswap-frontend/src/modules/application/containers/AppMenu/index.tsx (4 hunks)
  • apps/cowswap-frontend/src/modules/application/containers/AppMenu/styled.ts (1 hunks)
  • libs/ui/src/pure/MenuBar/index.tsx (3 hunks)
  • libs/ui/src/pure/MenuBar/styled.ts (2 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-10-10T20:28:16.565Z
Learnt from: fairlighteth
Repo: cowprotocol/cowswap PR: 6347
File: apps/cowswap-frontend/src/modules/trade/pure/TradeConfirmation/index.tsx:49-49
Timestamp: 2025-10-10T20:28:16.565Z
Learning: In apps/cowswap-frontend/src/modules/trade, TradeConfirmation follows a two-layer architecture: TradeConfirmationView (pure/stateless) in pure/TradeConfirmation/index.tsx renders the UI, while TradeConfirmation (container) in containers/TradeConfirmation/index.tsx wraps it to freeze props during pending trades (via useStableTradeConfirmationProps), wire in signing state (useSigningStep), and inject trade confirmation state (useTradeConfirmState). Consuming modules should import the container TradeConfirmation from 'modules/trade' to preserve this stateful behavior.
<!-- [add_learning]
When reviewing component refactoring in apps/cowswap-frontend/src/modules/trade, recognize the pattern where a pure view component (e.g., TradeConfirmationView) is separated from a stateful container (e.g., TradeConfirmation) that wraps it. The container adds runtime state management (prop stabilization, signing state, etc.) while the view remains testable and composable. Do not flag usages that import th...

Applied to files:

  • apps/cowswap-frontend/src/modules/application/containers/AppMenu/index.tsx
📚 Learning: 2025-09-11T08:25:51.460Z
Learnt from: alfetopito
Repo: cowprotocol/cowswap PR: 6234
File: libs/tokens/src/index.ts:1-4
Timestamp: 2025-09-11T08:25:51.460Z
Learning: In the cowprotocol/cowswap project, there is currently no SSR (Server-Side Rendering) support, so localStorage access at module import time does not cause SSR-related issues.

Applied to files:

  • apps/cowswap-frontend/src/modules/application/containers/AppMenu/index.tsx
🧬 Code graph analysis (2)
apps/cowswap-frontend/src/modules/application/containers/AppMenu/styled.ts (2)
libs/ui/src/pure/MenuBar/styled.ts (2)
  • isMobileQuery (773-773)
  • HideMobile (775-779)
libs/ui/src/consts.ts (1)
  • Media (23-43)
libs/ui/src/pure/MenuBar/index.tsx (2)
apps/cowswap-frontend/src/legacy/hooks/useMediaQuery.ts (1)
  • useMediaQuery (7-24)
libs/ui/src/pure/MenuBar/styled.ts (3)
  • isMobileQuery (773-773)
  • HideMobile (775-779)
  • NavItems (166-234)
🔇 Additional comments (3)
libs/ui/src/pure/MenuBar/styled.ts (1)

3-3: Shared isMobileQuery + HideMobile helper is a clean way to centralize the breakpoint

Aliasing Media.upToLarge as isMobileQuery and reusing it both in CSS (HideMobile) and via hooks in MenuBar keeps the “mobile” breakpoint in one place and solves the initial flash without changing the breakpoint semantics.

Also applies to: 773-779

apps/cowswap-frontend/src/modules/application/containers/AppMenu/index.tsx (1)

6-6: Using isMobileQuery + HideMobile here correctly removes the initial desktop flash for header children

Wiring isMobile through useMediaQuery(isMobileQuery(false)) and wrapping children in <HideMobile> for the persistentAdditionalContent slot means:

  • On mobile, the desktop header content is visually hidden immediately via CSS, even while isMobile is still false on the first render.
  • After the media query hook updates, persistentAdditionalContent becomes null, so desktop-only content stays out of the mobile layout.

This looks consistent with the intended behavior of that slot.

Please double‑check that isMobileQuery(false) indeed returns a raw media query string (without the @media prefix) matching what useMediaQuery from @cowprotocol/common-hooks expects, and that the chosen up‑to‑medium breakpoint aligns with the product definition of “mobile” for AppMenu.

Also applies to: 22-23, 46-47, 113-114

libs/ui/src/pure/MenuBar/index.tsx (1)

51-53: Reusing isMobileQuery and wrapping NavItems in HideMobile cleanly fixes the initial desktop flicker

Switching isMobile to useMediaQuery(isMobileQuery(false)) keeps the breakpoint aligned with the styled helper, and wrapping the desktop NavItems block in <HideMobile> ensures that on mobile widths the desktop menu is CSS‑hidden immediately while the hook still reports false on the first render. Once isMobile flips to true, the block isn’t rendered at all, so runtime behavior remains consistent with the prior logic without the flash.

This is a solid approach for synchronizing JS and CSS behavior around the same breakpoint.

Please confirm that:

  • isMobileQuery(true) produces the correct @media wrapper for styled‑components, and
  • isMobileQuery(false) yields the raw media condition string that useMediaQuery expects,

so both CSS and JS stay in lockstep with the intended “mobile” breakpoint.

Also applies to: 938-940, 1004-1019

@vercel
Copy link

vercel bot commented Dec 3, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Updated (UTC)
swap-dev Ready Ready Preview Dec 5, 2025 6:37am

}
`

export const isMobileQuery = Media.upToLarge
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice context clarification!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
libs/ui/src/pure/MenuBar/styled.ts (1)

776-780: LGTM! CSS-based hiding solves the initial render flash issue.

The HideMobile component correctly uses isMobileQuery(true) to apply display: none via CSS media query. This ensures desktop-only elements are hidden immediately on mobile without waiting for JavaScript hydration, which directly addresses the initial render flash described in the PR objectives.

Consider adding a JSDoc comment to document the purpose:

+/**
+ * Hides child elements on mobile viewports using CSS media queries.
+ * Used to prevent desktop-only UI from flashing on initial mobile render.
+ */
 export const HideMobile = styled.div`
   ${isMobileQuery(true)} {
     display: none;
   }
 `
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ea3d4aa and 3600107.

📒 Files selected for processing (1)
  • libs/ui/src/pure/MenuBar/styled.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
libs/ui/src/pure/MenuBar/styled.ts (2)
apps/cowswap-frontend/src/modules/application/containers/AppMenu/styled.ts (2)
  • isMobileQuery (5-5)
  • HideMobile (7-11)
libs/ui/src/consts.ts (1)
  • Media (23-43)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Setup
  • GitHub Check: Cypress
🔇 Additional comments (2)
libs/ui/src/pure/MenuBar/styled.ts (2)

3-3: LGTM! Media import is necessary for the new exports.

The addition of Media to the imports is correct and required for the isMobileQuery constant defined below.


774-774: Verify the breakpoint consistency between MenuBar and AppMenu.

The implementation correctly aliases Media.upToLarge for MenuBar's mobile query. However, AppMenu/styled.ts defines its own isMobileQuery using Media.upToMedium, which is a different breakpoint.

This means:

  • MenuBar switches to mobile mode at the "Large" breakpoint
  • AppMenu switches to mobile mode at the "Medium" breakpoint (earlier)

Please confirm this difference is intentional. If both components should transition to mobile mode at the same screen size, consider using a shared breakpoint constant.

Copy link
Contributor

@elena-zh elena-zh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the UI perspective changes LGTM

@shoom3301 shoom3301 merged commit 63da8fc into cowprotocol:develop Dec 5, 2025
9 of 15 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators Dec 5, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mobile: MenuBar's initial broken styles

3 participants