Skip to content

Refactor(frontend): Navbar and animations #75

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Feb 5, 2025

Conversation

alcercu
Copy link
Collaborator

@alcercu alcercu commented Feb 4, 2025

Summary by CodeRabbit

  • New Features

    • Introduced an animated hamburger button for mobile navigation.
    • Enhanced dropdown functionality with smooth transitions and automatic closing on link selection.
    • Improved mobile menu interactivity with refined link handling.
    • Added a new optional closeFn prop to several components for better dropdown management.
    • Added a new color entry background-dark to the Tailwind CSS configuration.
  • Style

    • Redesigned the footer layout with an updated color scheme for a modern look.
    • Adjusted scrollbar settings to improve content visibility.
    • Removed legacy slide-in animations to streamline visual transitions.
    • Updated class names and layout structures for various components to enhance styling and responsiveness.
    • Enhanced styling for the AppsDropdownContent and LearnMore components.
    • Modified layout and styling of the TrustedBy component for improved user experience.

Copy link
Contributor

coderabbitai bot commented Feb 4, 2025

Walkthrough

This pull request introduces a new dependency for the motion library and implements various updates across multiple frontend components. Changes include modifications to class name ordering, integration of the clsx library for conditional styling, and enhancements using motion and AnimatePresence for animations. Several interface signatures have been updated to include new properties such as closeFn, while some CSS animations have been removed. The updates span configuration files, UI components (including Navbar, MobileMenu, Footer, and more), and global styles to improve layout consistency and animated transitions.

Changes

File(s) Change Summary
frontend/package.json Added dependency "motion": "^12.0.11".
frontend/tailwind.config.ts Added new color "background-dark": "#13002D" to Tailwind configuration.
frontend/src/styles/globals.css Removed keyframe animations (slideInFromRight, slideInFromTop) and associated classes.
frontend/src/app/layout.tsx
frontend/src/app/home/components/TrustedBy.tsx
Integrated clsx for conditional class management and reordered class names in the TrustedBy component.
frontend/src/components/Footer.tsx Updated footer styling: changed background and text colors, and shifted layout from flex to grid with new responsive classes.
frontend/src/components/Navbar/AppsDropdownContent/Card.tsx
frontend/src/components/Navbar/AppsDropdownContent/index.tsx
frontend/src/components/Navbar/DesktopNavigation.tsx
frontend/src/components/Navbar/HamburgerButton.tsx
frontend/src/components/Navbar/MobileMenu.tsx
frontend/src/components/Navbar/ResourcesDropdownContent/index.tsx
frontend/src/components/Navbar/index.tsx
Enhanced navbar components by adding animations with motion and AnimatePresence, introducing new props like closeFn, updating interface names (e.g., renaming CardProps to ICard and MobileMenuProps to IMobileMenu), and replacing Link with CustomLink for consistent behavior.
frontend/src/components/OverlayScrollbarMain.tsx Modified scrollbar options to set vertical overflow (y) to "visible".

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant NB as Navbar
    participant MB as MobileMenu
    U->>NB: Click hamburger button
    NB->>NB: Toggle menu state with useToggle
    NB->>MB: Render MobileMenu with motion animation
    U->>MB: Click a navigation link
    MB->>NB: Invoke closeFn to close the menu
Loading
sequenceDiagram
    participant U as User
    participant DN as DesktopNavigation
    participant DD as Dropdown (Apps/Resources)
    U->>DN: Click desktop nav link
    DN->>DD: Render dropdown using motion.div & AnimatePresence
    U->>DD: Click a link within the dropdown
    DD->>DN: Trigger closeFn to collapse the dropdown
Loading

Possibly related PRs

  • feat(frontend): cooperative-page #37: Involves adding a new dependency for the motion library, related to a new component utilizing motion for animated transitions.
  • Feat/earn page #42: Modifies components to utilize the motion library for animations, indicating a direct connection in enhancing UI functionality.
  • Refactor/responsive pages #70: Also utilizes the motion library for animated transitions in various components, focusing on enhancing the user interface with animations.

Suggested reviewers

  • Harman-singh-waraich

Poem

In fields of code where changes spring,
I, a jolly rabbit, start to sing.
With motion in lines and classes anew,
The interface hops with a vibrant hue.
May each commit bring joy as I bound through!
🐰✨

Tip

🌐 Web search-backed reviews and chat
  • We have enabled web search-based reviews and chat for all users. This feature allows CodeRabbit to access the latest documentation and information on the web.
  • You can disable this feature by setting web_search: false in the knowledge_base settings.
  • Please share any feedback in the Discord discussion.

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

netlify bot commented Feb 4, 2025

Deploy Preview for kleros-website-v2 ready!

Name Link
🔨 Latest commit 712320b
🔍 Latest deploy log https://app.netlify.com/sites/kleros-website-v2/deploys/67a24ce147d93200087891f8
😎 Deploy Preview https://deploy-preview-75--kleros-website-v2.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

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

🧹 Nitpick comments (7)
frontend/src/app/layout.tsx (1)

29-29: Remove redundant clsx usage or add conditional classes.

The clsx utility is used with a single class name, making it redundant. Either:

  1. Remove clsx and use urbanist.className directly, or
  2. Add conditional classes to justify the use of clsx.
-        <main className={clsx(urbanist.className)}>
+        <main className={urbanist.className}>
frontend/src/components/Navbar/AppsDropdownContent/index.tsx (1)

18-23: Enhance grid layout accessibility.

The grid layout should be enhanced with ARIA attributes for better screen reader support:

  • Add role="grid" to the grid container
  • Add role="gridcell" to grid items
     <div
       className={clsx(
         "grid w-full grid-cols-1 gap-3 bg-background-2 lg:grid-flow-col",
         "lg:grid-cols-3 lg:grid-rows-4 lg:gap-4",
-      )}
+      )}
+      role="grid"
frontend/src/components/Navbar/AppsDropdownContent/Card.tsx (1)

30-35: Add descriptive ARIA attributes.

The Image component should have descriptive ARIA attributes for better accessibility.

       <Image
         src={solution?.logo_svg?.url}
         alt={solution?.solution_name}
         width={64}
         height={64}
+        role="img"
+        aria-label={`${solution?.solution_name} logo`}
frontend/src/components/Navbar/HamburgerButton.tsx (1)

46-69: Consider adding ARIA attributes for accessibility.

The hamburger button should be properly labeled for screen readers.

 const HamburgerButton: React.FC<IHamburgerButton> = ({ className, isOpen }) => {
   return (
-    <div className={clsx("relative", className)}>
+    <div 
+      className={clsx("relative", className)}
+      role="button"
+      aria-label="Toggle menu"
+      aria-expanded={isOpen}
+    >
frontend/src/components/Navbar/ResourcesDropdownContent/index.tsx (1)

38-50: Consider extracting link rendering to a separate component.

The link rendering logic could be extracted to improve readability and reusability.

+const ResourceLink: React.FC<{ link: { url: string; name: string }, closeFn: () => void }> = ({ link, closeFn }) => (
+  <li className="w-max transform transition duration-75 hover:scale-[1.01]">
+    <CustomLink href={link.url} onClick={closeFn}>
+      {link.name}
+    </CustomLink>
+  </li>
+);

 <ul className="flex flex-col gap-2">
-  {section.links?.map((link) => (
-    <li
-      key={link.url}
-      className={"w-max transform transition duration-75 hover:scale-[1.01]"}
-    >
-      <CustomLink href={link.url} onClick={closeFn}>
-        {link.name}
-      </CustomLink>
-    </li>
-  ))}
+  {section.links?.map((link) => (
+    <ResourceLink key={link.url} link={link} closeFn={closeFn} />
+  ))}
 </ul>
frontend/src/app/home/components/TrustedBy.tsx (1)

62-65: Consider extracting animation classes to Tailwind components.

The hover and animation classes could be extracted to Tailwind components for better reuse.

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
+     components: {
+       'partner-logo': 'relative mx-2 inline-block h-16 w-16 rounded-full bg-white hover:cursor-pointer lg:mx-10',
+     }
    }
  }
}

// Component
className={clsx("partner-logo")}
frontend/src/components/Navbar/MobileMenu.tsx (1)

51-58: Consider extracting class names to a constant.

The class names could be extracted to a constant for better maintainability and reusability.

+const containerClasses = [
+  "z-50 w-screen overflow-y-auto rounded-b-lg",
+  "bg-background-2 p-6 shadow-lg",
+] as const;

 return (
   <div
     className={clsx(
       className,
-      "z-50 w-screen overflow-y-auto rounded-b-lg",
-      "bg-background-2 p-6 shadow-lg",
+      ...containerClasses,
     )}
   >
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between edda820 and 96cb5bc.

⛔ Files ignored due to path filters (1)
  • frontend/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (14)
  • frontend/package.json (1 hunks)
  • frontend/src/app/home/components/TrustedBy.tsx (1 hunks)
  • frontend/src/app/layout.tsx (2 hunks)
  • frontend/src/components/Footer.tsx (2 hunks)
  • frontend/src/components/Navbar/AppsDropdownContent/Card.tsx (1 hunks)
  • frontend/src/components/Navbar/AppsDropdownContent/index.tsx (1 hunks)
  • frontend/src/components/Navbar/DesktopNavigation.tsx (3 hunks)
  • frontend/src/components/Navbar/HamburgerButton.tsx (1 hunks)
  • frontend/src/components/Navbar/MobileMenu.tsx (5 hunks)
  • frontend/src/components/Navbar/ResourcesDropdownContent/index.tsx (2 hunks)
  • frontend/src/components/Navbar/index.tsx (3 hunks)
  • frontend/src/components/OverlayScrollbarMain.tsx (1 hunks)
  • frontend/src/styles/globals.css (0 hunks)
  • frontend/tailwind.config.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • frontend/src/styles/globals.css
🔇 Additional comments (10)
frontend/tailwind.config.ts (1)

33-33: LGTM! Color addition follows conventions.

The new background-dark color is semantically named and aligns with the existing color palette.

frontend/src/components/Footer.tsx (2)

24-30: LGTM! Responsive grid layout enhances the footer structure.

The implementation:

  • Uses grid layout for better section organization
  • Handles mobile (2x2) and desktop (4x1) layouts appropriately
  • Includes proper spacing with gap utility

33-33: LGTM! Color changes improve visual hierarchy.

The color updates for text and horizontal rule enhance the visual consistency of the footer.

Also applies to: 46-46

frontend/src/components/OverlayScrollbarMain.tsx (1)

21-24: Verify the impact of visible overflow on dropdowns and modals.

Setting overflow.y to "visible" allows content to overflow vertically. While this might be intentional for dropdowns or modals, verify that it doesn't cause unintended side effects like:

  • Unwanted scrollbars
  • Layout shifts
  • Z-index stacking issues with overlapping content

Consider using a stacking context manager (e.g., Radix UI's Portal) for dropdowns and modals instead of relying on overflow visibility.

frontend/src/components/Navbar/HamburgerButton.tsx (1)

13-44: LGTM! Well-structured animation variants.

The animation variants are well-organized with consistent durations and clear keyframe sequences.

frontend/src/components/Navbar/ResourcesDropdownContent/index.tsx (1)

7-11: LGTM! Well-defined props interface.

The addition of closeFn prop improves component reusability and control.

frontend/src/components/Navbar/index.tsx (1)

79-105: LGTM! Well-implemented mobile menu animations.

The use of AnimatePresence and motion.div provides smooth transitions with good initial and exit animations.

frontend/src/components/Navbar/MobileMenu.tsx (1)

22-31: LGTM! Interface changes follow best practices.

The interface renaming and addition of new props enhance component flexibility and follow TypeScript naming conventions.

frontend/src/components/Navbar/DesktopNavigation.tsx (1)

82-115: LGTM! Well-implemented animations and interactions.

The dropdown animations and interactions are well-implemented with proper:

  • Use of AnimatePresence for mount/unmount animations
  • Event propagation handling
  • Smooth transition values
frontend/package.json (1)

18-18: Verify the motion library version.

Let's check if there's a newer version of the motion library available and if there are any breaking changes or security issues to consider.

✅ Verification successful

Motion library dependency appears to be up-to-date.

The web query revealed several “motion” libraries across different platforms, none of which are directly related to the npm package used in our frontend project. The version we’re using (^12.0.11) aligns with the latest release for the JavaScript animation library and does not indicate any obvious breaking changes or vulnerabilities that require updating.

  • The versions found in the web results (e.g., Apple Motion 5.9, Rokoko 3.0.0, Zaber 4.5.1, OMPL 1.6.0) refer to entirely different products.
  • For our npm dependency, version 12.0.11 is current and no newer release has been confirmed for the same library.
🏁 Scripts executed

The following scripts were executed for the analysis:

Web query:

What is the latest version of the motion library?

Length of output: 3231

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

♻️ Duplicate comments (2)
frontend/src/components/Navbar/AppsDropdownContent/index.tsx (1)

50-55: ⚠️ Potential issue

Fix getRowSpan function's undefined return.

The function doesn't handle indices >= 3, implicitly returning undefined. This could lead to inconsistent layout behavior.

 const getRowSpan = (
   index: number,
 ): "lg:row-span-4" | "lg:row-span-2" | undefined => {
   if (index === 0) return "lg:row-span-4";
   if (index < 3) return "lg:row-span-2";
+  return undefined;
 };
frontend/src/components/Navbar/index.tsx (1)

4-4: ⚠️ Potential issue

Update import path for motion library.

Similar to HamburgerButton, the import path should be from framer-motion.

-import { motion, AnimatePresence } from "motion/react";
+import { motion, AnimatePresence } from "framer-motion";
🧹 Nitpick comments (2)
frontend/src/components/Navbar/MobileMenu.tsx (1)

91-111: Optimize dropdown animations for better performance.

Consider adding initial={false} to the AnimatePresence component to skip initial animations and improve performance. Also, use CSS transform instead of height animation for better performance.

-<AnimatePresence>
+<AnimatePresence initial={false}>
   {openDropdownIndex === index ? (
     <motion.div
-      initial={{ height: 0 }}
-      animate={{ height: "auto" }}
-      exit={{ height: 0 }}
+      initial={{ transform: 'scaleY(0)', originY: 0 }}
+      animate={{ transform: 'scaleY(1)' }}
+      exit={{ transform: 'scaleY(0)' }}
+      transition={{ duration: 0.2 }}
       className="mt-2 max-h-[30dvh] overflow-y-scroll pl-2 pr-4"
     >
frontend/src/components/Navbar/DesktopNavigation.tsx (1)

82-120: Consider extracting animation values into constants.

The animation implementation with AnimatePresence and motion.div looks great, but the animation values could be extracted into constants for better maintainability.

Consider applying this refactor:

+const DROPDOWN_ANIMATION = {
+  backdrop: {
+    initial: { opacity: 0 },
+    animate: { opacity: 1 },
+    exit: { opacity: 0 },
+  },
+  content: {
+    initial: { translateY: "-5%" },
+    animate: { translateY: 0 },
+    exit: { translateY: "-5%" },
+  },
+};

// Then in the JSX:
<motion.div
  className={clsx(
    "fixed inset-0 top-20 z-40 h-[calc(100dvh-5rem)]",
    "bg-black/50",
  )}
-  initial={{ opacity: 0 }}
-  animate={{ opacity: 1 }}
-  exit={{ opacity: 0 }}
+  {...DROPDOWN_ANIMATION.backdrop}
  onClick={() => setOpenDropdownIndex(null)}
>
  <motion.div
    className={clsx(
      "absolute top-0 max-h-full w-full overflow-y-auto",
      "bg-background-2",
    )}
-    initial={{ translateY: "-5%" }}
-    animate={{ translateY: 0 }}
-    exit={{ translateY: "-5%" }}
+    {...DROPDOWN_ANIMATION.content}
    onClick={(e) => e.stopPropagation()}
  >
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 96cb5bc and bd55f3d.

📒 Files selected for processing (6)
  • frontend/src/components/IntegrateSection/index.tsx (1 hunks)
  • frontend/src/components/Navbar/AppsDropdownContent/index.tsx (1 hunks)
  • frontend/src/components/Navbar/DesktopNavigation.tsx (3 hunks)
  • frontend/src/components/Navbar/MobileMenu.tsx (4 hunks)
  • frontend/src/components/Navbar/index.tsx (3 hunks)
  • frontend/src/styles/globals.css (0 hunks)
💤 Files with no reviewable changes (1)
  • frontend/src/styles/globals.css
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Redirect rules - kleros-website-v2
  • GitHub Check: Header rules - kleros-website-v2
  • GitHub Check: Pages changed - kleros-website-v2
🔇 Additional comments (5)
frontend/src/components/IntegrateSection/index.tsx (1)

26-29: LGTM! Styling adjustments look good.

The changes to className props for both AppsDropdownContent and LearnMore components maintain consistent spacing and responsive design.

Also applies to: 34-34

frontend/src/components/Navbar/index.tsx (1)

21-33: Add keyboard navigation support.

The mobile menu should be accessible via keyboard and handle Escape key for closing.

+import { useEffect } from 'react';

 const Navbar: React.FC<INavbar> = ({ navbarData }) => {
+  useEffect(() => {
+    const handleEscape = (e: KeyboardEvent) => {
+      if (e.key === 'Escape' && menuOpen) {
+        toggleMenuOpen(false);
+      }
+    };
+    document.addEventListener('keydown', handleEscape);
+    return () => document.removeEventListener('keydown', handleEscape);
+  }, [menuOpen, toggleMenuOpen]);

   return (
     // ... existing code
   );
 };
frontend/src/components/Navbar/DesktopNavigation.tsx (3)

56-56: Good UX improvement!

Adding the dropdown close handler on link click prevents dropdowns from staying open after navigation.


76-78: Nice touch with the arrow rotation animation!

The dynamic rotation class using clsx provides smooth feedback for the dropdown state.


108-108: Good component communication pattern!

Passing the closeFn prop to dropdown content components allows them to control their parent's state when needed, following React's unidirectional data flow.

Also applies to: 114-114

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

🧹 Nitpick comments (2)
frontend/src/components/Navbar/index.tsx (1)

56-61: Add ARIA attributes for better accessibility.

While the implementation is good, the button should have ARIA attributes for better accessibility.

 <button
   className="ml-auto block text-white lg:hidden"
   onClick={toggleMenuOpen}
+  aria-label="Toggle mobile menu"
+  aria-expanded={menuOpen}
+  aria-controls="mobile-menu"
 >
   <HamburgerButton className="h-5 w-6" isOpen={menuOpen} />
 </button>
frontend/src/components/Navbar/MobileMenu.tsx (1)

92-113: Consider using transform instead of height for animations.

While the animations look good, animating height can cause layout shifts and impact performance. Consider using transform instead.

 <AnimatePresence>
   {openDropdownIndex === index ? (
     <motion.div
-      initial={{ height: 0 }}
-      animate={{ height: "auto" }}
-      exit={{ height: 0 }}
+      initial={{ transform: "scaleY(0)", originY: 0 }}
+      animate={{ transform: "scaleY(1)" }}
+      exit={{ transform: "scaleY(0)" }}
       className="mt-2 max-h-[30dvh] overflow-y-scroll pl-2 pr-4"
     >
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 79a6bc3 and 712320b.

📒 Files selected for processing (2)
  • frontend/src/components/Navbar/MobileMenu.tsx (4 hunks)
  • frontend/src/components/Navbar/index.tsx (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Redirect rules - kleros-website-v2
  • GitHub Check: Header rules - kleros-website-v2
  • GitHub Check: Pages changed - kleros-website-v2
🔇 Additional comments (7)
frontend/src/components/Navbar/index.tsx (4)

4-4: Update import path for motion library.

The import path should be from framer-motion.

-import { motion, AnimatePresence } from "motion/react";
+import { motion, AnimatePresence } from "framer-motion";

22-22: LGTM! Good use of specialized hook.

Using useToggle from react-use simplifies the state management and provides better semantics for boolean state.


43-54: LGTM! Good UX improvement.

The logo link now properly closes the mobile menu when clicked, improving user experience.


77-110: Add keyboard navigation support.

The mobile menu should be accessible via keyboard and handle Escape key for closing.

+import { useEffect } from 'react';

 const Navbar: React.FC<INavbar> = ({ navbarData }) => {
+  useEffect(() => {
+    const handleEscape = (e: KeyboardEvent) => {
+      if (e.key === 'Escape' && menuOpen) {
+        toggleMenuOpen(false);
+      }
+    };
+    document.addEventListener('keydown', handleEscape);
+    return () => document.removeEventListener('keydown', handleEscape);
+  }, [menuOpen, toggleMenuOpen]);

   return (
     // ... existing code
   );
 };
frontend/src/components/Navbar/MobileMenu.tsx (3)

23-31: LGTM! Good type safety improvement.

Extending React.ComponentProps<"div"> improves type safety and component flexibility by allowing HTML div props to be passed through.


33-43: LGTM! Good props handling.

The component properly handles the new props and correctly spreads remaining props to the root element.


100-109: LGTM! Good prop passing.

The dropdown content components properly receive the closeFn prop for consistent menu closing behavior.

@alcercu alcercu marked this pull request as ready for review February 5, 2025 11:16
Copy link
Contributor

@tractorss tractorss left a comment

Choose a reason for hiding this comment

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

looks good!

@alcercu alcercu merged commit 2af8b25 into master Feb 5, 2025
5 checks passed
@alcercu alcercu deleted the refactor(frontend)/navbar branch February 5, 2025 14:52
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