-
-
Notifications
You must be signed in to change notification settings - Fork 952
feat(navbar): add smooth fade-slide dropdowns for Docs, Tools, Community #4447
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
base: master
Are you sure you want to change the base?
feat(navbar): add smooth fade-slide dropdowns for Docs, Tools, Community #4447
Conversation
❌ Deploy Preview for asyncapi-website failed.Built without sensitive environment variables
|
WalkthroughImplements per-dropdown open state and closeTimeout handling in NavBar to coordinate hover (desktop) and click (mobile) interactions, adds transitional wrapper containers for dropdown panels with CSS opacity/translate/scale transitions, and standardizes JSX/className formatting and minor accessibility/text tweaks. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor U as User
participant N as NavBar
participant D as Dropdown Panel
rect rgba(200,235,255,0.25)
note over U,N: Desktop hover flow
U->>N: mouseenter (trigger)
N-->>N: clear pending closeTimeout
N->>D: set open = true (apply transition)
U->>D: mouseenter (panel)
U->>D: mouseleave (panel)
N-->>N: start closeTimeout (delayed close)
alt user re-enters before timeout
U->>N: mouseenter (trigger/panel)
N-->>N: clear closeTimeout (keep open)
else timeout expires
N->>D: set open = false
end
end
rect rgba(220,255,220,0.25)
note over U,N: Mobile click flow
U->>N: click (trigger)
alt closed
N->>D: set open = true (toggle)
else open
N->>D: set open = false (toggle)
end
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Welcome to AsyncAPI. Thanks a lot for creating your first pull request. Please check out our contributors guide useful for opening a pull request.
Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out this issue.
|
⚡️ Lighthouse report for the changes in this PR:
Lighthouse ran on https://deploy-preview-4447--asyncapi-website.netlify.app/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
components/navigation/NavBar.tsx (2)
64-76: Fix formatting in language filtering logic.The filter and map operations include trailing commas and line breaks that violate the project's style guidelines.
Apply this diff:
- const uniqueLangs = Object.keys(i18nPaths).filter((lang) => - i18nPaths[lang].includes(pathnameWithoutLocale), - ); + const uniqueLangs = Object.keys(i18nPaths).filter((lang) => i18nPaths[lang].includes(pathnameWithoutLocale)); // If no unique languages are found, default to ['en'] return uniqueLangs.length === 0 ? ['en'] : uniqueLangs; }; const uniqueLangs = getUniqueLangs().map((lang) => ({ key: lang, text: lang, - value: lang, + value: lang }));
300-334: Fix quote violations in remaining nav items.The remaining navigation items contain multiple quote violations that must be corrected.
Apply this diff:
{otherItems.map((item, index) => ( <NavItem href={item.href} key={index} text={item.text} target={item.target} className={item.className} /> ))} - <div className="justify-content flex flex-row items-center"> + <div className='justify-content flex flex-row items-center'> <SearchButton - className="mr-2 flex items-center space-x-2 rounded-md p-2 text-left text-gray-400 transition duration-150 ease-in-out hover:bg-gray-100 hover:text-gray-500 focus:bg-gray-100 focus:text-gray-500 focus:outline-none" - aria-label="Open Search" + className='mr-2 flex items-center space-x-2 rounded-md p-2 text-left text-gray-400 transition duration-150 ease-in-out hover:bg-gray-100 hover:text-gray-500 focus:bg-gray-100 focus:text-gray-500 focus:outline-none' + aria-label='Open Search' > <IconLoupe /> </SearchButton> {/* // Language Picker Component */} <LanguageSelect options={uniqueLangs} onChange={(value) => { changeLanguage(value.toLowerCase(), true); }} - className="" + className='' selected={i18n.language ? i18n.language : 'en'} /> <GithubButton - text="Star on GitHub" - href="https://github.com/asyncapi/spec" - className="ml-2 py-2" + text='Star on GitHub' + href='https://github.com/asyncapi/spec' + className='ml-2 py-2' inNav={true} /> </div>
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
components/navigation/NavBar.tsx(7 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
components/navigation/NavBar.tsx (8)
utils/i18n.ts (1)
i18nPaths(7-18)components/logos/AsyncAPILogo.tsx (1)
AsyncAPILogo(12-140)components/AlgoliaSearch.tsx (1)
SearchButton(284-333)components/icons/Loupe.tsx (1)
IconLoupe(7-24)components/navigation/LearningPanel.tsx (1)
LearningPanel(9-11)components/navigation/ToolsPanel.tsx (1)
ToolsPanel(9-11)components/navigation/CommunityPanel.tsx (1)
CommunityPanel(9-11)components/buttons/GithubButton.tsx (1)
GithubButton(22-45)
🪛 GitHub Actions: PR testing - if Node project
components/navigation/NavBar.tsx
[error] 36-36: prettier/prettier: Replace ⏎··className·=·'',⏎··hideLogo·=·false,⏎ with className='' ,hideLogo=false
[error] 38-38: prettier/prettier: Unexpected trailing comma.
[error] 42-42: prettier/prettier: Replace ⏎····null,⏎·· with null
[error] 43-43: prettier/prettier: Unexpected trailing comma.
[error] 46-46: no-undef: 'NodeJS' is not defined
[error] 64-64: prettier/prettier: Replace ⏎······i18nPaths[lang].includes(pathnameWithoutLocale),⏎···· with i18nPaths[lang].includes(pathnameWithoutLocale)
[error] 65-65: prettier/prettier: Unexpected trailing comma.
[error] 75-75: prettier/prettier: Delete ,
[error] 75-75: prettier/prettier: Unexpected trailing comma.
[error] 84-84: prettier/prettier: Replace ⏎····locale:·string,⏎····langPicker:·boolean,⏎·· with locale:·string,·langPicker:·boolean
[error] 86-86: prettier/prettier: Unexpected trailing comma.
[error] 163-163: prettier/prettier: Replace "flex·w-full·items-center·justify-between·py-6·lg:justify-start·lg:space-x-2" with 'flex w-full items-center justify-between py-6 lg:justify-start lg:space-x-2'
[error] 163-163: jsx-quotes: Unexpected usage of doublequote.
[error] 165-165: prettier/prettier: Replace "lg:w-auto·lg:flex-1" with 'lg:w-auto·lg:flex-1'
[error] 165-165: jsx-quotes: Unexpected usage of doublequote.
[error] 166-166: prettier/prettier: Replace "flex" with 'flex'
[error] 166-166: jsx-quotes: Unexpected usage of doublequote.
[error] 167-167: prettier/prettier: Replace a long line with a chained property form; see log for details.
[error] 168-168: jsx-quotes: Unexpected usage of doublequote.
[error] 169-169: jsx-quotes: Unexpected usage of doublequote.
[error] 170-170: jsx-quotes: Unexpected usage of doublequote.
[error] 171-171: jsx-quotes: Unexpected usage of doublequote.
[error] 173-173: prettier/prettier: Replace "w-auto" with 'w-auto'
[error] 173-173: jsx-quotes: Unexpected usage of doublequote.
[error] 179-179: prettier/prettier: Replace "-my-2·-mr-2·flex·flex-row·items-center·justify-center·lg:hidden" with '-my-2 -mr-2 flex flex-row items-center justify-center lg:hidden'
[error] 180-180: jsx-quotes: Unexpected usage of doublequote.
[error] 184-184: max-len: This line is too long (221). Maximum allowed is 120.
[error] 184-184: prettier/prettier: Replace long string with string literal using single quotes.
[error] 185-185: jsx-quotes: Unexpected usage of doublequote.
[error] 191-191: prettier/prettier: Replace "button" with 'button'
[error] 191-191: jsx-quotes: Unexpected usage of doublequote.
[error] 192-192: max-len: This line is too long (223). Maximum allowed is 120.
[error] 192-192: prettier/prettier: Replace long string with single-quoted literal.
[error] 194-194: prettier/prettier: Replace string with attribute-friendly form.
[error] 195-195: jsx-quotes: Unexpected usage of doublequote.
[error] 196-196: jsx-quotes: Unexpected usage of doublequote.
[error] 197-197: jsx-quotes: Unexpected usage of doublequote.
[error] 198-198: jsx-quotes: Unexpected usage of doublequote.
[error] 201-201: prettier/prettier: Replace strokeLinecap="round" with strokeLinecap='round'
[error] 202-202: prettier/prettier: Replace strokeLinejoin="round" with strokeLinejoin='round'
[error] 203-203: prettier/prettier: Replace strokeWidth="2" with strokeWidth='2'
[error] 204-204: prettier/prettier: Replace d="M4·6h16M4·12h16M4·18h16" with d='M4 6h16M4 12h16M4 18h16'
[error] 205-205: prettier/prettier: Replace "M4·6h16M4·12h16M4·18h16" with m' (invalid message placeholder)
[error] 212-212: prettier/prettier: Replace "hidden·w-full·space-x-4·lg:flex·lg:items-center·lg:justify-end·xl:space-x-8" with 'hidden w-full space-x-4 lg:flex lg:items-center lg:justify-end xl:space-x-8'
[error] 212-212: jsx-quotes: Unexpected usage of doublequote.
[error] 213-213: prettier/prettier: Replace "Navbar-main" with 'Navbar-main'
[error] 213-213: jsx-quotes: Unexpected usage of doublequote.
[error] 216-216: prettier/prettier: Replace "relative" with 'relative'
[error] 216-216: jsx-quotes: Unexpected usage of doublequote.
[error] 220-220: newline-after-var: Expected blank line after variable declarations.
[error] 221-221: padding-line-between-statements: Expected blank line before this statement.
[error] 225-225: prettier/prettier: Replace "Docs" with 'Docs'
[error] 225-225: jsx-quotes: Unexpected usage of doublequote.
[error] 226-226: prettier/prettier: Replace "/docs" with '/docs'
[error] 226-226: jsx-quotes: Unexpected usage of doublequote.
[error] 232-232: max-len: This line is too long (126). Maximum allowed is 120.
[error] 233-233: prettier/prettier: Replace long string with single-quoted literal.
[error] 233-233: jsx-quotes: Unexpected usage of doublequote.
[error] 240-240: prettier/prettier: Replace "rounded-xl·shadow-lg·border·border-gray-100·bg-white/95·backdrop-blur-sm" with 'rounded-xl·shadow-lg·border·border-gray-100·bg-white/95·backdrop-blur-sm'
[error] 240-240: jsx-quotes: Unexpected usage of doublequote.
[error] 246-246: prettier/prettier: Replace long string with single-quoted literal.
[error] 246-246: jsx-quotes: Unexpected usage of doublequote.
[error] 252-252: prettier/prettier: Replace "Tools" with 'Tools'
[error] 252-252: jsx-quotes: Unexpected usage of doublequote.
[error] 253-253: prettier/prettier: Replace "/tools" with '/tools'
[error] 253-253: jsx-quotes: Unexpected usage of doublequote.
[error] 259-259: max-len: This line is too long (126). Maximum allowed is 120.
[error] 260-260: prettier/prettier: Replace long string with single-quoted literal.
[error] 260-260: jsx-quotes: Unexpected usage of doublequote.
[error] 267-267: prettier/prettier: Replace "rounded-xl·shadow-lg·border·border-gray-100·bg-white/95·backdrop-blur-sm" with 'rounded-xl·shadow-lg·border·border-gray-100·bg-white/95·backdrop-blur-sm'
[error] 267-267: jsx-quotes: Unexpected usage of doublequote.
[error] 273-273: prettier/prettier: Replace "relative" with 'relative'
[error] 273-273: jsx-quotes: Unexpected usage of doublequote.
[error] 279-279: prettier/prettier: Replace "Community" with 'Community'
[error] 279-279: jsx-quotes: Unexpected usage of doublequote.
[error] 280-280: prettier/prettier: Replace "/community" with '/community'
[error] 280-280: jsx-quotes: Unexpected usage of doublequote.
[error] 286-286: max-len: This line is too long (126). Maximum allowed is 120.
[error] 288-288: prettier/prettier: Replace long string with single-quoted literal.
[error] 294-294: prettier/prettier: Replace "rounded-xl·shadow-lg·border·border-gray-100·bg-white/95·backdrop-blur-sm" with 'rounded-xl·shadow-lg·border·border-gray-100·bg-white/95·backdrop-blur-sm'
[error] 294-294: jsx-quotes: Unexpected usage of doublequote.
[error] 301-301: prettier/prettier: Replace strokeLinecap="round" with strokeLinecap='round'
[error] 302-302: prettier/prettier: Replace strokeLinejoin="round" with strokeLinejoin='round'
[error] 303-303: prettier/prettier: Replace strokeWidth="2" with strokeWidth='2'
[error] 304-304: prettier/prettier: Replace d="M4·6h16M4·12h16M4·18h16" with d='M4 6h16M4 12h16M4 18h16'
[error] 312-312: prettier/prettier: Replace "justify-content·flex·flex-row·items-center" with 'justify-content·flex·flex-row·items-center'
[error] 312-312: jsx-quotes: Unexpected usage of doublequote.
[error] 324-324: prettier/prettier: Replace "" with ''
[error] 324-324: jsx-quotes: Unexpected usage of doublequote.
[error] 329-329: prettier/prettier: Replace "Star·on·GitHub" with 'Star·on·GitHub'
[error] 329-329: jsx-quotes: Unexpected usage of doublequote.
[error] 330-330: prettier/prettier: Replace "https://github.com/asyncapi/spec" with 'https://github.com/asyncapi/spec'
[error] 330-330: jsx-quotes: Unexpected usage of doublequote.
[error] 331-331: prettier/prettier: Replace "ml-2·py-2" with 'ml-2·py-2'
[error] 331-331: jsx-quotes: Unexpected usage of doublequote.
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Lighthouse CI
🔇 Additional comments (1)
components/navigation/NavBar.tsx (1)
136-141: Verify timeout cleanup on unmount.The timeout clearing logic correctly prevents race conditions when hovering between menu items. However, ensure that any pending
closeTimeoutis cleared when the component unmounts to avoid memory leaks.Add this cleanup to the existing
useEffect:useEffect(() => { setMobileMenuOpen(false); setOpen(null); + return () => { + if (closeTimeout) { + clearTimeout(closeTimeout); + } + }; - }, [asPath]); + }, [asPath, closeTimeout]);
| export default function NavBar({ | ||
| className = '', | ||
| hideLogo = false, | ||
| }: NavBarProps) { | ||
| const router: NextRouter = useRouter(); | ||
| const { pathname, query, asPath } = router; | ||
| const [open, setOpen] = useState<'learning' | 'tooling' | 'community' | null>(null); | ||
| const [open, setOpen] = useState<'learning' | 'tooling' | 'community' | null>( | ||
| null, | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix formatting to match project style.
The parameter formatting and state declaration include trailing commas and line breaks that violate the project's Prettier and ESLint configuration.
Apply this diff to fix the formatting:
-export default function NavBar({
- className = '',
- hideLogo = false,
-}: NavBarProps) {
+export default function NavBar({ className = '', hideLogo = false }: NavBarProps) {
const router: NextRouter = useRouter();
const { pathname, query, asPath } = router;
- const [open, setOpen] = useState<'learning' | 'tooling' | 'community' | null>(
- null,
- );
+ const [open, setOpen] = useState<'learning' | 'tooling' | 'community' | null>(null);🧰 Tools
🪛 GitHub Actions: PR testing - if Node project
[error] 36-36: prettier/prettier: Replace ⏎··className·=·'',⏎··hideLogo·=·false,⏎ with className='' ,hideLogo=false
[error] 38-38: prettier/prettier: Unexpected trailing comma.
[error] 42-42: prettier/prettier: Replace ⏎····null,⏎·· with null
[error] 43-43: prettier/prettier: Unexpected trailing comma.
🤖 Prompt for AI Agents
In components/navigation/NavBar.tsx around lines 36 to 44, update the function
parameter and useState formatting to match project Prettier/ESLint rules: put
the props object shorthand on one line (export default function NavBar({
className = '', hideLogo = false }: NavBarProps) {), and collapse the useState
declaration to a single line without a trailing comma (const [open, setOpen] =
useState<'learning' | 'tooling' | 'community' | null>(null);). Ensure no
trailing commas or unnecessary line breaks remain.
| null, | ||
| ); | ||
| const [mobileMenuOpen, setMobileMenuOpen] = useState<boolean>(false); | ||
| const [closeTimeout, setCloseTimeout] = useState<NodeJS.Timeout | null>(null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix undefined 'NodeJS' and use proper timer type.
The NodeJS namespace is not defined in the browser environment, causing a linting error. Use ReturnType<typeof setTimeout> for cross-environment compatibility.
Apply this diff:
- const [closeTimeout, setCloseTimeout] = useState<NodeJS.Timeout | null>(null);
+ const [closeTimeout, setCloseTimeout] = useState<ReturnType<typeof setTimeout> | null>(null);📝 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.
| const [closeTimeout, setCloseTimeout] = useState<NodeJS.Timeout | null>(null); | |
| const [closeTimeout, setCloseTimeout] = useState<ReturnType<typeof setTimeout> | null>(null); |
🧰 Tools
🪛 GitHub Actions: PR testing - if Node project
[error] 46-46: no-undef: 'NodeJS' is not defined
🤖 Prompt for AI Agents
In components/navigation/NavBar.tsx around line 46, the state is typed as
NodeJS.Timeout which is undefined in browser environments; change the type to
ReturnType<typeof setTimeout> and keep the initial value as null (i.e.,
useState<ReturnType<typeof setTimeout> | null>(null)) so the timer type works
cross-environment and satisfies the linter.
| const changeLanguage = async ( | ||
| locale: string, | ||
| langPicker: boolean, | ||
| ): Promise<void> => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix parameter formatting in changeLanguage.
The function parameters include trailing commas and line breaks that violate the project's formatting rules.
Apply this diff:
- const changeLanguage = async (
- locale: string,
- langPicker: boolean,
- ): Promise<void> => {
+ const changeLanguage = async (locale: string, langPicker: boolean): Promise<void> => {📝 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.
| const changeLanguage = async ( | |
| locale: string, | |
| langPicker: boolean, | |
| ): Promise<void> => { | |
| const changeLanguage = async (locale: string, langPicker: boolean): Promise<void> => { |
🧰 Tools
🪛 GitHub Actions: PR testing - if Node project
[error] 84-84: prettier/prettier: Replace ⏎····locale:·string,⏎····langPicker:·boolean,⏎·· with locale:·string,·langPicker:·boolean
[error] 86-86: prettier/prettier: Unexpected trailing comma.
🤖 Prompt for AI Agents
In components/navigation/NavBar.tsx around lines 84 to 87, the changeLanguage
function signature is formatted with trailing commas and unnecessary line
breaks; reformat the parameter list to follow project style by placing
parameters on a single line without trailing commas (e.g., changeLanguage =
async (locale: string, langPicker: boolean): Promise<void> => { ), ensuring
consistent spacing and removing the extra comma and line break.
| <div className="flex w-full items-center justify-between py-6 lg:justify-start lg:space-x-2"> | ||
| {!hideLogo && ( | ||
| <div className='lg:w-auto lg:flex-1'> | ||
| <div className='flex'> | ||
| <Link href='/' className='cursor-pointer' aria-label='AsyncAPI' data-testid='Navbar-logo'> | ||
| <AsyncAPILogo className='w-auto' /> | ||
| <div className="lg:w-auto lg:flex-1"> | ||
| <div className="flex"> | ||
| <Link | ||
| href="/" | ||
| className="cursor-pointer" | ||
| aria-label="AsyncAPI" | ||
| data-testid="Navbar-logo" | ||
| > | ||
| <AsyncAPILogo className="w-auto" /> | ||
| </Link> | ||
| </div> | ||
| </div> | ||
| )} | ||
|
|
||
| <div className='-my-2 -mr-2 flex flex-row items-center justify-center lg:hidden' data-testid='Navbar-search'> | ||
| <div | ||
| className="-my-2 -mr-2 flex flex-row items-center justify-center lg:hidden" | ||
| data-testid="Navbar-search" | ||
| > | ||
| <SearchButton | ||
| className='flex items-center space-x-2 rounded-md p-2 text-left text-gray-400 transition duration-150 ease-in-out hover:bg-gray-100 hover:text-gray-500 focus:bg-gray-100 focus:text-gray-500 focus:outline-none' | ||
| aria-label='Open Search' | ||
| className="flex items-center space-x-2 rounded-md p-2 text-left text-gray-400 transition duration-150 ease-in-out hover:bg-gray-100 hover:text-gray-500 focus:bg-gray-100 focus:text-gray-500 focus:outline-none" | ||
| aria-label="Open Search" | ||
| > | ||
| <IconLoupe /> | ||
| </SearchButton> | ||
| <button | ||
| onClick={() => setMobileMenuOpen(true)} | ||
| type='button' | ||
| className='inline-flex items-center justify-center rounded-md p-2 text-gray-400 transition duration-150 ease-in-out hover:bg-gray-100 hover:text-gray-500 focus:bg-gray-100 focus:text-gray-500 focus:outline-none' | ||
| type="button" | ||
| className="inline-flex items-center justify-center rounded-md p-2 text-gray-400 transition duration-150 ease-in-out hover:bg-gray-100 hover:text-gray-500 focus:bg-gray-100 focus:text-gray-500 focus:outline-none" | ||
| > | ||
| <svg className='size-6' stroke='currentColor' fill='none' viewBox='0 0 24 24'> | ||
| <svg | ||
| className="size-6" | ||
| stroke="currentColor" | ||
| fill="none" | ||
| viewBox="0 0 24 24" | ||
| > | ||
| <title>Menu</title> | ||
| <path strokeLinecap='round' strokeLinejoin='round' strokeWidth='2' d='M4 6h16M4 12h16M4 18h16' /> | ||
| <path | ||
| strokeLinecap="round" | ||
| strokeLinejoin="round" | ||
| strokeWidth="2" | ||
| d="M4 6h16M4 12h16M4 18h16" | ||
| /> | ||
| </svg> | ||
| </button> | ||
| </div> | ||
|
|
||
| <nav | ||
| className='hidden w-full space-x-4 lg:flex lg:items-center lg:justify-end xl:space-x-8' | ||
| data-testid='Navbar-main' | ||
| className="hidden w-full space-x-4 lg:flex lg:items-center lg:justify-end xl:space-x-8" | ||
| data-testid="Navbar-main" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix extensive quote and formatting violations.
Multiple JSX attributes use double quotes instead of single quotes, violating the project's ESLint configuration. Lines also exceed maximum length.
The following violations must be fixed:
- Line 163: Replace double quotes with single quotes
- Line 165-173: Replace double quotes with single quotes in all Link attributes
- Line 179-185: Replace double quotes with single quotes
- Line 191-205: Replace double quotes with single quotes in SVG attributes
- Line 212-213: Replace double quotes with single quotes
Apply formatting by running:
npm run formatOr apply changes manually following the pattern:
- <div className="flex w-full items-center justify-between py-6 lg:justify-start lg:space-x-2">
+ <div className='flex w-full items-center justify-between py-6 lg:justify-start lg:space-x-2'>🧰 Tools
🪛 GitHub Actions: PR testing - if Node project
[error] 163-163: prettier/prettier: Replace "flex·w-full·items-center·justify-between·py-6·lg:justify-start·lg:space-x-2" with 'flex w-full items-center justify-between py-6 lg:justify-start lg:space-x-2'
[error] 163-163: jsx-quotes: Unexpected usage of doublequote.
[error] 165-165: prettier/prettier: Replace "lg:w-auto·lg:flex-1" with 'lg:w-auto·lg:flex-1'
[error] 165-165: jsx-quotes: Unexpected usage of doublequote.
[error] 166-166: prettier/prettier: Replace "flex" with 'flex'
[error] 166-166: jsx-quotes: Unexpected usage of doublequote.
[error] 167-167: prettier/prettier: Replace a long line with a chained property form; see log for details.
[error] 168-168: jsx-quotes: Unexpected usage of doublequote.
[error] 169-169: jsx-quotes: Unexpected usage of doublequote.
[error] 170-170: jsx-quotes: Unexpected usage of doublequote.
[error] 171-171: jsx-quotes: Unexpected usage of doublequote.
[error] 173-173: prettier/prettier: Replace "w-auto" with 'w-auto'
[error] 173-173: jsx-quotes: Unexpected usage of doublequote.
[error] 179-179: prettier/prettier: Replace "-my-2·-mr-2·flex·flex-row·items-center·justify-center·lg:hidden" with '-my-2 -mr-2 flex flex-row items-center justify-center lg:hidden'
[error] 180-180: jsx-quotes: Unexpected usage of doublequote.
[error] 184-184: max-len: This line is too long (221). Maximum allowed is 120.
[error] 184-184: prettier/prettier: Replace long string with string literal using single quotes.
[error] 185-185: jsx-quotes: Unexpected usage of doublequote.
[error] 191-191: prettier/prettier: Replace "button" with 'button'
[error] 191-191: jsx-quotes: Unexpected usage of doublequote.
[error] 192-192: max-len: This line is too long (223). Maximum allowed is 120.
[error] 192-192: prettier/prettier: Replace long string with single-quoted literal.
[error] 194-194: prettier/prettier: Replace string with attribute-friendly form.
[error] 195-195: jsx-quotes: Unexpected usage of doublequote.
[error] 196-196: jsx-quotes: Unexpected usage of doublequote.
[error] 197-197: jsx-quotes: Unexpected usage of doublequote.
[error] 198-198: jsx-quotes: Unexpected usage of doublequote.
[error] 201-201: prettier/prettier: Replace strokeLinecap="round" with strokeLinecap='round'
[error] 202-202: prettier/prettier: Replace strokeLinejoin="round" with strokeLinejoin='round'
[error] 203-203: prettier/prettier: Replace strokeWidth="2" with strokeWidth='2'
[error] 204-204: prettier/prettier: Replace d="M4·6h16M4·12h16M4·18h16" with d='M4 6h16M4 12h16M4 18h16'
[error] 205-205: prettier/prettier: Replace "M4·6h16M4·12h16M4·18h16" with m' (invalid message placeholder)
[error] 212-212: prettier/prettier: Replace "hidden·w-full·space-x-4·lg:flex·lg:items-center·lg:justify-end·xl:space-x-8" with 'hidden w-full space-x-4 lg:flex lg:items-center lg:justify-end xl:space-x-8'
[error] 212-212: jsx-quotes: Unexpected usage of doublequote.
[error] 213-213: prettier/prettier: Replace "Navbar-main" with 'Navbar-main'
[error] 213-213: jsx-quotes: Unexpected usage of doublequote.
🤖 Prompt for AI Agents
components/navigation/NavBar.tsx lines 163-213: JSX attributes currently use
double quotes and some lines exceed max length; update all JSX attribute string
delimiters to single quotes on the specified lines (163, 165-173, 179-185,
191-205, 212-213), break long attribute or element lines into shorter
concatenated lines or wrap props onto multiple lines to satisfy max-line-length,
then run npm run format (or your project's formatter) and re-run lint to ensure
formatting and quote-style violations are resolved.
| <div | ||
| className="relative" | ||
| ref={learningRef} | ||
| onMouseEnter={() => showMenu('learning')} | ||
| onMouseLeave={() => { | ||
| const timeout = setTimeout(() => setOpen(null), 200); | ||
| setCloseTimeout(timeout); | ||
| }} | ||
| > | ||
| <NavItem | ||
| text='Docs' | ||
| href='/docs' | ||
| text="Docs" | ||
| href="/docs" | ||
| onClick={() => showOnClickMenu('learning')} | ||
| onMouseEnter={() => showMenu('learning')} | ||
| hasDropdown | ||
| /> | ||
| {open === 'learning' && <LearningPanel />} | ||
| <div | ||
| className={`absolute left-0 top-full mt-3 transform transition-all duration-300 ease-[cubic-bezier(0.4,0,0.2,1)] | ||
| ${ | ||
| open === 'learning' | ||
| ? 'opacity-100 translate-y-0 scale-100 visible' | ||
| : 'opacity-0 -translate-y-2 scale-95 invisible' | ||
| } | ||
| `} | ||
| > | ||
| <div className="rounded-xl shadow-lg border border-gray-100 bg-white/95 backdrop-blur-sm"> | ||
| <LearningPanel /> | ||
| </div> | ||
| </div> | ||
| </div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix dropdown hover behavior to prevent premature closing.
The Learning dropdown sets a 200ms timeout to close on onMouseLeave (line 219-222), but the panel content (lines 231-243) doesn't have hover handlers to cancel this timeout. This causes the panel to close when the user moves their cursor from the trigger to the panel content.
Apply this diff to fix the hover behavior:
<div
- className={`absolute left-0 top-full mt-3 transform transition-all duration-300 ease-[cubic-bezier(0.4,0,0.2,1)]
- ${
- open === 'learning'
- ? 'opacity-100 translate-y-0 scale-100 visible'
- : 'opacity-0 -translate-y-2 scale-95 invisible'
- }
- `}
+ className={`absolute left-0 top-full mt-3 transform transition-all duration-300 ease-[cubic-bezier(0.4,0,0.2,1)] ${
+ open === 'learning'
+ ? 'opacity-100 translate-y-0 scale-100 visible'
+ : 'opacity-0 -translate-y-2 scale-95 invisible'
+ }`}
+ onMouseEnter={() => showMenu('learning')}
>
- <div className="rounded-xl shadow-lg border border-gray-100 bg-white/95 backdrop-blur-sm">
+ <div className='rounded-xl shadow-lg border border-gray-100 bg-white/95 backdrop-blur-sm'>
<LearningPanel />
</div>
</div>Note: This also fixes the quote violations in the className strings.
📝 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.
| <div | |
| className="relative" | |
| ref={learningRef} | |
| onMouseEnter={() => showMenu('learning')} | |
| onMouseLeave={() => { | |
| const timeout = setTimeout(() => setOpen(null), 200); | |
| setCloseTimeout(timeout); | |
| }} | |
| > | |
| <NavItem | |
| text='Docs' | |
| href='/docs' | |
| text="Docs" | |
| href="/docs" | |
| onClick={() => showOnClickMenu('learning')} | |
| onMouseEnter={() => showMenu('learning')} | |
| hasDropdown | |
| /> | |
| {open === 'learning' && <LearningPanel />} | |
| <div | |
| className={`absolute left-0 top-full mt-3 transform transition-all duration-300 ease-[cubic-bezier(0.4,0,0.2,1)] | |
| ${ | |
| open === 'learning' | |
| ? 'opacity-100 translate-y-0 scale-100 visible' | |
| : 'opacity-0 -translate-y-2 scale-95 invisible' | |
| } | |
| `} | |
| > | |
| <div className="rounded-xl shadow-lg border border-gray-100 bg-white/95 backdrop-blur-sm"> | |
| <LearningPanel /> | |
| </div> | |
| </div> | |
| </div> | |
| <div | |
| className="relative" | |
| ref={learningRef} | |
| onMouseEnter={() => showMenu('learning')} | |
| onMouseLeave={() => { | |
| const timeout = setTimeout(() => setOpen(null), 200); | |
| setCloseTimeout(timeout); | |
| }} | |
| > | |
| <NavItem | |
| text="Docs" | |
| href="/docs" | |
| onClick={() => showOnClickMenu('learning')} | |
| onMouseEnter={() => showMenu('learning')} | |
| hasDropdown | |
| /> | |
| <div | |
| className={`absolute left-0 top-full mt-3 transform transition-all duration-300 ease-[cubic-bezier(0.4,0,0.2,1)] ${ | |
| open === 'learning' | |
| ? 'opacity-100 translate-y-0 scale-100 visible' | |
| : 'opacity-0 -translate-y-2 scale-95 invisible' | |
| }`} | |
| onMouseEnter={() => showMenu('learning')} | |
| > | |
| <div className='rounded-xl shadow-lg border border-gray-100 bg-white/95 backdrop-blur-sm'> | |
| <LearningPanel /> | |
| </div> | |
| </div> | |
| </div> |
🧰 Tools
🪛 GitHub Actions: PR testing - if Node project
[error] 216-216: prettier/prettier: Replace "relative" with 'relative'
[error] 216-216: jsx-quotes: Unexpected usage of doublequote.
[error] 220-220: newline-after-var: Expected blank line after variable declarations.
[error] 221-221: padding-line-between-statements: Expected blank line before this statement.
[error] 225-225: prettier/prettier: Replace "Docs" with 'Docs'
[error] 225-225: jsx-quotes: Unexpected usage of doublequote.
[error] 226-226: prettier/prettier: Replace "/docs" with '/docs'
[error] 226-226: jsx-quotes: Unexpected usage of doublequote.
[error] 232-232: max-len: This line is too long (126). Maximum allowed is 120.
[error] 233-233: prettier/prettier: Replace long string with single-quoted literal.
[error] 233-233: jsx-quotes: Unexpected usage of doublequote.
[error] 240-240: prettier/prettier: Replace "rounded-xl·shadow-lg·border·border-gray-100·bg-white/95·backdrop-blur-sm" with 'rounded-xl·shadow-lg·border·border-gray-100·bg-white/95·backdrop-blur-sm'
[error] 240-240: jsx-quotes: Unexpected usage of doublequote.
| <div | ||
| className="relative" | ||
| onMouseLeave={() => showMenu(null)} | ||
| ref={toolingRef} | ||
| > | ||
| <NavItem | ||
| text='Tools' | ||
| href='/tools' | ||
| text="Tools" | ||
| href="/tools" | ||
| onClick={() => showOnClickMenu('tooling')} | ||
| onMouseEnter={() => showMenu('tooling')} | ||
| hasDropdown | ||
| /> | ||
| {open === 'tooling' && <ToolsPanel />} | ||
| <div | ||
| className={`absolute left-0 top-full mt-3 transform transition-all duration-300 ease-[cubic-bezier(0.4,0,0.2,1)] | ||
| ${ | ||
| open === 'tooling' | ||
| ? 'opacity-100 translate-y-0 scale-100 visible' | ||
| : 'opacity-0 -translate-y-2 scale-95 invisible' | ||
| } | ||
| `} | ||
| > | ||
| <div className="rounded-xl shadow-lg border border-gray-100 bg-white/95 backdrop-blur-sm"> | ||
| <ToolsPanel /> | ||
| </div> | ||
| </div> | ||
| </div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix inconsistent hover behavior and apply same pattern as Learning dropdown.
The Tooling dropdown uses onMouseLeave={() => showMenu(null)} at line 248, which closes immediately without the 200ms timeout used in the Learning dropdown. This creates an inconsistent user experience. Additionally, the panel lacks an onMouseEnter handler to keep it open when hovered.
Apply this diff to match the Learning dropdown pattern:
<div
- className="relative"
- onMouseLeave={() => showMenu(null)}
+ className='relative'
ref={toolingRef}
+ onMouseEnter={() => showMenu('tooling')}
+ onMouseLeave={() => {
+ const timeout = setTimeout(() => setOpen(null), 200);
+ setCloseTimeout(timeout);
+ }}
>
<NavItem
- text="Tools"
- href="/tools"
+ text='Tools'
+ href='/tools'
onClick={() => showOnClickMenu('tooling')}
onMouseEnter={() => showMenu('tooling')}
hasDropdown
/>
<div
- className={`absolute left-0 top-full mt-3 transform transition-all duration-300 ease-[cubic-bezier(0.4,0,0.2,1)]
- ${
- open === 'tooling'
- ? 'opacity-100 translate-y-0 scale-100 visible'
- : 'opacity-0 -translate-y-2 scale-95 invisible'
- }
- `}
+ className={`absolute left-0 top-full mt-3 transform transition-all duration-300 ease-[cubic-bezier(0.4,0,0.2,1)] ${
+ open === 'tooling'
+ ? 'opacity-100 translate-y-0 scale-100 visible'
+ : 'opacity-0 -translate-y-2 scale-95 invisible'
+ }`}
+ onMouseEnter={() => showMenu('tooling')}
>
- <div className="rounded-xl shadow-lg border border-gray-100 bg-white/95 backdrop-blur-sm">
+ <div className='rounded-xl shadow-lg border border-gray-100 bg-white/95 backdrop-blur-sm'>
<ToolsPanel />
</div>
</div>📝 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.
| <div | |
| className="relative" | |
| onMouseLeave={() => showMenu(null)} | |
| ref={toolingRef} | |
| > | |
| <NavItem | |
| text='Tools' | |
| href='/tools' | |
| text="Tools" | |
| href="/tools" | |
| onClick={() => showOnClickMenu('tooling')} | |
| onMouseEnter={() => showMenu('tooling')} | |
| hasDropdown | |
| /> | |
| {open === 'tooling' && <ToolsPanel />} | |
| <div | |
| className={`absolute left-0 top-full mt-3 transform transition-all duration-300 ease-[cubic-bezier(0.4,0,0.2,1)] | |
| ${ | |
| open === 'tooling' | |
| ? 'opacity-100 translate-y-0 scale-100 visible' | |
| : 'opacity-0 -translate-y-2 scale-95 invisible' | |
| } | |
| `} | |
| > | |
| <div className="rounded-xl shadow-lg border border-gray-100 bg-white/95 backdrop-blur-sm"> | |
| <ToolsPanel /> | |
| </div> | |
| </div> | |
| </div> | |
| <div | |
| className='relative' | |
| ref={toolingRef} | |
| onMouseEnter={() => showMenu('tooling')} | |
| onMouseLeave={() => { | |
| const timeout = setTimeout(() => setOpen(null), 200); | |
| setCloseTimeout(timeout); | |
| }} | |
| > | |
| <NavItem | |
| text='Tools' | |
| href='/tools' | |
| onClick={() => showOnClickMenu('tooling')} | |
| onMouseEnter={() => showMenu('tooling')} | |
| hasDropdown | |
| /> | |
| <div | |
| className={`absolute left-0 top-full mt-3 transform transition-all duration-300 ease-[cubic-bezier(0.4,0,0.2,1)] ${ | |
| open === 'tooling' | |
| ? 'opacity-100 translate-y-0 scale-100 visible' | |
| : 'opacity-0 -translate-y-2 scale-95 invisible' | |
| }`} | |
| onMouseEnter={() => showMenu('tooling')} | |
| > | |
| <div className='rounded-xl shadow-lg border border-gray-100 bg-white/95 backdrop-blur-sm'> | |
| <ToolsPanel /> | |
| </div> | |
| </div> | |
| </div> |
🧰 Tools
🪛 GitHub Actions: PR testing - if Node project
[error] 246-246: prettier/prettier: Replace long string with single-quoted literal.
[error] 246-246: jsx-quotes: Unexpected usage of doublequote.
[error] 252-252: prettier/prettier: Replace "Tools" with 'Tools'
[error] 252-252: jsx-quotes: Unexpected usage of doublequote.
[error] 253-253: prettier/prettier: Replace "/tools" with '/tools'
[error] 253-253: jsx-quotes: Unexpected usage of doublequote.
[error] 259-259: max-len: This line is too long (126). Maximum allowed is 120.
[error] 260-260: prettier/prettier: Replace long string with single-quoted literal.
[error] 260-260: jsx-quotes: Unexpected usage of doublequote.
[error] 267-267: prettier/prettier: Replace "rounded-xl·shadow-lg·border·border-gray-100·bg-white/95·backdrop-blur-sm" with 'rounded-xl·shadow-lg·border·border-gray-100·bg-white/95·backdrop-blur-sm'
[error] 267-267: jsx-quotes: Unexpected usage of doublequote.
🤖 Prompt for AI Agents
In components/navigation/NavBar.tsx around lines 246 to 271, the tooling
dropdown closes immediately because it uses onMouseLeave={() => showMenu(null)}
and the dropdown panel lacks an onMouseEnter to keep it open; update the outer
div to use the same delayed hide API as the Learning dropdown (e.g.
onMouseLeave={() => showMenu(null, 200)}) and add onMouseEnter={() =>
showMenu('tooling')} to the inner panel div (the container wrapping ToolsPanel)
so hovering the panel keeps the menu open and behavior matches the Learning
dropdown pattern.
| <div | ||
| className="relative" | ||
| onMouseLeave={() => showMenu(null)} | ||
| ref={communityRef} | ||
| > | ||
| <NavItem | ||
| text='Community' | ||
| href='/community' | ||
| text="Community" | ||
| href="/community" | ||
| onClick={() => showOnClickMenu('community')} | ||
| onMouseEnter={() => showMenu('community')} | ||
| hasDropdown | ||
| /> | ||
| {open === 'community' && <CommunityPanel />} | ||
| <div | ||
| className={`absolute left-0 top-full mt-3 transform transition-all duration-300 ease-[cubic-bezier(0.4,0,0.2,1)] | ||
| ${ | ||
| open === 'community' | ||
| ? 'opacity-100 translate-y-0 scale-100 visible' | ||
| : 'opacity-0 -translate-y-2 scale-95 invisible' | ||
| } | ||
| `} | ||
| > | ||
| <div className="rounded-xl shadow-lg border border-gray-100 bg-white/95 backdrop-blur-sm"> | ||
| <CommunityPanel /> | ||
| </div> | ||
| </div> | ||
| </div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix inconsistent hover behavior and apply same pattern as Learning dropdown.
The Community dropdown has the same issues as the Tooling dropdown: it closes immediately without a timeout and lacks hover handlers on the panel to keep it open.
Apply this diff to match the Learning dropdown pattern:
<div
- className="relative"
- onMouseLeave={() => showMenu(null)}
+ className='relative'
ref={communityRef}
+ onMouseEnter={() => showMenu('community')}
+ onMouseLeave={() => {
+ const timeout = setTimeout(() => setOpen(null), 200);
+ setCloseTimeout(timeout);
+ }}
>
<NavItem
- text="Community"
- href="/community"
+ text='Community'
+ href='/community'
onClick={() => showOnClickMenu('community')}
onMouseEnter={() => showMenu('community')}
hasDropdown
/>
<div
- className={`absolute left-0 top-full mt-3 transform transition-all duration-300 ease-[cubic-bezier(0.4,0,0.2,1)]
- ${
- open === 'community'
- ? 'opacity-100 translate-y-0 scale-100 visible'
- : 'opacity-0 -translate-y-2 scale-95 invisible'
- }
- `}
+ className={`absolute left-0 top-full mt-3 transform transition-all duration-300 ease-[cubic-bezier(0.4,0,0.2,1)] ${
+ open === 'community'
+ ? 'opacity-100 translate-y-0 scale-100 visible'
+ : 'opacity-0 -translate-y-2 scale-95 invisible'
+ }`}
+ onMouseEnter={() => showMenu('community')}
>
- <div className="rounded-xl shadow-lg border border-gray-100 bg-white/95 backdrop-blur-sm">
+ <div className='rounded-xl shadow-lg border border-gray-100 bg-white/95 backdrop-blur-sm'>
<CommunityPanel />
</div>
</div>📝 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.
| <div | |
| className="relative" | |
| onMouseLeave={() => showMenu(null)} | |
| ref={communityRef} | |
| > | |
| <NavItem | |
| text='Community' | |
| href='/community' | |
| text="Community" | |
| href="/community" | |
| onClick={() => showOnClickMenu('community')} | |
| onMouseEnter={() => showMenu('community')} | |
| hasDropdown | |
| /> | |
| {open === 'community' && <CommunityPanel />} | |
| <div | |
| className={`absolute left-0 top-full mt-3 transform transition-all duration-300 ease-[cubic-bezier(0.4,0,0.2,1)] | |
| ${ | |
| open === 'community' | |
| ? 'opacity-100 translate-y-0 scale-100 visible' | |
| : 'opacity-0 -translate-y-2 scale-95 invisible' | |
| } | |
| `} | |
| > | |
| <div className="rounded-xl shadow-lg border border-gray-100 bg-white/95 backdrop-blur-sm"> | |
| <CommunityPanel /> | |
| </div> | |
| </div> | |
| </div> | |
| <div | |
| className='relative' | |
| ref={communityRef} | |
| onMouseEnter={() => showMenu('community')} | |
| onMouseLeave={() => { | |
| const timeout = setTimeout(() => setOpen(null), 200); | |
| setCloseTimeout(timeout); | |
| }} | |
| > | |
| <NavItem | |
| text='Community' | |
| href='/community' | |
| onClick={() => showOnClickMenu('community')} | |
| onMouseEnter={() => showMenu('community')} | |
| hasDropdown | |
| /> | |
| <div | |
| className={`absolute left-0 top-full mt-3 transform transition-all duration-300 ease-[cubic-bezier(0.4,0,0.2,1)] ${ | |
| open === 'community' | |
| ? 'opacity-100 translate-y-0 scale-100 visible' | |
| : 'opacity-0 -translate-y-2 scale-95 invisible' | |
| }`} | |
| onMouseEnter={() => showMenu('community')} | |
| > | |
| <div className='rounded-xl shadow-lg border border-gray-100 bg-white/95 backdrop-blur-sm'> | |
| <CommunityPanel /> | |
| </div> | |
| </div> | |
| </div> |
🧰 Tools
🪛 GitHub Actions: PR testing - if Node project
[error] 273-273: prettier/prettier: Replace "relative" with 'relative'
[error] 273-273: jsx-quotes: Unexpected usage of doublequote.
[error] 279-279: prettier/prettier: Replace "Community" with 'Community'
[error] 279-279: jsx-quotes: Unexpected usage of doublequote.
[error] 280-280: prettier/prettier: Replace "/community" with '/community'
[error] 280-280: jsx-quotes: Unexpected usage of doublequote.
[error] 286-286: max-len: This line is too long (126). Maximum allowed is 120.
[error] 288-288: prettier/prettier: Replace long string with single-quoted literal.
[error] 294-294: prettier/prettier: Replace "rounded-xl·shadow-lg·border·border-gray-100·bg-white/95·backdrop-blur-sm" with 'rounded-xl·shadow-lg·border·border-gray-100·bg-white/95·backdrop-blur-sm'
[error] 294-294: jsx-quotes: Unexpected usage of doublequote.
🤖 Prompt for AI Agents
In components/navigation/NavBar.tsx around lines 273-298, the Community dropdown
currently closes immediately and the panel lacks hover handlers; mirror the
Learning dropdown pattern by adding onMouseEnter={() => showMenu('community')}
and onMouseLeave={() => showMenu(null)} to the dropdown panel container (the div
that wraps CommunityPanel) so hovering the panel keeps it open, and ensure the
parent uses the same delayed-close behavior (use the same timeout-based hide
logic used by the Learning dropdown) so the menu doesn’t close instantly when
moving the pointer between trigger and panel.
|
Please fix the failing CI checks @maneshri00 |
What was done
Screen.Recording.2025-10-02.220025.mp4
Related issue
Closes #4427
Notes for reviewers
Summary by CodeRabbit