8000 765-fix: Fix styles active menu item by JuliaAnt · Pull Request #814 · rolling-scopes/site · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

765-fix: Fix styles active menu item #814

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

Open
wants to merge 25 commits into
base: main
Choose a base branch
from

Conversation

JuliaAnt
Copy link
Collaborator
@JuliaAnt JuliaAnt commented Mar 12, 2025

What type of PR is this? (select all that apply)

  • 🍕 Feature
  • 🐛 Bug Fix
  • 🚧 Breaking Change
  • 🧑‍💻 Code Refactor
  • 📝 Documentation Update

Description

Rework desktop and mobile menus according to the new design.

Related Tickets & Documents

Screenshots, Recordings

Before:

Screenshot 2025-04-12 at 23 03 28

After:

Screenshot 2025-04-12 at 23 04 21

Added/updated tests?

  • 👌 Yes
  • 🙅‍♂️ No, because they aren't needed
  • 🙋‍♂️ No, because I need help

[optional] Are there any post deployment tasks we need to perform?

[optional] What gif best describes this PR or how it makes you feel?

Feel free to hit me with your best practices :))

so-little-work-i-done

Summary by CodeRabbit

  • New Features

    • Added interactive, collapsible navigation menus for both desktop and mobile, including new "Support Us" and "Mentors Wanted" sections.
    • Introduced a "small" font size variant for paragraphs and enhanced breadcrumb and logo components with new customization options.
    • Added a custom hook for detecting outside clicks and improved keyboard accessibility in navigation.
  • Improvements

    • Redesigned header and navigation for a more consistent, accessible, and visually appealing experience.
    • Enhanced menu layouts with grid and column support, improved dropdown transitions, and responsive styling.
    • Updated donation options with clearer labels and icons, and expanded color palette for improved UI consistency.
  • Bug Fixes

    • Improved accessibility and keyboard navigation throughout navigation components.
    • Fixed test coverage and expectations to align with updated navigation structure and UI.
  • Chores

    • Refactored and streamlined code for better maintainability, including removal of unused features and improved state management.

@JuliaAnt JuliaAnt self-assigned this Mar 12, 2025
@github-actions github-actions bot changed the title fix: 765 - change style of active menu item. Fix lighthouse problem 765-fix: Fix styles active menu item Mar 12, 2025
@SpaNb4
Copy link
Collaborator
SpaNb4 commented Mar 13, 2025

The arrow's focus state could be improved
image

This isn't due to your changes, but the spacing is inconsistent here
image

Copy link

Lighthouse Report:

  • Performance: 97 / 100
  • Accessibility: 96 / 100
  • Best Practices: 100 / 100
  • SEO: 100 / 100

View detailed report

Copy link
Collaborator
@SpaNb4 SpaNb4 left a comment

Choose a reason for hiding this comment

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

Keyboard navigation of submenus seems broken to me. First Enter/Space press redirects the page, second opens the menu

2025-03-15.12-16-29.mp4

Copy link
Collaborator
@ansivgit ansivgit left a comment

Choose a reason for hiding this comment

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

image

For a non-yellow background of the hero-banner, the underline blends in with the image. Also, I think the current page should be highlighted.

setDropdownOpen((prev) => !prev);
}
};

const handleEscKeyPress = (e: KeyboardEvent<HTMLElement>) => {
if (e.code === 'Escape') {
Copy link
Collaborator
@ansivgit ansivgit Mar 18, 2025

Choose a reason for hiding this comment

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

Let's all keys' codes move to constant like KEY_CODES = {ESCAPE: 'Escape', .....} You could add it here src/core/const/index.ts

@YulikK YulikK changed the title 765-fix: Fix styles active menu item DRAFT - 765-fix: Fix styles active menu item Mar 18, 2025
Copy link

Lighthouse Report:

  • Performance: 96 / 100
  • Accessibility: 96 / 100
  • Best Practices: 100 / 100
  • SEO: 100 / 100

View detailed report

@SpaNb4
Copy link
Collaborator
SpaNb4 commented May 14, 2025

@JuliaAnt, please check the keyboard navigation. It seems like this functionality is no longer working

import classNames from 'classnames/bind';
import { usePathname } from 'next/navigation';

import { BurgerMenu } from './ui/burger/burger';
import { donateOptionsForNavMenu } from '../../../dev-data/donate-options.data';
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please add donateOptionsForNavMenu to file dev-data/index.ts
And update import:
import { donateOptionsForNavMenu } from 'data';

Comment on lines 79 to 88
opacity: 0;
}

&.visible {
@extend %transition-all;

max-height: 624px;
margin-top: 26px;
visibility: visible;
opacity: 1;
Copy link
Collaborator

Choose a reason for hiding this comment

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

please use constant for opacity
$opacity-100, $opacity-0

Copy link

Lighthouse Report:

  • Performance: 79 / 100
  • Accessibility: 96 / 100
  • Best Practices: 100 / 100
  • SEO: 100 / 100

View detailed report

Copy link

Lighthouse Report:

  • Performance: 99 / 100
  • Accessibility: 96 / 100
  • Best Practices: 100 / 100
  • SEO: 100 / 100

View detailed report

Copy link

Lighthouse Report:

  • Performance: 88 / 100
  • Accessibility: 96 / 100
  • Best Practices: 100 / 100
  • SEO: 100 / 100

View detailed report

Copy link

Lighthouse Report:

  • Performance: 76 / 100
  • Accessibility: 96 / 100
  • Best Practices: 100 / 100
  • SEO: 100 / 100

View detailed report

@SpaNb4 SpaNb4 marked this pull request as ready for review May 27, 2025 10:10
@SpaNb4
Copy link
Collaborator
SpaNb4 commented May 27, 2025

Noticed some issue with the new ai course
image

Copy link
Contributor
coderabbitai bot commented May 27, 2025
📝 Walkthrough

Walkthrough

This update refactors navigation menus and related UI components. It introduces new menu layouts, improves accessibility and keyboard interaction, adds new color variables and mixins, updates donation data structures, and enhances test coverage. Several components receive new props or styling, and menu logic shifts to a click-to-open model with improved active state visuals.

Changes

Files/Groups Change Summary
dev-data/donate-options.data.ts, src/widgets/support/ui/support.tsx Donation options restructured: split labels and icons for button/menu, replaced string icons with React/SVG imports.
dev-data/school-menu-links.ts Added "Support Us" and "Mentors Wanted" links; renamed "About" to "About Community".
src/core/styles/_constants.scss, src/core/styles/_mixins.scss Added new gray color variables and a media query mixin.
src/shared/constants.ts Expanded key codes and added navigation menu labels constant.
src/shared/hooks/use-outside-click/use-outside-click.ts New hook for handling outside clicks.
src/shared/ui/logo/logo.module.scss, src/shared/ui/logo/logo.tsx Logo size adjusted; logo component now accepts a dynamic icon prop.
src/shared/ui/paragraph/paragraph.module.scss, src/shared/ui/paragraph/paragraph.tsx Added "small" font size variant and related styles.
src/widgets/breadcrumbs/ui/breadcrumbs.module.scss, src/widgets/breadcrumbs/ui/breadcrumbs.tsx Breadcrumbs component accepts className prop; added responsive styles.
src/widgets/footer/footer.test.tsx Added navigation mock and minor formatting in tests.
src/widgets/header/header.module.scss Navbar height, colors, and menu gap updated; introduced support text style.
src/widgets/header/header.test.tsx Updated tests for menu arrows, link selectors, and mocks; removed scroll color test.
src/widgets/header/header.tsx Refactored to static header color; reorganized menus; improved support and mentorship menu logic.
src/widgets/header/ui/dropdown/dropdown-wrapper.module.scss, src/widgets/header/ui/dropdown/dropdown-wrapper.tsx Dropdown uses grid layout, reverse layout prop, and removes mouse event handlers.
src/widgets/header/ui/nav-item/nav-item.module.scss, src/widgets/header/ui/nav-item/nav-item.tsx Refactored NavItem: button-based, icon/reverseLayout props, improved active state, keyboard/accessibility, and dropdown logic.
src/widgets/mobile-view/ui/mobile-nav-item/mobile-nav-item.module.scss, src/widgets/mobile-view/ui/mobile-nav-item/mobile-nav-item.tsx New MobileNavItem component and styles for mobile navigation.
src/widgets/mobile-view/ui/mobile-view.module.scss, src/widgets/mobile-view/ui/mobile-view.tsx MobileView refactored to dynamic, collapsible menu using MobileNavItem; improved state and icon logic.
src/widgets/school-menu/ui/school-item/school-item.module.scss, src/widgets/school-menu/ui/school-item/school-item.tsx SchoolItem: conditional styling for clickable/non-clickable, improved accessibility.
src/widgets/school-menu/ui/school-menu/school-menu.module.scss, src/widgets/school-menu/ui/school-menu/school-menu.tsx, src/widgets/school-menu/ui/school-menu/school-menu.test.tsx SchoolMenu: new layout/visibility props, grid/flex layouts, show/hide transitions, updated tests.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant NavItem
    participant DropdownWrapper
    participant useOutsideClick
    participant Router

    User->>NavItem: Clicks menu button
    NavItem->>NavItem: Toggle dropdown state
    NavItem->>DropdownWrapper: Render dropdown (isOpen)
    NavItem->>useOutsideClick: Listen for outside clicks
    useOutsideClick-->>NavItem: On outside click, close dropdown
    User->>NavItem: Presses Enter/Space/Escape
    NavItem->>NavItem: Handle keyboard navigation
    NavItem->>Router: Navigate if not dropdown
Loading

Assessment against linked issues

Objective (Issue #) Addressed Explanation
Make active menu item text readable and update arrow accessibility (#765)
Change desktop menu to open only on click, not hover (#660)

Possibly related PRs

Suggested labels

refactor

Suggested reviewers

  • andron13
  • dzmitry-varabei
  • ansivgit
  • natanchik
  • Quiddlee

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.

npm warn config production Use --omit=dev instead.
npm error Exit handler never called!
npm error This is an error with npm itself. Please report this error at:
npm error https://github.com/npm/cli/issues
npm error A complete log of this run can be found in: /.npm/_logs/2025-05-27T10_12_00_441Z-debug-0.log

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @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 anywhere in the PR title to generate the title automatically.

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

🔭 Outside diff range comments (1)
src/widgets/header/header.module.scss (1)

91-100: 💡 Verification agent

🧩 Analysis chain

Verify mobile menu opacity transition consistency.

The opacity transitions should align with the mobile menu open/close behavior. Ensure the opacity values work correctly with the transform animations.


🏁 Script executed:

#!/bin/bash
# Description: Check mobile menu interaction patterns and transition consistency
# Expected: Find mobile menu state management and transition usage

rg -A 5 -B 5 'mobile.*menu.*open\|\.open.*mobile' src/widgets/
ast-grep --pattern 'className={$$$mobile$$$}'

Length of output: 112


🏁 Script executed:

#!/bin/bash
# Show SCSS context around .mobile-menu rules
rg -n -C5 '\.mobile-menu' src/widgets/header/header.module.scss

# Find where the mobile-menu class is toggled in the React component
rg -n -C3 'mobile-menu' src/widgets/header

Length of output: 3036


Fix mobile menu display and opacity transitions

The .mobile-menu.open rule currently sets display: none, which prevents any transform or opacity animation from ever showing. To allow a smooth reveal:

• In src/widgets/header/header.module.scss (around lines 70–100):
– Remove or override display: none in the open state (e.g. use display: block).
– Ensure the closed state has opacity: 0 and the open state has opacity: 1.
– Add an opacity transition alongside the transform.

Suggested update:

 .mobile-menu {
-  transform: translateY(-100%);
+  transform: translateY(-100%);
+  opacity: 0;
+  display: none;
+  transition: transform 0.4s ease-out, opacity 0.4s ease-out;
 }

 .mobile-menu.open {
-  transform: translateY(0);
-  display: none;
-  opacity: 1;
+  transform: translateY(0);
+  opacity: 1;
+  display: block;
 }
♻️ Duplicate comments (9)
src/widgets/mobile-view/ui/mobile-nav-item/mobile-nav-item.tsx (1)

29-35: Fix hardcoded alt text for dynamic icon usage.

The alt text is hardcoded as "Donate-icon" but should be dynamic based on the icon being displayed, as previously suggested.

Apply this fix to make the alt text contextual:

-            alt="Donate-icon"
+            alt={`${title} icon`}
src/widgets/mobile-view/ui/mobile-view.module.scss (2)

4-12: Remove default flex value and consider past feedback.

The align-items: flex-end should be sufficient here without explicitly setting the default flex-start behavior mentioned in past comments.


47-57: Use color constants for border colors.

The divider implementations use hard-coded color variables that should leverage existing constants as suggested in past feedback.

src/widgets/header/header.tsx (3)

8-8: Import path needs update

The import path for donateOptions should be from the data barrel export.


49-49: Previous suggestion addressed

The removal of dynamic class names addresses the earlier suggestion about removing the white-class when only one color is used.


155-155: Consider component decomposition

The Header component has grown significantly with the addition of the Support Us menu. Consider splitting each NavItem into separate components as previously suggested.

src/widgets/mobile-view/ui/mobile-view.tsx (2)

10-10: Import path needs update

The import path for donateOptions should be from the data barrel export.


242-242: Component has grown significantly

As suggested previously, consider splitting this large component into smaller, more manageable pieces. Each menu section could be its own component.

src/widgets/header/ui/nav-item/nav-item.module.scss (1)

115-115: Consider using color constant

The hover color $color-gray-450 should be defined as a constant as previously suggested.

🧹 Nitpick comments (10)
src/shared/ui/logo/logo.module.scss (2)

3-4: Consistent logo sizing across breakpoints
Default logo dimensions are now 48px but identical values are repeated in the media‐tablet‐large block. Consider extracting these into a variable or removing the redundant declarations to adhere to DRY principles.


12-13: Redundant declarations
The width and height here mirror the default styles. Unless future breakpoints require different sizing, you can safely remove these rules.

src/shared/hooks/use-outside-click/use-outside-click.ts (1)

3-7: Consider using useCallback for the callback parameter.

The hook works correctly, but including the callback in the dependency array could cause unnecessary re-renders if it's not memoized in consuming components.

Consider documenting that the callback should be wrapped with useCallback:

+/**
+ * Hook to detect clicks outside a referenced element
+ * @param ref - Reference to the element
+ * @param callback - Function to call on outside click (should be memoized with useCallback)
+ * @param isDropdownOpen - Whether the dropdown is currently open
+ */
 export function useOutsideClick<T extends HTMLElement>(
src/widgets/breadcrumbs/ui/breadcrumbs.module.scss (1)

37-43: Simplify padding declarations.

The mobile breadcrumb styles look good, but the padding can be streamlined.

 .mobile-breadcrumbs.breadcrumbs-content {
   @include media-tablet-large {
     width: 100%;
-    padding: 6px;
-    padding-left: 0;
+    padding: 6px 6px 6px 0;
   }
 }
src/widgets/school-menu/ui/school-item/school-item.tsx (2)

28-28: Consider using a more explicit check for non-clickable URLs.

The Boolean(url === '#') could be simplified to just url === '#' since the comparison already returns a boolean.

-  const isNonClickable = Boolean(url === '#');
+  const isNonClickable = url === '#';

31-31: Potential className conflict issue.

Using cx(props.className) may not properly merge class names if props.className contains multiple classes. Consider using cx(props.className) only if it's a single class, or handle multiple classes appropriately.

-    <li {...props} className={cx(props.className)}>
+    <li {...props} className={cx(props.className)}>

Actually, this should work correctly since cx() can handle multiple class names. The current implementation looks fine.

src/widgets/mobile-view/ui/mobile-nav-item/mobile-nav-item.tsx (1)

39-45: Remove redundant role attribute.

The role="button" is redundant since the dropdown arrow is already contained within a <button> element.

       <span
         className={cx('dropdown-arrow', { rotate: isDropdownActive })}
-        role="button"
         aria-expanded={isDropdownActive}
       >
src/widgets/mobile-view/ui/mobile-view.tsx (1)

216-228: Consider alternative approach for non-interactive items

The descriptive text items use url="#" which creates non-functional links. Consider using a different component or prop to indicate these are informational items only.

-            <SchoolMenu.Item
-              className="support-title"
-              title="Your donations help us cover hosting, domains, licenses, and advertising for courses
-                          and events. Every donation, big or small, helps!"
-              url="#"
-              color={color}
-            />
+            <SchoolMenu.InfoItem
+              className="support-title"
+              title="Your donations help us cover hosting, domains, licenses, and advertising for courses
+                          and events. Every donation, big or small, helps!"
+              color={color}
+            />
src/widgets/header/ui/dropdown/dropdown-wrapper.module.scss (1)

55-68: Consider the visual impact of the decorative element

The white ::before element might not be visible against light backgrounds. Consider if this provides the intended visual effect in all scenarios.

src/widgets/header/ui/nav-item/nav-item.tsx (1)

127-130: Consider moving aria-expanded to the parent button

The aria-expanded attribute on a non-interactive span might be confusing. Consider moving it to the parent button element for better accessibility semantics.

-        {isDropdown && (
-          <span className={cx('dropdown-arrow')} role="button" aria-expanded={isDropdownOpen}>
-            <DropdownArrow />
-          </span>
-        )}
-      </button>
+        aria-expanded={isDropdown ? isDropdownOpen : undefined}
+      >
+        {icon && (
+          <Image
+            src={icon}
+            alt={`${label} icon`}
+            width={18}
+            height={16}
+            aria-hidden="true"
+            data-testid="nav-item-icon"
+          />
+        )}
+        <span className={cx('label-bold')}>
+          {label}
+          <span className={cx('label-content')} aria-hidden="true">
+            {label}
+          </span>
+        </span>
+        {isDropdown && (
+          <span className={cx('dropdown-arrow')} aria-hidden="true">
+            <DropdownArrow />
+          </span>
+        )}
+      </button>
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c513d17 and c7093fa.

⛔ Files ignored due to path filters (3)
  • src/shared/assets/svg/heart-blue.svg is excluded by !**/*.svg
  • src/shared/assets/svg/heart-yellow.svg is excluded by !**/*.svg
  • src/shared/assets/svg/rss-logo-blue.svg is excluded by !**/*.svg
📒 Files selected for processing (30)
  • dev-data/donate-options.data.ts (1 hunks)
  • dev-data/school-menu-links.ts (1 hunks)
  • src/core/styles/_constants.scss (1 hunks)
  • src/core/styles/_mixins.scss (1 hunks)
  • src/shared/constants.ts (2 hunks)
  • src/shared/hooks/use-outside-click/use-outside-click.ts (1 hunks)
  • src/shared/ui/logo/logo.module.scss (1 hunks)
  • src/shared/ui/logo/logo.tsx (2 hunks)
  • src/shared/ui/paragraph/paragraph.module.scss (2 hunks)
  • src/shared/ui/paragraph/paragraph.tsx (1 hunks)
  • src/widgets/breadcrumbs/ui/breadcrumbs.module.scss (1 hunks)
  • src/widgets/breadcrumbs/ui/breadcrumbs.tsx (2 hunks)
  • src/widgets/footer/footer.test.tsx (2 hunks)
  • src/widgets/header/header.module.scss (4 hunks)
  • src/widgets/header/header.test.tsx (5 hunks)
  • src/widgets/header/header.tsx (6 hunks)
  • src/widgets/header/ui/dropdown/dropdown-wrapper.module.scss (2 hunks)
  • src/widgets/header/ui/dropdown/dropdown-wrapper.tsx (1 hunks)
  • src/widgets/header/ui/nav-item/nav-item.module.scss (3 hunks)
  • src/widgets/header/ui/nav-item/nav-item.tsx (2 hunks)
  • src/widgets/mobile-view/ui/mobile-nav-item/mobile-nav-item.module.scss (1 hunks)
  • src/widgets/mobile-view/ui/mobile-nav-item/mobile-nav-item.tsx (1 hunks)
  • src/widgets/mobile-view/ui/mobile-view.module.scss (1 hunks)
  • src/widgets/mobile-view/ui/mobile-view.tsx (2 hunks)
  • src/widgets/school-menu/ui/school-item/school-item.module.scss (3 hunks)
  • src/widgets/school-menu/ui/school-item/school-item.tsx (1 hunks)
  • src/widgets/school-menu/ui/school-menu/school-menu.module.scss (2 hunks)
  • src/widgets/school-menu/ui/school-menu/school-menu.test.tsx (1 hunks)
  • src/widgets/school-menu/ui/school-menu/school-menu.tsx (1 hunks)
  • src/widgets/support/ui/support.tsx (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
dev-data/school-menu-links.ts (2)
src/shared/constants.ts (1)
  • ANCHORS (68-77)
dev-data/index.ts (1)
  • communityMenuStaticLinks (49-49)
src/widgets/school-menu/ui/school-item/school-item.tsx (1)
src/shared/ui/logo/logo.tsx (1)
  • cx (17-17)
src/widgets/footer/footer.test.tsx (3)
src/shared/__tests__/utils/render-with-router/render-with-router.tsx (1)
  • renderWithRouter (38-49)
src/widgets/mobile-view/ui/mobile-view.tsx (1)
  • MobileView (41-244)
src/shared/__tests__/constants.ts (1)
  • mockedCourses (27-207)
src/widgets/mobile-view/ui/mobile-nav-item/mobile-nav-item.tsx (1)
src/shared/icons/dropdown-arrow.tsx (1)
  • DropdownArrow (5-7)
🔇 Additional comments (60)
src/shared/ui/paragraph/paragraph.module.scss (2)

18-22: Confirm spacing requirements
Unlike the other size variants, .small-font-size doesn’t include bottom padding. Verify against the design spec if vertical spacing is needed here.


35-37: Review responsive adjustments
At the media-laptop breakpoint only line-height is overridden. Confirm whether properties like font-size or font-weight should also adapt on larger screens.

src/core/styles/_constants.scss (1)

56-59: Addition of intermediate gray variables
Both $color-gray-450 and $color-gray-250 are correctly inserted into the grayscale scale and follow the existing ordering.

src/core/styles/_mixins.scss (1)

3-7: New media-laptop-large mixin
The mixin appropriately targets viewports above $content-width. Ensure documentation or examples are updated to reflect this new breakpoint utility.

src/shared/constants.ts (1)

45-49: Extended KEY_CODES for improved keyboard interactions
Adding ENTER and SPACE aligns with accessibility best practices for menu toggles.

src/shared/hooks/use-outside-click/use-outside-click.ts (1)

13-17: Solid click detection logic.

Good use of mousedown event and proper null checking before calling contains().

dev-data/donate-options.data.ts (1)

9-12: Clean separation of button and menu variants.

The split into buttonLinkLabel/menuLinkLabel and buttonIcon/menuIcon provides good flexibility for different UI contexts.

src/widgets/school-menu/ui/school-menu/school-menu.test.tsx (1)

42-44: Test expectations correctly updated.

The increase from 2 to 4 elements aligns with the addition of new menu items mentioned in the PR objectives.

src/shared/ui/paragraph/paragraph.tsx (1)

18-18: LGTM! Clean addition of new font size variant.

The new "small" variant follows the established pattern and integrates well with the existing CVA configuration.

src/widgets/footer/footer.test.tsx (2)

10-10: Appropriate mock addition for navigation-dependent components.

The usePathname mock returning '/' is consistent with the testing pattern and necessary for components using Next.js navigation hooks.


41-43: Improved JSX formatting for better readability.

The multi-line format makes the test props more readable while maintaining the same functionality.

dev-data/school-menu-links.ts (2)

14-23: Well-structured addition of new menu items.

Both "Support Us" and "Mentors Wanted" entries follow the established pattern perfectly, using proper anchor constants and providing clear descriptions.


28-28: Improved clarity with more specific title.

Changing "About" to "About Community" provides better context and reduces ambiguity when multiple "About" sections exist.

src/widgets/breadcrumbs/ui/breadcrumbs.tsx (3)

15-17: Clean type definition for enhanced styling flexibility.

The optional className prop follows React best practices and maintains backward compatibility.


19-19: Proper component signature update.

The destructured className parameter correctly implements the new prop interface.


31-31: Correct implementation of className merging.

The cx() function properly combines existing classes with the optional external className, maintaining styling consistency.

src/widgets/support/ui/support.tsx (2)

31-31:

✅ Verification successful

Verify destructuring matches updated data structure.

The destructuring now includes buttonLinkLabel and buttonIcon instead of the previous linkLabel and icon. Ensure the donateOptions data structure in dev-data/donate-options.data.ts exports these exact property names.


🏁 Script executed:

#!/bin/bash
# Description: Verify the donateOptions data structure has the expected properties
# Expected: Properties should include buttonLinkLabel and buttonIcon

rg -A 10 -B 5 "buttonLinkLabel|buttonIcon" --type ts

Length of output: 2744


Verification complete: destructuring matches data structure
The donateOptions array in dev-data/donate-options.data.ts exports buttonLinkLabel and buttonIcon, matching the destructuring in support.tsx.


34-34:

✅ Verification successful

Verify icon function call pattern.

The buttonIcon() is called as a function. Ensure this returns a valid React component and that all icons in the data structure follow this pattern.


🏁 Script executed:

#!/bin/bash
# Description: Check how buttonIcon is defined in the donate options data
# Expected: Should be functions that return React components

ast-grep --pattern 'buttonIcon: $$$'

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Search for where buttonIcon is defined and how it’s assigned
rg "buttonIcon" -n -C2 .

Length of output: 1519


🏁 Script executed:

#!/bin/bash
# Inspect imports in donate-options data
sed -n '1,50p' dev-data/donate-options.data.ts

# Locate component definitions for the icons
rg "export .*OpenCollectiveIcon" -n .
rg "export .*BoostyIcon" -n .

Length of output: 1124


Icon function call pattern verified
buttonIcon maps to pure functional components (OpenCollectiveIcon, BoostyIcon) that return valid React elements and don’t use hooks, so calling buttonIcon() is safe.

(Optional) For clearer JSX semantics you could destructure:

donateOptions.map(({ buttonIcon: Icon, ... }) => (
  <Icon />
  
))

but no changes are required.

src/widgets/school-menu/ui/school-item/school-item.tsx (1)

39-39: Good accessibility improvement with tabIndex management.

Properly setting tabIndex={-1} for non-clickable items removes them from keyboard navigation, which improves accessibility and addresses potential keyboard navigation issues mentioned in the PR comments.

src/widgets/school-menu/ui/school-item/school-item.module.scss (4)

3-4: Good spacing adjustment for better visual hierarchy.

Reducing the gap from 15px to 8px and changing alignment to flex-start creates better visual spacing and addresses the spacing inconsistencies mentioned in PR comments.


10-13: Excellent accessibility enhancement for non-clickable items.

The .non-clickable class properly disables pointer events and changes cursor, which works well with the tabIndex={-1} set in the component for truly non-interactive items.


57-59: Icon sizing constraint is well-implemented.

Using the data-testid selector to constrain icon height to 32px ensures consistent icon sizing across the menu items.


32-32:

✅ Verification successful

Verify new color variable is defined.

The $color-gray-450 variable is used but needs to be defined in the constants file.


🏁 Script executed:

#!/bin/bash
# Description: Check if the new gray color variable is defined
# Expected: Should find $color-gray-450 definition

rg "\$color-gray-450" --type scss

Length of output: 63


To catch definitions without relying on filetype detection, let’s search all SCSS files by extension:


🏁 Script executed:

#!/bin/bash
# Search for any usage or definition of $color-gray-450 in .scss files
rg '\$color-gray-450' -g '*.scss'

Length of output: 292


Confirmed: $color-gray-450 is defined
The variable is declared in src/core/styles/_constants.scss as:

$color-gray-450: hsl(210deg 9% 62%); // #969fa8

No further action needed.

src/widgets/mobile-view/ui/mobile-nav-item/mobile-nav-item.module.scss (4)

18-20: Good dropdown arrow animation implementation.

The rotation animation provides clear visual feedback for collapsible menu states, which should improve the user experience mentioned in PR objectives.


1-27: Well-structured mobile navigation styling.

The category link styling properly resets button defaults and provides good mobile touch targets with appropriate font sizing and spacing.


16-16:

✅ Verification successful

Verify transition mixin is defined.

The @extend %transition-all references a placeholder selector that should be defined in the shared styles.


🏁 Script executed:

#!/bin/bash
# Description: Check if the transition-all placeholder is defined
# Expected: Should find %transition-all definition

rg "%transition-all" --type scss

Length of output: 61


🏁 Script executed:

#!/bin/bash
# Search for the %transition-all placeholder across all SCSS files
rg '%transition-all' -g '*.scss' . || grep -R --include='*.scss' '%transition-all' .

Length of output: 1570


%transition-all placeholder verified

The %transition-all placeholder is defined in src/core/styles/_placeholders.scss, so the @extend %transition-all; in mobile-nav-item.module.scss is valid. No further changes needed.


40-40:

✅ Verification successful

Verify light color variable consistency.

Using $color-gray-100 for light text. Ensure this provides sufficient contrast for accessibility.


🏁 Script executed:

#!/bin/bash
# Description: Check the gray color palette definition
# Expected: Should find consistent gray color variable definitions

rg "\$color-gray-(100|250|450|900)" --type scss

Length of output: 77


🏁 Script executed:

#!/bin/bash
# Re-run search for gray color variables across all SCSS files
rg -g '*.scss' '\$color-gray-(100|250|450|900)' -n

Length of output: 2854


🏁 Script executed:

#!/bin/bash
# Display mobile-nav-item styles to confirm background and text color context
sed -n '1,200p' src/widgets/mobile-view/ui/mobile-nav-item/mobile-nav-item.module.scss

Length of output: 615


Color variable usage verified

Definitions for $color-gray-100 (#f0f2f5) and $color-gray-900 (#191b1d) are consistent in core/styles/_constants.scss, and the .light/.dark classes in mobile-nav-item.module.scss correctly apply them. Contrast between these values meets WCAG AA/AAA on their intended backgrounds.

• core/styles/_constants.scss (lines 51–61): gray palette
• src/widgets/mobile-view/ui/mobile-nav-item/mobile-nav-item.module.scss (lines 36–40): .dark/.light classes

No changes required.

src/widgets/mobile-view/ui/mobile-nav-item/mobile-nav-item.tsx (1)

18-47: Well-structured mobile navigation component.

The component properly handles conditional icon rendering, dropdown states, and accessibility attributes. The click handler and ARIA attributes support good UX and accessibility.

src/widgets/school-menu/ui/school-menu/school-menu.tsx (2)

15-16: Good addition of layout and visibility props.

These props address previous feedback about simplifying consumer component logic and moving complexity into the component itself.


28-36: Proper implementation of conditional visibility and layout.

The visibility classes are applied correctly based on the isVisible prop, and the dynamic layout class follows React best practices.

src/widgets/header/ui/dropdown/dropdown-wrapper.tsx (2)

10-10: Good addition of layout control prop.

The reverseLayout prop provides flexibility for dropdown positioning without complex logic.


14-27: Simplified component interface improves maintainability.

Removing mouse event handlers and positioning logic simplifies the component. This suggests a shift to click-based dropdown interaction, which can improve mobile UX.

src/shared/ui/logo/logo.tsx (2)

12-15: Good extension of props interface.

Adding the optional icon prop with proper TypeScript typing maintains backward compatibility while enabling dynamic logo usage.


21-31: Proper implementation of dynamic icon support.

The default value ensures backward compatibility while the dynamic src attribute enables flexible logo rendering across different contexts.

src/widgets/mobile-view/ui/mobile-view.module.scss (2)

31-34: Well-structured media query organization.

Good placement of overflow-y: hidden and explicit flex-direction: column in the tablet-large media query, addressing the layout structure concerns.


14-28: Excellent responsive breadcrumbs handling.

The nested .content.breadcrumbs-content selector with tablet-specific padding removal is a clean approach for responsive design.

src/widgets/header/header.test.tsx (4)

15-18: Appropriate navigation mocking for header tests.

The next/navigation mock properly stubs router functionality needed for the header component testing.


42-47: Improved test scoping with within.

Using within(desktopMenu) provides better test isolation and reduces flaky test potential compared to global queries.


90-90: Good addition of reverseLayout prop.

The reverseLayout={false} prop addition aligns with the component API changes and maintains test coverage for this feature.


68-74:

❓ Verification inconclusive

Verify mobile menu arrow count aligns with implementation.

The test expects 5 SVG arrows in mobile view. Ensure this count matches the actual mobile menu structure after the refactoring.


🏁 Script executed:

#!/bin/bash
# Description: Verify mobile menu dropdown arrow count in mobile-view components
# Expected: Find mobile navigation items with dropdown arrows

ast-grep --pattern 'aria-label="dropdown-arrow"' 
rg -A 3 -B 3 'dropdown-arrow' src/widgets/mobile-view/

Length of output: 1986


🏁 Script executed:

#!/bin/bash
# Locate the DropdownArrow icon component and inspect for aria-label
DROP_PATH=$(fd dropdown-arrow.tsx)

echo "Inspecting file: $DROP_PATH"

# Check for any aria attributes on the icon
rg -n "aria" "$DROP_PATH"

# Show the SVG markup to see if an aria-label is set
rg -n "<svg" -A5 "$DROP_PATH"

Length of output: 374


Verify mobile menu arrow count matches rendered items

I confirmed each <MobileNavItem> renders one icon with aria-label="dropdown-arrow". Please double-check the number of items passed into the mobile menu (in src/widgets/header/header.tsx where you render the items under data-testid="mobile-menu") and update the test’s expected length if it no longer equals 5.

src/widgets/school-menu/ui/school-menu/school-menu.module.scss (4)

2-2: Good use of transition placeholder.

The @extend %transition-all provides consistent transition behavior across the component.


29-39: Sophisticated grid layout implementation.

The grid-based approach with automatic column adjustment for 5+ items is well-designed for flexible menu layouts.


52-68: Excellent visibility state implementation.

The .hidden and .visible classes properly use opacity constants and create smooth transitions for show/hide behavior.


35-38:

❓ Verification inconclusive

Verify grid layout behavior with variable content.

The :has(:nth-child(5)) selector switches to single-column layout. Test this behavior with different menu item counts to ensure proper responsive behavior.


🏁 Script executed:

#!/bin/bash
# Description: Check school menu usage patterns to verify grid layout behavior
# Expected: Find school menu components and their typical item counts

rg -A 10 -B 5 'SchoolMenu.*items\|school.*menu.*data' src/
ast-grep --pattern 'SchoolMenu $$$'

Length of output: 98


Verify grid layout behavior across varying menu item counts

Please ensure the single-column switch triggered by :has(:nth-child(5)) works as intended:

• Test the SchoolMenu component (in app, Storybook or tests) with fewer than 5 items, exactly 5 items, and more than 5 items.
• Confirm the grid switches back to multi-column when item count drops below 5.
• Validate responsive behavior at different breakpoints.

We couldn’t find automated usage patterns in the repo—manual or Storybook verification is recommended.

src/widgets/header/header.module.scss (4)

8-8: Appropriate height increase for better visual hierarchy.

The navbar height increase from 64px to 70px provides better proportions and aligns with the menu refactoring goals.


14-16: Clean unified background styling.

The consistent white background with subtle shadow creates a more cohesive header appearance compared to the previous color variants.


43-43: Good use of gap for menu spacing.

The increased gap (33.8px) between menu items addresses previous feedback about using gap instead of margins for layout.


107-117: Well-structured support text styling.

The .support-text class provides proper layout for donation-related content with appropriate constraints and typography.

src/widgets/header/header.tsx (2)

35-38: LGTM!

Clean implementation of conditional logic for mentorship page detection and icon selection.


64-130: Well-structured menu implementation

Good use of NAV_MENU_LABELS constants and consistent SchoolMenu patterns across all navigation items.

src/widgets/mobile-view/ui/mobile-view.tsx (1)

49-68: Excellent state management implementation

Great use of Set for managing dropdown states and proper cleanup when menu closes. The toggle logic is clean and efficient.

src/widgets/header/ui/nav-item/nav-item.module.scss (2)

22-30: Great accessibility improvement!

The addition of focus-visible styles with proper outline enhances keyboard navigation support.


53-74: Clever solution for preventing layout shift

The nested label structure with transparent parent effectively prevents layout shift when font weight changes between regular and bold states.

src/widgets/header/ui/dropdown/dropdown-wrapper.module.scss (3)

15-17: CSS Grid implementation looks good!

The three-column grid layout provides a clean structure for dropdown content organization.


29-29: Proper use of hsla color syntax

Good implementation following the requested pattern for colors with opacity.


31-53:

✅ Verification successful

Verify browser support for :has() pseudo-class

The :has() pseudo-class has limited browser support. Ensure this aligns with your browser support requirements.


🌐 Web query:

What is the current browser support for CSS :has() pseudo-class and when was it added to major browsers?

💡 Result:

The CSS :has() pseudo-class, introduced in the Selectors Level 4 specification, allows developers to select elements based on their descendants, effectively enabling parent selection in CSS. (css-tricks.com)

Browser Support Timeline:

  • Chrome: Full support began with version 105, released on September 2, 2022. (caniuse.com)

  • Edge: Support was added starting with version 105, released on September 1, 2022. (caniuse.com)

  • Safari: Support commenced with version 15.4, released on March 14, 2022. (caniuse.com)

  • Firefox: Support was introduced in version 121, released on December 19, 2023. (caniuse.com)

Current Support Status (as of May 27, 2025):

As of May 2025, the :has() pseudo-class is supported in the latest versions of major browsers:

  • Chrome: Versions 105 and later.

  • Edge: Versions 105 and later.

  • Safari: Versions 15.4 and later.

  • Firefox: Versions 121 and later.

This widespread support allows developers to utilize the :has() pseudo-class for more dynamic and context-aware styling across modern browsers.

Citations:


Browser Support for CSS :has() Verified

The CSS :has() pseudo-class is supported in all modern browsers as of these versions:

  • Chrome 105+ (Sep 2, 2022)
  • Edge 105+ (Sep 1, 2022)
  • Safari 15.4+ (Mar 14, 2022)
  • Firefox 121+ (Dec 19, 2023)

As long as your project’s browser-support baseline targets these (or later) versions, you can safely use :has() for dynamic grid layouts in src/widgets/header/ui/dropdown/dropdown-wrapper.module.scss (lines 31–53). No further changes required.

src/widgets/header/ui/nav-item/nav-item.tsx (4)

48-53: Good implementation of dropdown coordination

The custom event pattern effectively ensures only one dropdown is open at a time.


70-76: Excellent keyboard accessibility implementation

Proper handling of Enter, Space, and Escape keys with preventDefault for form submission prevention.


80-86: Proper event listener lifecycle management

Good implementation with cleanup to prevent memory leaks.


120-125:

✅ Verification successful

Verify the double label rendering pattern

The duplicate label with aria-hidden appears to be for styling purposes. Ensure this doesn't cause issues with screen readers or SEO.


🏁 Script executed:

#!/bin/bash
# Check if this pattern is used elsewhere in the codebase
ast-grep --pattern $'<span className={$_}>
  $_
  <span className={$_} aria-hidden="true">
    $_
  </span>
</span>'

Length of output: 117


🏁 Script executed:

#!/bin/bash
# Search for all occurrences of aria-hidden to identify similar double-render patterns
rg -n 'aria-hidden="true"'

Length of output: 1107


Double‐render label pattern is consistent and accessible

I checked similar components (mobile-nav-item, school-item, etc.) and confirmed the duplicate label with aria-hidden="true" is a deliberate styling trick. Screen readers will ignore the hidden span, so only the primary label is announced and there’s no SEO impact. No changes required.

Comment on lines +92 to +99
export const NAV_MENU_LABELS = {
RS_SCHOOL: 'RS School',
COURSES: 'Courses',
COMMUNITY: 'Community',
MENTORSHIP: 'Mentorship',
DOCS: 'Docs',
SUPPORT_US: 'Support Us',
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add as const for type safety
To maintain consistency with other constant maps and preserve literal types, append as const to the NAV_MENU_LABELS definition.

🤖 Prompt for AI Agents
In src/shared/constants.ts around lines 92 to 99, the NAV_MENU_LABELS object
should be appended with 'as const' to ensure type safety and preserve literal
types. Modify the export statement by adding 'as const' at the end of the object
definition to maintain consistency with other constant maps.

@gbogdanova
Copy link
Collaborator

I noticed that tapping the logo in the mobile menu doesn't trigger the onClose callback, so the collapsible menu remains open. Maybe we should add to the Logo component when it's used in the mobile menu to ensure consistent behavior.

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.

Menu items active text color Desktop menu rework
8 participants
0