Building an Animated User Account Avatar Component
A deep dive into creating interactive dropdown menus with smooth spring animations, expandable sections, and accessibility features using Radix UI and Motion.
In this tutorial, we'll build the User Account Avatar component step by step. Scroll through to see how each feature is added - the component preview on the left will update as you progress.
Avatar Trigger
Start with a simple avatar button as the trigger element.
<button className="rounded-full border"> <img src={user.avatar} alt="Avatar" className="rounded-full" width={48} height={48} /></button>Popover Container
Wrap the avatar with Radix UI's Popover for accessibility.
import { Popover, PopoverTrigger, PopoverContent } from "@/components/ui/popover";<Popover> <PopoverTrigger asChild> {/* Avatar button */} </PopoverTrigger> <PopoverContent sideOffset={8}> {/* Popover content */} </PopoverContent></Popover>Section Buttons
Add interactive section buttons with state management.
const [activeSection, setActiveSection] = useState<string | null>(null);const handleClick = (section: string) => { setActiveSection( activeSection === section ? null : section );};Spring Animation
Add spring animations for smooth expansion effects.
<motion.div initial={{ opacity: 0, height: 0 }} animate={{ opacity: 1, height: "auto" }} exit={{ opacity: 0, height: 0 }} transition={{ type: "spring", duration: 0.25, bounce: 0 // No overshoot for professional feel }}>Why spring? Springs feel more natural than linear timing. Why bounce: 0? No overshoot keeps it professional.
Blur Effect
Add blur transition for a materializing effect.
initial={{ opacity: 0, height: 0, filter: "blur(10px)"}}animate={{ opacity: 1, height: "auto", filter: "blur(0px)"}}The blur mimics how our eyes focus when something appears.
Progress Bars
Animate progress bars with spring physics.
<motion.div initial={{ width: 0 }} animate={{ width: `${progress}%` }} transition={{ type: "spring", stiffness: 300, damping: 30, duration: 0.4 }}/>Higher stiffness = snappier. Longer duration lets users see the progress.
Complete
The final component with all features combined.
// The complete component includes:✓ Accessible Radix UI popover✓ Spring animations with no bounce✓ Blur transition effect✓ Animated progress bars✓ Reduced motion support✓ Keyboard accessibilityTry it! Click the avatar and explore the sections.
Key Takeaways
After building this component, you've learned:
- Spring animations with
bounce: 0-0.1feel professional and natural - Keep durations under 300ms for responsive UI
- Combine opacity + height + blur for polished expand/collapse effects
- Always support reduced motion with
useReducedMotion()from Motion - Use Radix primitives for built-in accessibility
- Test with keyboard and screen readers
Install the Component
Want to use this component in your project?
npx smoothui-cli add user-account-avatarCheck out the full documentation for all props and variations.