Skip to content

fix(landing): improve responsive sidebar on smaller screens#126

Open
leno23 wants to merge 2 commits into
SamXop123:mainfrom
leno23:fix/responsive-sidebar-mobile
Open

fix(landing): improve responsive sidebar on smaller screens#126
leno23 wants to merge 2 commits into
SamXop123:mainfrom
leno23:fix/responsive-sidebar-mobile

Conversation

@leno23
Copy link
Copy Markdown
Contributor

@leno23 leno23 commented May 30, 2026

Summary

  • Adds mobile sidebar backdrop overlay with smooth open/close transitions
  • Uses responsive sidebar widths across breakpoints and locks body scroll when open
  • Prevents content overlap by offsetting main layout when sidebar is expanded on small screens

Fixes #24

Test plan

  • Resize to mobile/tablet widths and open sidebar via menu button
  • Verify backdrop click closes sidebar
  • Confirm page content is not hidden behind the sidebar panel
  • Check desktop layout remains unchanged

Made with Cursor

Summary by CodeRabbit

Release Notes

  • New Features
    • Sidebar can now be closed by pressing the Escape key
    • Sidebar automatically closes when selecting a navigation item on mobile devices
    • Page scrolling is disabled when the sidebar is open to prevent background interaction
    • Improved accessibility with enhanced navigation controls and labels

Review Change Stack

leno23 and others added 2 commits May 18, 2026 01:49
Lock body scroll and close on Escape when the drawer is open, cap
sidebar width on narrow viewports, hide the mobile backdrop on lg+,
and fix header overlap with a flex-based navbar layout.

Fixes SamXop123#24
@vercel
Copy link
Copy Markdown

vercel Bot commented May 30, 2026

@SamXop123 is attempting to deploy a commit to the Dot_NotSam's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

📝 Walkthrough

Walkthrough

The PR improves sidebar responsiveness by adding scroll lock, keyboard dismissal, and responsive auto-close behavior. App manages sidebar state with toggleSidebar and a closeSidebar helper, plus an effect that disables page scrolling and registers an Escape key handler. Sidebar receives closeSidebar and wires it to the backdrop and close button, while navigation items trigger closeSidebar on small screens via a conditional handleNavClick.

Changes

Sidebar Responsive Close Behavior

Layer / File(s) Summary
Sidebar state management and scroll lock effect
landing/src/App.jsx
App introduces toggleSidebar state updater and closeSidebar helper, plus a useEffect that disables body scrolling when the sidebar is open and registers an Escape key handler to close it, with proper cleanup.
Sidebar wiring and backdrop behavior
landing/src/App.jsx, landing/src/components/Sidebar.jsx
App passes closeSidebar to Sidebar and updates the header navigation button with aria attributes; Sidebar receives closeSidebar and wires it to the backdrop overlay and close button, adding handleNavClick to conditionally close on small screens (innerWidth < 1024).
Navigation item responsive close behavior
landing/src/components/Sidebar.jsx
Sidebar navigation items are wired to pass onNavigate={handleNavClick} to SidebarItem, and SidebarItem receives and attaches the onNavigate prop to its button onClick, enabling sidebar close on small screens when a nav item is selected.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

A sidebar that closes with grace,
On mobiles and tablets, the perfect place,
Press Escape, click a link, and away,
Responsive magic, each responsive day! 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ 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%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: improving responsive sidebar behavior on smaller screens, which is the primary objective of this pull request.
Linked Issues check ✅ Passed The pull request successfully implements all coding requirements from issue #24: adds responsive sidebar toggle, prevents content overlap via backdrop and body scroll locking, includes smooth animations, and handles mobile-specific close behavior on navigation.
Out of Scope Changes check ✅ Passed All changes are scoped to the sidebar responsive behavior improvements. The modifications to App.jsx and Sidebar.jsx are directly related to sidebar management, navigation handling, and responsive design requirements.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch fix/responsive-sidebar-mobile

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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
Copy Markdown

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@landing/src/components/Sidebar.jsx`:
- Around line 23-31: Replace the current use of aria-hidden on the motion.aside
with the boolean inert prop tied to isSidebarOpen (e.g., inert={!isSidebarOpen})
so the closed sidebar subtree is removed from the accessibility tree and tab
order; remove aria-hidden from the motion.aside and keep role="dialog" and
aria-modal="true". Additionally, implement focus management when the dialog
opens/closes in the same component (motion.aside) by moving focus into the
dialog and trapping focus while isSidebarOpen is true (use a focus-trap utility
or a small hook to save/restore previously focused element and trap
tab/shift+tab inside the dialog). Ensure these changes reference the existing
isSidebarOpen state and motion.aside element so the inert prop and focus-trap
target the same DOM node.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3b31ff3c-9218-464b-b2cf-6ab684ac0c10

📥 Commits

Reviewing files that changed from the base of the PR and between 7e6a9e1 and 54b4142.

📒 Files selected for processing (2)
  • landing/src/App.jsx
  • landing/src/components/Sidebar.jsx

Comment on lines +23 to 31
<motion.aside
initial={false}
animate={{ x: isSidebarOpen ? 0 : "-100%" }}
transition={{ type: "spring", stiffness: 450, damping: 30 }}
className="flex flex-col h-screen lg:w-[22vw] md:w-[40vw] sm:w-[50vw] w-[75vw] fixed top-0 left-0 z-50 bg-[#050816]/95 backdrop-blur-2xl shadow-[10px_0_50px_rgba(0,0,0,0.8)] border-r border-white/[0.08] overflow-hidden"
role="dialog"
aria-modal="true"
aria-hidden={!isSidebarOpen}
className="fixed top-0 left-0 z-50 flex h-screen w-[min(85vw,20rem)] flex-col overflow-hidden border-r border-white/[0.08] bg-[#050816]/95 shadow-[10px_0_50px_rgba(0,0,0,0.8)] backdrop-blur-2xl sm:w-[min(70vw,18rem)] md:w-[min(50vw,16rem)] lg:w-[min(22vw,15rem)]"
>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Does React 19 support rendering the native inert attribute as a boolean prop on DOM elements?

💡 Result:

Yes, React 19 natively supports the inert attribute as a boolean prop [1][2]. In React 19, you can pass a boolean value to the inert prop (e.g.,

) [3][4]. React will correctly handle this as a standard boolean DOM attribute, adding the attribute to the element when the value is true and removing it when the value is false [3][4]. This represents a change from older versions of React, where the inert attribute was not natively supported as a boolean prop, often necessitating workarounds such as using an empty string (inert="") or managing the attribute directly via refs [3][4][5]. Note that in React 19, the legacy workaround of passing an empty string (inert="") is no longer treated as true for boolean props; therefore, you should transition to using standard boolean values [1][4].

Citations:


Fix off-screen sidebar accessibility by swapping aria-hidden for inert.

When the sidebar is closed it remains mounted and still tabbable; aria-hidden on a container with focusable descendants is also flagged by accessibility tooling. In React 19, inert is supported as a boolean prop on DOM elements, so use it to remove the subtree from the tab order/accessibility tree.

♿ Proposed fix using inert
       transition={{ type: "spring", stiffness: 450, damping: 30 }}
       role="dialog"
       aria-modal="true"
-      aria-hidden={!isSidebarOpen}
+      inert={!isSidebarOpen}
       className="fixed top-0 left-0 z-50 flex h-screen w-[min(85vw,20rem)] flex-col overflow-hidden border-r border-white/[0.08] bg-[`#050816`]/95 shadow-[10px_0_50px_rgba(0,0,0,0.8)] backdrop-blur-2xl sm:w-[min(70vw,18rem)] md:w-[min(50vw,16rem)] lg:w-[min(22vw,15rem)]"

Also, role="dialog" + aria-modal="true" implies focus should be moved into the dialog and trapped while open; that focus management isn’t present here.

📝 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
<motion.aside
initial={false}
animate={{ x: isSidebarOpen ? 0 : "-100%" }}
transition={{ type: "spring", stiffness: 450, damping: 30 }}
className="flex flex-col h-screen lg:w-[22vw] md:w-[40vw] sm:w-[50vw] w-[75vw] fixed top-0 left-0 z-50 bg-[#050816]/95 backdrop-blur-2xl shadow-[10px_0_50px_rgba(0,0,0,0.8)] border-r border-white/[0.08] overflow-hidden"
role="dialog"
aria-modal="true"
aria-hidden={!isSidebarOpen}
className="fixed top-0 left-0 z-50 flex h-screen w-[min(85vw,20rem)] flex-col overflow-hidden border-r border-white/[0.08] bg-[#050816]/95 shadow-[10px_0_50px_rgba(0,0,0,0.8)] backdrop-blur-2xl sm:w-[min(70vw,18rem)] md:w-[min(50vw,16rem)] lg:w-[min(22vw,15rem)]"
>
<motion.aside
initial={false}
animate={{ x: isSidebarOpen ? 0 : "-100%" }}
transition={{ type: "spring", stiffness: 450, damping: 30 }}
role="dialog"
aria-modal="true"
inert={!isSidebarOpen}
className="fixed top-0 left-0 z-50 flex h-screen w-[min(85vw,20rem)] flex-col overflow-hidden border-r border-white/[0.08] bg-[`#050816`]/95 shadow-[10px_0_50px_rgba(0,0,0,0.8)] backdrop-blur-2xl sm:w-[min(70vw,18rem)] md:w-[min(50vw,16rem)] lg:w-[min(22vw,15rem)]"
>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@landing/src/components/Sidebar.jsx` around lines 23 - 31, Replace the current
use of aria-hidden on the motion.aside with the boolean inert prop tied to
isSidebarOpen (e.g., inert={!isSidebarOpen}) so the closed sidebar subtree is
removed from the accessibility tree and tab order; remove aria-hidden from the
motion.aside and keep role="dialog" and aria-modal="true". Additionally,
implement focus management when the dialog opens/closes in the same component
(motion.aside) by moving focus into the dialog and trapping focus while
isSidebarOpen is true (use a focus-trap utility or a small hook to save/restore
previously focused element and trap tab/shift+tab inside the dialog). Ensure
these changes reference the existing isSidebarOpen state and motion.aside
element so the inert prop and focus-trap target the same DOM node.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve Responsive Sidebar Behavior on Smaller Screens

2 participants