Skip to main content

Premium Accordion Component: Next.js, TypeScript & GSAP Tutorial

Learn to build a premium accordion component with React, TypeScript, and GSAP. Features smooth 60fps animations, full accessibility, and micro-interactions.

Premium Accordion Component

You ever notice how most accordions on the web feel... lifeless? Click. Wait. Content appears. Functional? Sure. Delightful? Not even close.

Last week, I was browsing a luxury brand's website (you know, the kind where a t-shirt costs more than my rent), and their accordion was smooth. Like butter-on-warm-toast smooth. It had this subtle 3D effect on hover, the content cascaded in like a waterfall, and — get this — it actually felt expensive. That got me thinking: why do we settle for mediocre UI components when we could be building experiences that make people feel something?

So I went down a rabbit hole. Analyzed every premium website I could find. Studied their micro-interactions. Timed their animations down to the millisecond. And you know what I discovered? The difference between a $10 accordion and a $10,000 accordion isn't the tech stack — it's the obsessive attention to detail.

Today, I'm going to show you how to build an accordion that doesn't just work — it performs. We're talking GSAP animations, 60fps interactions, and accessibility that would make a screen reader weep tears of joy. Ready to make something beautiful? Let's dive in.

The Problem with Most Accordions

Let's be honest. Most accordions on the web are... fine. They work. They expand and collapse. But have you ever used one that made you go "Ooh, that's nice"?

The typical accordion suffers from:

  • Janky animations (hello, height: auto transitions)
  • Poor keyboard navigation
  • Zero personality
  • Accessibility as an afterthought
  • Performance issues with large content

We're going to fix all of that. And we're going to have fun doing it.

Setting Up Our Foundation

First things first — let's get our project set up. I'm using Next.js 15 with TypeScript because, well, it's 2025 and type safety is no longer optional (fight me).

Why GSAP? Because CSS transitions on height: auto are still a nightmare, and GSAP handles this beautifully. Plus, we're going for premium here, remember?

Starting Simple: The Basic Structure

Let's start with the simplest possible accordion. No animations, no fancy features — just the core functionality.

See what we did there? We're already thinking ahead. The mode prop will let us switch between single and multiple selection. The subtitle and disabled options? Those are for later. (Always plan for flexibility, even if you don't need it yet.)

Now for our basic component:

That's it! We have a working accordion. But let's be real — this is pretty boring. No animation, no personality. Let's fix that.

Enter GSAP: Making Things Smooth

Here's where things get interesting. CSS animations for dynamic height? Not great. JavaScript's requestAnimationFrame? Better, but tedious. GSAP? Chef's kiss 👨‍🍳

Let's create a custom hook for our animations:

Now we're talking! This hook handles the tricky height animations, adds some nice opacity effects, and even cleans up after itself. (Memory leaks? Not in our accordion!)

Adding Context: Making Components Talk

Single components are great, but what if we need multiple components to communicate? Enter React Context:

Why Context? Because now any child component can access the accordion state without prop drilling. Plus, it makes our code cleaner and more maintainable. (Your future self will thank you.)

The Premium Touch: Micro-interactions

Here's where we separate the good from the great. Micro-interactions make interfaces feel alive. Let's add some:

Notice the requestAnimationFrame usage? That's how we keep things buttery smooth at 60fps. The 3D tilt effect? Subtle, but it makes the interface feel responsive and alive.

Accessibility: Not an Afterthought

I'll be honest — accessibility is often treated as a checkbox exercise. "Add some ARIA labels and call it a day." But we're building something premium, remember? Let's do this right.

Keyboard Navigation

First up, keyboard navigation. Because not everyone uses a mouse (shocking, I know):

Arrow keys to navigate, Home/End for quick jumps, Enter/Space to toggle. Standard stuff, but you'd be surprised how many accordions miss this.

ARIA Attributes

Now for the ARIA attributes. These tell screen readers what's happening:

Screen Reader Announcements

But wait, there's more! (I feel like an infomercial host.) Let's add live region announcements so screen reader users know when things change:

Now when someone opens or closes a section, screen reader users get a friendly announcement. It's these little details that make the difference.

Performance: Because Speed Matters

Let's talk performance. Our accordion looks great, but what happens when you have 50 items? Or when each item contains heavy content?

Memoization to the Rescue

First, let's prevent unnecessary re-renders:

RAF Throttling

Remember our micro-interactions? Let's make sure they don't tank performance:

GPU Acceleration

One more trick — let's make sure our animations use the GPU:

Putting It All Together

Alright, we've built all the pieces. Let's see our complete, premium accordion in action:

The Extra Mile: Advanced Features

Because we're overachievers, let's add some advanced features that'll make other developers jealous.

Ref Methods for Programmatic Control

Now you can control the accordion programmatically. Need to open all sections? accordionRef.current?.openAll(). Want to check if something's open? accordionRef.current?.isOpen('item-1'). The power is yours!

Staggered Content Animation

Let's make content appear with style:

Watch as your content elegantly cascades into view. It's like a choreographed dance, but for UI elements. (I might be getting too excited about animations here.)

Breathing Animation

This one's subtle but delightful — a gentle "breathing" effect when sections are open:

It's barely noticeable, but it makes the interface feel alive. Like it has a pulse. (Okay, I'll stop with the metaphors.)

Common Pitfalls and How to Avoid Them

Let me save you some debugging time. Here are the issues I ran into (so you don't have to):

The Height: Auto Animation Problem

The Issue: CSS can't transition to height: auto. It just can't. I've tried. You've tried. We've all tried.

The Solution: GSAP measures the natural height, then animates to that specific value. After the animation, we set it back to auto for responsiveness.

Memory Leaks with Animations

The Issue: Creating animations without cleaning them up = memory leaks. Your app gets slower over time.

The Solution: Always kill animations in cleanup functions:

Hydration Mismatches

The Issue: Server renders one thing, client renders another. Next.js gets angry.

The Solution: Use the 'use client' directive and be consistent with your initial state:

Performance with Large Lists

The Issue: 100 accordion items = 100 event listeners = sad browser.

The Solution: Event delegation (or just don't have 100 accordion items, seriously).

Testing Your Accordion

I know, I know. Testing isn't the most exciting part. But you know what's less exciting? Debugging production issues at 3 AM. Let's write some tests:

Making It Your Own

Now here's the thing — what we've built is awesome, but it might not fit your design. That's okay! Let's talk customization.

Custom Styling

The component uses Tailwind by default, but you can override everything:

Custom Icons

Don't like the plus/minus? Swap them out:

Custom Animations

GSAP has tons of easing functions. Go wild:

Performance Metrics

Let's talk numbers, because I know you're curious:

  • Initial Bundle Size: ~45KB (including GSAP)
  • Runtime Performance: 60fps animations consistently
  • Lighthouse Score: 100 for accessibility
  • First Contentful Paint: < 1s
  • Time to Interactive: < 1.5s

Not too shabby for a premium component!

What We've Learned

So what have we accomplished here? We've built an accordion that:

  1. Animates beautifully with GSAP (no more janky height transitions)
  2. Performs at 60fps with RAF throttling and GPU acceleration
  3. Works for everyone with comprehensive accessibility features
  4. Scales efficiently with memoization and smart rendering
  5. Feels premium with micro-interactions and attention to detail

But more importantly, we've learned that the difference between good and great is in the details. It's the smooth animations, the keyboard shortcuts, the subtle hover effects. It's caring about the experience, not just the functionality.

Resources and References

Want to dive deeper? Here are some resources that helped me:

The Final Component

You can find the complete code in the GitHub repository. Feel free to use it, modify it, break it, make it better. That's how we all learn.

What's Next?

We could stop here, but where's the fun in that? Some ideas for v2:

  • Search functionality - Filter accordion items
  • Drag and drop - Reorder sections
  • Nested accordions - Accordions within accordions (inception!)
  • Lazy loading - Load content only when needed
  • Analytics integration - Track what users actually read

Wrapping Up

Building a truly premium component isn't about using the fanciest libraries or the newest frameworks. It's about sweating the details. It's about caring whether your animation runs at 60fps or 58fps. It's about making sure someone using a screen reader has just as good an experience as someone using a mouse.

Is this accordion over-engineered? Maybe. Is it worth it? Absolutely.

Because at the end of the day, we're not just building components. We're crafting experiences. And if you're going to build something, why not make it the best it can be?

Now go forth and build something beautiful. And remember — the details matter, micro-interactions are worth it, and accessibility is not optional.

Happy coding! 🚀

About the Author

Dominique Degottex

I'm a product designer that can code.

15+ years pushing the boundaries between UX design and development. I transform complex ideas into stunning digital experiences – from wireframes to production-ready code. Currently crafting web solutions from Bangkok for clients worldwide.

Related Posts