Skip to content

fix: add persistent desktop navigation#108

Open
AlejandroAkbal wants to merge 1 commit intomainfrom
auto-triage/206-feature-better-design-for-desktop-computer-laptop
Open

fix: add persistent desktop navigation#108
AlejandroAkbal wants to merge 1 commit intomainfrom
auto-triage/206-feature-better-design-for-desktop-computer-laptop

Conversation

@AlejandroAkbal
Copy link
Member

@AlejandroAkbal AlejandroAkbal commented Mar 15, 2026

Summary

  • add a sticky desktop sidebar so navigation stays visible on large screens instead of keeping the app in a centered mobile-style shell
  • keep the existing mobile drawer flow, hide the hamburger button on desktop, and automatically close the drawer when the viewport crosses into the desktop breakpoint
  • offset the fixed posts navbar on desktop so it does not overlap the new sidebar

Validation

  • pnpm build (fails on current repo baseline: assets/js/nuxt-image/imgproxy.provider.ts imports Buffer from buffer, which Vite externalizes in browser builds)
  • pnpm exec vue-tsc --noEmit (fails on current repo baseline with existing repo-wide typing issues unrelated to this patch)
  • runtime browser validation was blocked by the local dev environment because Nuxt errored on missing import-in-the-middle from .nuxt/dev/index.mjs

Summary by CodeRabbit

Release Notes

Improvements

  • Navigation menu now automatically closes when the viewport expands to large screen sizes and adjusts responsively during window resizing.
  • Redesigned layout structure with responsive two-column design: desktop sidebar (hidden on mobile) and optimized main content area.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 15, 2026

Walkthrough

This PR restructures the layout system to support a responsive two-column design with a persistent desktop sidebar, adjusts the navbar positioning for posts pages, and implements automatic menu dismissal on large screens when the window is resized.

Changes

Cohort / File(s) Summary
Navigation UI
components/layout/navigation/Navbar.vue, components/layout/navigation/SidebarWrapper.vue
Navbar gains LG breakpoint positioning (lg:left-64) on posts pages and hides menu button on large screens. SidebarWrapper adds responsive behavior: desktop breakpoint detection via useEventListener, auto-closes menu on mount and during window resize when viewport exceeds 1024px.
Layout Restructuring
layouts/default.vue
Converted single-column layout to responsive two-column structure with left desktop-only sidebar and main content area. Reorganized layout primitives into a flex row, made sidebar sticky on large viewports, and repositioned Navbar, Toaster, DialogManager, and SidebarWrapper into the new main content flow.

Sequence Diagram

sequenceDiagram
    participant Window as Window/Viewport
    participant SidebarWrapper as SidebarWrapper
    participant Menu as Navigation Menu
    participant Layout as Layout Renderer

    Window->>SidebarWrapper: onMounted
    SidebarWrapper->>SidebarWrapper: closeMenuOnDesktopBreakpoint()<br/>(width >= 1024px)
    SidebarWrapper->>Menu: closeMenu()
    Menu->>Layout: Update visibility state
    Layout->>Layout: Re-render (menu hidden)

    Window->>Window: User resizes window
    Window->>SidebarWrapper: 'resize' event
    SidebarWrapper->>SidebarWrapper: closeMenuOnDesktopBreakpoint()<br/>(check breakpoint)
    alt width >= 1024px
        SidebarWrapper->>Menu: closeMenu()
        Menu->>Layout: Update visibility state
        Layout->>Layout: Re-render (menu hidden)
    else width < 1024px
        Note over Menu: Menu state unchanged
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: add persistent desktop navigation' directly addresses the main change: adding a sticky desktop sidebar for persistent navigation on large screens, which is the primary objective.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch auto-triage/206-feature-better-design-for-desktop-computer-laptop
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch auto-triage/206-feature-better-design-for-desktop-computer-laptop
📝 Coding Plan
  • Generate coding plan for human review comments

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.

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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/layout/navigation/Navbar.vue`:
- Around line 47-50: Navbar.vue currently hardcodes the desktop offset as
'lg:left-64' when isPostsPage is true, duplicating the sidebar width defined as
'w-64' in layouts/default.vue; replace the hard-coded value with a shared token
(CSS variable or layout token) so both the sidebar width and Navbar offset
reference the same variable (e.g., --sidebar-width) and update the conditional
class in Navbar.vue (isPostsPage branch) to use that variable instead of
'lg:left-64' and ensure layouts/default.vue uses the same variable for 'w-64' so
changes to sidebar width stay in sync.

In `@layouts/default.vue`:
- Around line 98-113: The DialogManager and SidebarWrapper (and Toaster) are
rendered before Navbar so Navbar may paint on top; move the <ClientOnly> block
containing <Toaster> and <DialogManager> and the <SidebarWrapper> (including
<LazySidebar>) to render after <Navbar> so the overlays (DialogManager,
SidebarWrapper) are mounted last and sit above Navbar (alternatively ensure
these components set a higher z-index than Navbar), specifically adjust the
order of ClientOnly, DialogManager, SidebarWrapper/LazySidebar relative to the
Navbar component in layouts/default.vue.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ed110056-8b66-4f6a-a85a-110842e706fc

📥 Commits

Reviewing files that changed from the base of the PR and between 5cc34fe and 6bfd081.

📒 Files selected for processing (3)
  • components/layout/navigation/Navbar.vue
  • components/layout/navigation/SidebarWrapper.vue
  • layouts/default.vue

Comment on lines 47 to 50
:class="{
'fixed!': isPostsPage,
'lg:left-64': isPostsPage,
'bg-base-1000/60 shadow-lg backdrop-blur-lg backdrop-saturate-200 md:border-b-2': isPostsPage && !isOnTop
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

De-duplicate the desktop sidebar offset.

Line 49 hard-codes lg:left-64, while layouts/default.vue Line 66 hard-codes the sidebar as w-64. Keeping those values in separate files will silently misalign the posts navbar the next time the sidebar width changes. Consider sourcing both from the same layout token/CSS variable.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/layout/navigation/Navbar.vue` around lines 47 - 50, Navbar.vue
currently hardcodes the desktop offset as 'lg:left-64' when isPostsPage is true,
duplicating the sidebar width defined as 'w-64' in layouts/default.vue; replace
the hard-coded value with a shared token (CSS variable or layout token) so both
the sidebar width and Navbar offset reference the same variable (e.g.,
--sidebar-width) and update the conditional class in Navbar.vue (isPostsPage
branch) to use that variable instead of 'lg:left-64' and ensure
layouts/default.vue uses the same variable for 'w-64' so changes to sidebar
width stay in sync.

Comment on lines +98 to +113
<ClientOnly>
<Toaster
:expand="true"
close-button
position="top-center"
theme="dark"
/>

<DialogManager />
</ClientOnly>

<SidebarWrapper>
<LazySidebar />
</SidebarWrapper>

<Navbar />
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Render fixed overlays above the navbar.

Lines 98-113 place DialogManager and SidebarWrapper before Navbar, but components/layout/navigation/SidebarWrapper.vue Line 29, components/layout/DialogManager.vue Lines 162-209, and components/layout/navigation/Navbar.vue Line 52 all sit at z-10. Because the navbar renders later, it can paint above the drawer/modal backdrop and remain clickable on mobile.

🛠️ Suggested fix
-        <ClientOnly>
-          <Toaster
-            :expand="true"
-            close-button
-            position="top-center"
-            theme="dark"
-          />
-
-          <DialogManager />
-        </ClientOnly>
-
-        <SidebarWrapper>
-          <LazySidebar />
-        </SidebarWrapper>
-
         <Navbar />
+
+        <ClientOnly>
+          <Toaster
+            :expand="true"
+            close-button
+            position="top-center"
+            theme="dark"
+          />
+
+          <DialogManager />
+        </ClientOnly>
+
+        <SidebarWrapper>
+          <LazySidebar />
+        </SidebarWrapper>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<ClientOnly>
<Toaster
:expand="true"
close-button
position="top-center"
theme="dark"
/>
<DialogManager />
</ClientOnly>
<SidebarWrapper>
<LazySidebar />
</SidebarWrapper>
<Navbar />
<Navbar />
<ClientOnly>
<Toaster
:expand="true"
close-button
position="top-center"
theme="dark"
/>
<DialogManager />
</ClientOnly>
<SidebarWrapper>
<LazySidebar />
</SidebarWrapper>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@layouts/default.vue` around lines 98 - 113, The DialogManager and
SidebarWrapper (and Toaster) are rendered before Navbar so Navbar may paint on
top; move the <ClientOnly> block containing <Toaster> and <DialogManager> and
the <SidebarWrapper> (including <LazySidebar>) to render after <Navbar> so the
overlays (DialogManager, SidebarWrapper) are mounted last and sit above Navbar
(alternatively ensure these components set a higher z-index than Navbar),
specifically adjust the order of ClientOnly, DialogManager,
SidebarWrapper/LazySidebar relative to the Navbar component in
layouts/default.vue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant