feat: add profile dropdown component with animated icons#128
feat: add profile dropdown component with animated icons#128Abhijit-Jha merged 6 commits intoitshover:masterfrom
Conversation
|
@Prathik018 is attempting to deploy a commit to the itshover-oss Team on Vercel. A member of the Team first needs to authorize it. |
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a new React TSX example component, Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant ProfileDropdown
participant DropdownItem
participant AnimatedIcon
participant DarkModeState
User->>ProfileDropdown: open dropdown / hover item
ProfileDropdown->>DropdownItem: render item (isAnimated)
DropdownItem->>AnimatedIcon: mouseenter / focus -> start animation
AnimatedIcon-->>DropdownItem: animation active
User->>ProfileDropdown: click Dark Mode toggle
ProfileDropdown->>DarkModeState: toggle value
DarkModeState-->>ProfileDropdown: updated state
ProfileDropdown->>DropdownItem: update rightElement visuals
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@components/examples/profile-dropdown.tsx`:
- Around line 13-20: The menu rows are rendered as inert divs—update the
DropdownItem component to accept an onClick?: () => void and href?: string (or a
generic action prop) and render a semantic interactive element: if href is
provided render an <a> with role/link behavior, otherwise render a <button> for
actionable items; keep non-actionable items as a <div> or use aria-disabled.
Replace the root div in DropdownItem with the chosen element, forward refs, and
wire focus and blur handlers to call the same animation toggles currently used
for hover so the AnimatedIcon (the prop typed as
React.ComponentType<AnimatedIconProps &
React.RefAttributes<AnimatedIconHandle>>) animates on keyboard focus as well as
mouse hover. Ensure keyboard activation triggers the onClick handler and
preserve rightElement rendering.
- Around line 109-120: The dark-mode toggle button lacks accessible labeling and
explicit type; update the button in the ProfileDropdown component (the element
using onClick={() => setDarkMode(!darkMode)} and the darkMode state) to include
type="button", an accessible name (e.g., aria-label="Toggle dark mode" or a
visually hidden label) and an explicit toggle state using
aria-pressed={darkMode} (or aria-checked with role="switch" if you prefer switch
semantics) so assistive tech knows what the control is and whether it is active.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ea834af0-085c-412a-b69d-267a3e1cef98
📒 Files selected for processing (2)
components/examples/profile-dropdown.tsxlib/examples.ts
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
components/examples/profile-dropdown.tsx (1)
43-45:⚠️ Potential issue | 🟡 MinorDon't leave the dark-mode row as a dead focus target.
The
rightElementpath still renders a focusabledivwith pointer styling, but the row itself has no action. That adds an inert tab stop before the real toggle and makes most of the row look clickable when it is not. Either make the whole row toggle dark mode, or removetabIndex/interactive styling and let the nested button own the interaction.Also applies to: 80-89
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/examples/profile-dropdown.tsx` around lines 43 - 45, The dark-mode row renders an interactive-looking wrapper (see baseClasses and the rightElement container) but the actual toggle lives inside, creating an inert tab stop; either wire the entire row to toggle dark mode (add the toggle handler to the row container and make it keyboard-accessible) or remove interactive affordances from the wrapper (remove tabIndex, role, and cursor/pointer styling from the rightElement/div) so only the nested button is focusable and clickable; apply the same fix to the other instance around lines 80-89 to eliminate the dead focus target.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@components/examples/profile-dropdown.tsx`:
- Around line 136-155: The demo DropdownItem instances (DropdownItem with props
icon, label, href, isAnimated) currently use href="proxy.php?url=https%3A%2F%2Fgithub.com%2F%23" which mutates the URL;
update these demo entries to avoid placeholder fragment links by either
rendering them as non-link controls (remove href and render as a
button/interactive element) or by turning them into disabled/non-interactive
items until real routes exist; ensure you change the three instances labeled
"Profile", "Account Settings", and "Notifications" to use a button variant or no
href and keep isAnimated behavior intact.
---
Duplicate comments:
In `@components/examples/profile-dropdown.tsx`:
- Around line 43-45: The dark-mode row renders an interactive-looking wrapper
(see baseClasses and the rightElement container) but the actual toggle lives
inside, creating an inert tab stop; either wire the entire row to toggle dark
mode (add the toggle handler to the row container and make it
keyboard-accessible) or remove interactive affordances from the wrapper (remove
tabIndex, role, and cursor/pointer styling from the rightElement/div) so only
the nested button is focusable and clickable; apply the same fix to the other
instance around lines 80-89 to eliminate the dead focus target.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 57aaef03-b2ba-4b42-98a6-4baad550d865
📒 Files selected for processing (1)
components/examples/profile-dropdown.tsx
|
Hey @Prathik018
Thank you! 🙂 |
|
Hi @Abhijit-Jha I’ve removed the console.log statements as requested. Here is a short demo video of the Profile Dropdown component: |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@components/examples/profile-dropdown.tsx`:
- Around line 80-89: The rightElement branch returns a wrapper div that omits
the shared group hover classes, so content (which relies on a parent "group" for
hover styling) doesn't receive hover styles; update the wrapper returned in the
rightElement branch (the div around content in the rightElement conditional) to
reuse the shared wrapper classes (including "group" and the same "flex
items-center rounded-xl px-4 py-3 w-full hover:bg-muted transition-all") or at
minimum add "group" to its className so content's group-based hover styles
apply; keep existing event handlers startAnimation and stopAnimation unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: bdfc931b-e8d6-425b-98b4-c5c3a5abd0e6
📒 Files selected for processing (1)
components/examples/profile-dropdown.tsx
| if (rightElement) { | ||
| return ( | ||
| <div | ||
| className="flex items-center rounded-xl px-4 py-3 w-full hover:bg-muted transition-all" | ||
| onMouseEnter={startAnimation} | ||
| onMouseLeave={stopAnimation} | ||
| > | ||
| {content} | ||
| </div> | ||
| ); |
There was a problem hiding this comment.
Restore the shared hover styling in the rightElement branch.
content depends on a parent group, but this wrapper drops it, so the Dark Mode row never applies the same icon/text hover state as the other items. Reusing the shared wrapper classes here, or at least adding group, keeps this variant visually consistent.
Proposed fix
if (rightElement) {
return (
<div
- className="flex items-center rounded-xl px-4 py-3 w-full hover:bg-muted transition-all"
+ className="group flex w-full items-center rounded-xl px-4 py-3 transition-all hover:bg-muted"
onMouseEnter={startAnimation}
onMouseLeave={stopAnimation}
>
{content}
</div>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@components/examples/profile-dropdown.tsx` around lines 80 - 89, The
rightElement branch returns a wrapper div that omits the shared group hover
classes, so content (which relies on a parent "group" for hover styling) doesn't
receive hover styles; update the wrapper returned in the rightElement branch
(the div around content in the rightElement conditional) to reuse the shared
wrapper classes (including "group" and the same "flex items-center rounded-xl
px-4 py-3 w-full hover:bg-muted transition-all") or at minimum add "group" to
its className so content's group-based hover styles apply; keep existing event
handlers startAnimation and stopAnimation unchanged.
|
Fix the formatting issue |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
components/examples/profile-dropdown.tsx (1)
78-87: Add focus handlers for keyboard accessibility consistency.The
hrefbranch (lines 68-71) andbuttonbranch (lines 97-98) both wireonFocus/onBlurto trigger icon animations, but thisrightElementbranch does not. When a keyboard user tabs to the nested toggle button, the icon animation won't trigger because focus events on the child don't callstartAnimation.♻️ Proposed fix
if (rightElement) { return ( <div className="group hover:bg-muted flex w-full items-center rounded-xl px-4 py-3 transition-all" onMouseEnter={startAnimation} onMouseLeave={stopAnimation} + onFocus={startAnimation} + onBlur={stopAnimation} > {content} </div> ); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/examples/profile-dropdown.tsx` around lines 78 - 87, The rightElement branch is missing keyboard focus handlers so icon animations don't trigger for keyboard users; update the wrapper div in the rightElement branch (the element that currently uses onMouseEnter={startAnimation} and onMouseLeave={stopAnimation}) to also include onFocus={startAnimation} and onBlur={stopAnimation} so focus events call the same startAnimation/stopAnimation handlers and match the href and button branches.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@components/examples/profile-dropdown.tsx`:
- Around line 78-87: The rightElement branch is missing keyboard focus handlers
so icon animations don't trigger for keyboard users; update the wrapper div in
the rightElement branch (the element that currently uses
onMouseEnter={startAnimation} and onMouseLeave={stopAnimation}) to also include
onFocus={startAnimation} and onBlur={stopAnimation} so focus events call the
same startAnimation/stopAnimation handlers and match the href and button
branches.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 50ca39b5-988a-45b2-a235-9b3b59f18e2e
📒 Files selected for processing (1)
components/examples/profile-dropdown.tsx
Added a new Profile-Dropdown component.
Features:
Summary by CodeRabbit