Skip to content

Conversation

@aditya-mitra
Copy link
Contributor

@aditya-mitra aditya-mitra commented Dec 9, 2025

It is hard to recognize the items by their icons - I often hover over them for a second to know where they will redirect.

Added an expandable sidebar to quickly know where it would be navigating.

feat.mp4

Summary by CodeRabbit

  • New Features
    • Added collapsible project menu with toggle button
    • Menu items display labels when expanded, icons only when collapsed
    • Smooth transitions between expanded and collapsed states

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 9, 2025

Walkthrough

This PR introduces a collapsible menu feature to the ProjectMenu component. The expanded state is managed at the parent level and propagates down to child components via props, enabling menu items to conditionally display text labels and apply responsive styling based on the expansion state.

Changes

Cohort / File(s) Summary
State Management & Toggle Control
webapp/src/views/projects/projectMenu/ProjectMenu.tsx
Added expanded state with useState(false), created StyledToggleButton with ChevronLeft/ChevronRight icon toggling, and passed expanded prop to SideMenu and each SideMenuItem.
Menu Container Styling
webapp/src/views/projects/projectMenu/SideMenu.tsx
Exported MENU_WIDTH_EXPANDED constant, updated SideMenu component to accept expanded prop, and applied conditional width/min-width styling with transition effects based on expansion state.
Menu Item Rendering
webapp/src/views/projects/projectMenu/SideMenuItem.tsx
Added expanded prop to SideMenuItem, adjusted StyledItem layout (padding, alignment, width) dynamically based on expansion, and conditionally rendered text label in a .text span with ellipsis handling when expanded.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

  • Verify that the expanded prop is correctly threaded through all three components
  • Ensure CSS transition effects on SideMenu width/min-width render smoothly without layout shifts
  • Confirm that the text label in SideMenuItem properly truncates and aligns when expanded, and verify the icon-only layout when collapsed is visually balanced

Poem

🐰 A menu that breathes, now open and closed,
With chevrons that dance as the state is composed,
Text labels appear when we expand with delight,
Collapsing back down to keep icons tight,
A tidy expansion—most rabbit-like right! 🎀

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 (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: expandable sidebar' directly summarizes the main change—adding expandable sidebar functionality to the ProjectMenu component with an expansion toggle.
✨ 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.

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 (4)
webapp/src/views/projects/projectMenu/SideMenu.tsx (1)

6-12: Avoid leaking the expanded styling prop to DOM elements

The styling logic and transition behavior look good, but expanded is currently being passed through to the underlying div and menu DOM nodes, which can trigger React “unknown prop” warnings.

Consider filtering it out via shouldForwardProp:

-import { styled } from '@mui/material';
+import { styled } from '@mui/material';

-const StyledMenuWrapper = styled('div')<{ expanded: boolean }>`
+const StyledMenuWrapper = styled('div', {
+  shouldForwardProp: (prop) => prop !== 'expanded',
+})<{ expanded: boolean }>`
   min-width: ${({ expanded }) =>
     expanded ? MENU_WIDTH_EXPANDED : MENU_WIDTH}px;
   transition: min-width 0.2s ease-in-out;
 `;
 
-const StyledMenuFixed = styled('menu')<{ expanded: boolean }>`
+const StyledMenuFixed = styled('menu', {
+  shouldForwardProp: (prop) => prop !== 'expanded',
+})<{ expanded: boolean }>`
   position: fixed;
   ...
   width: ${({ expanded }) => (expanded ? MENU_WIDTH_EXPANDED : MENU_WIDTH)}px;
   ...
 `;

Please double‑check the exact styled API for your MUI version to confirm shouldForwardProp usage.

Also applies to: 14-25

webapp/src/views/projects/projectMenu/SideMenuItem.tsx (1)

52-61: Prop API and rendering for expanded are consistent and backward‑compatible

Making expanded optional with a default of false keeps existing callers working, while still allowing ProjectMenu to control item expansion. The conditional text span inside the Link is a straightforward way to reveal labels without affecting the tooltip behavior.

One follow‑up: when you apply the shouldForwardProp pattern from SideMenu to avoid leaking expanded to the DOM, consider doing the same for StyledItem here.

Please confirm that adding shouldForwardProp for expanded to StyledItem is compatible with your MUI styled helper, similar to:

const StyledItem = styled('li', {
  shouldForwardProp: (prop) => prop !== 'expanded',
})<{ expanded: boolean }>`...`;

Also applies to: 68-76, 104-126

webapp/src/views/projects/projectMenu/ProjectMenu.tsx (2)

30-37: Consider using theme spacing for the toggle button offset

margin-bottom: 70px; works but hard‑codes a magic number. If you want this to be more consistent with the rest of the UI, you could tie it to theme.spacing instead (e.g. theme.spacing(9) or similar).


49-50: Expanded state wiring is clear; add E2E and ARIA hooks to the toggle

The expanded state is cleanly threaded from ProjectMenu into SideMenu and each SideMenuItem, and the chevron toggle logic is straightforward.

Given your guidelines and for accessibility:

  • Add a data-cy attribute to StyledToggleButton so E2E tests can target the control without relying on icon content.
  • Add appropriate ARIA attributes, e.g. aria-label and aria-expanded, so screen readers understand that this button expands/collapses the navigation.

For example:

-      <StyledToggleButton
-        onClick={() => setExpanded((prev) => !prev)}
-        size="small"
-      >
+      <StyledToggleButton
+        onClick={() => setExpanded((prev) => !prev)}
+        size="small"
+        data-cy="project-menu-expand-toggle"
+        aria-label={expanded ? 'Collapse project menu' : 'Expand project menu'}
+        aria-expanded={expanded}
+      >

Also applies to: 173-199

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between df527ba and 5e1fe71.

📒 Files selected for processing (3)
  • webapp/src/views/projects/projectMenu/ProjectMenu.tsx (5 hunks)
  • webapp/src/views/projects/projectMenu/SideMenu.tsx (1 hunks)
  • webapp/src/views/projects/projectMenu/SideMenuItem.tsx (6 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
webapp/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

webapp/**/*.{ts,tsx}: Use TypeScript path aliases (tg.component/, tg.service/, tg.hooks/, tg.views/, tg.globalContext/*) instead of relative imports
After backend API changes, regenerate TypeScript types by running npm run schema (and npm run billing-schema if applicable) in the webapp directory
Use typed React Query hooks from useQueryApi.ts for API communication, not raw React Query
Use Tolgee-specific hooks useReportEvent and useReportOnce from 'tg.hooks/useReportEvent' for business event tracking and analytics

Files:

  • webapp/src/views/projects/projectMenu/SideMenu.tsx
  • webapp/src/views/projects/projectMenu/ProjectMenu.tsx
  • webapp/src/views/projects/projectMenu/SideMenuItem.tsx
webapp/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Always use data-cy attributes for E2E test selectors, never rely on text content

Files:

  • webapp/src/views/projects/projectMenu/SideMenu.tsx
  • webapp/src/views/projects/projectMenu/ProjectMenu.tsx
  • webapp/src/views/projects/projectMenu/SideMenuItem.tsx
**/*.{ts,tsx,js,jsx,kt,kts}

⚙️ CodeRabbit configuration file

As part of review, please check if the file follows 'The Stepdown Rule': The most important, high-level concepts should be at the top (like a newspaper headline and opening paragraph). Details should increase as you read downward. Functions should be ordered so that a caller appears before the functions it calls. When working with JavaScript components, we allow the main component to live at the bottom of the file as an exception to the rule.

Files:

  • webapp/src/views/projects/projectMenu/SideMenu.tsx
  • webapp/src/views/projects/projectMenu/ProjectMenu.tsx
  • webapp/src/views/projects/projectMenu/SideMenuItem.tsx
🧬 Code graph analysis (1)
webapp/src/views/projects/projectMenu/ProjectMenu.tsx (1)
webapp/src/views/projects/projectMenu/SideMenu.tsx (1)
  • SideMenu (27-45)
🔇 Additional comments (2)
webapp/src/views/projects/projectMenu/SideMenuItem.tsx (1)

7-50: Expanded/collapsed item styling is coherent and preserves truncation

The conditional padding, alignment, width, and .text overflow handling nicely support both compact and expanded states while keeping labels ellipsized instead of wrapping. This fits the new sidebar behavior well.

webapp/src/views/projects/projectMenu/SideMenu.tsx (1)

27-44: SideMenu now requires expanded: verify all call sites are updated

The new expanded: boolean prop is cleanly threaded into the layout. Ensure all usages of SideMenu provide the expanded prop, not just ProjectMenu. Check for missing prop warnings during compilation or testing.

@JanCizmar
Copy link
Contributor

Hey Aditya! That's slay! ❤️

@ZuzanaOdstrcilova, what do you think?

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.

2 participants