Skip to content

feat: add profile dropdown component with animated icons#128

Merged
Abhijit-Jha merged 6 commits intoitshover:masterfrom
Prathik018:feat/profile-dropdown
Mar 7, 2026
Merged

feat: add profile dropdown component with animated icons#128
Abhijit-Jha merged 6 commits intoitshover:masterfrom
Prathik018:feat/profile-dropdown

Conversation

@Prathik018
Copy link
Copy Markdown
Contributor

@Prathik018 Prathik018 commented Mar 6, 2026

Added a new Profile-Dropdown component.

Features:

  • User avatar with gradient background
  • Profile, Account Settings, Notifications menu items
  • Dark mode toggle using Button
  • Logout action
  • Animated icons using itshover icon system

Summary by CodeRabbit

  • New Features
    • Added a profile dropdown menu with Profile, Account Settings, Notifications, Dark Mode toggle, and Logout.
    • Animated icon effects on hover/focus for improved visual feedback.
    • Added the profile dropdown as a new example in the examples gallery.

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Mar 6, 2026

@Prathik018 is attempting to deploy a commit to the itshover-oss Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 6, 2026

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a new React TSX example component, ProfileDropdown (default export), implementing a self-contained profile dropdown with animated icons and a Dark Mode toggle, and registers the example in the examples registry.

Changes

Cohort / File(s) Summary
New ProfileDropdown component
components/examples/profile-dropdown.tsx
Adds default-exported ProfileDropdown component and a non-exported DropdownItem subcomponent and prop types. Implements local darkMode state, hover/focus-triggered icon animations, a right-side Dark Mode toggle button, and items: Profile, Account Settings, Notifications, Dark Mode, Logout. No external data fetching.
Examples registry update
lib/examples.ts
Imports ProfileDropdown and adds a new "Profile Dropdown" entry to the examples registry with metadata (componentName, slug, filePath, component, description, tags).

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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hop where little icons wink and play,
A dropdown blooms and dances on display,
A moon-button flips the sky to night,
I nibble code until it’s just right,
Cheeks full of bugs, I bound away.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately describes the main change: adding a new profile dropdown component with animated icons, which directly matches the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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

📥 Commits

Reviewing files that changed from the base of the PR and between 094e6a8 and 1f8666b.

📒 Files selected for processing (2)
  • components/examples/profile-dropdown.tsx
  • lib/examples.ts

Comment thread components/examples/profile-dropdown.tsx
Comment thread components/examples/profile-dropdown.tsx
Copy link
Copy Markdown
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

♻️ Duplicate comments (1)
components/examples/profile-dropdown.tsx (1)

43-45: ⚠️ Potential issue | 🟡 Minor

Don't leave the dark-mode row as a dead focus target.

The rightElement path still renders a focusable div with 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 remove tabIndex/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

📥 Commits

Reviewing files that changed from the base of the PR and between 1f8666b and f9cc9fe.

📒 Files selected for processing (1)
  • components/examples/profile-dropdown.tsx

Comment thread components/examples/profile-dropdown.tsx
@Abhijit-Jha
Copy link
Copy Markdown
Member

Hey @Prathik018

  1. Could you please remove all the console.log statements? They are not necessary.
  2. Please share a short video of the example component you created, demonstrating its responsiveness. Also show the animation toggle being turned on and off, so both states are visible.

Thank you! 🙂

@Prathik018
Copy link
Copy Markdown
Contributor Author

Hi @Abhijit-Jha

I’ve removed the console.log statements as requested.

Here is a short demo video of the Profile Dropdown component:
https://www.loom.com/share/dfbab495e86e464e86975802af190075

Copy link
Copy Markdown
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

🤖 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

📥 Commits

Reviewing files that changed from the base of the PR and between 84a0881 and 2fea1c1.

📒 Files selected for processing (1)
  • components/examples/profile-dropdown.tsx

Comment on lines +80 to +89
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>
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

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.

@Abhijit-Jha
Copy link
Copy Markdown
Member

Fix the formatting issue

Copy link
Copy Markdown
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.

🧹 Nitpick comments (1)
components/examples/profile-dropdown.tsx (1)

78-87: Add focus handlers for keyboard accessibility consistency.

The href branch (lines 68-71) and button branch (lines 97-98) both wire onFocus/onBlur to trigger icon animations, but this rightElement branch 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 call startAnimation.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2fea1c1 and 01c6f95.

📒 Files selected for processing (1)
  • components/examples/profile-dropdown.tsx

@Abhijit-Jha Abhijit-Jha merged commit 8adf04c into itshover:master Mar 7, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants