Join our Discord Community

React Ripple Button

React ripple button with Material Design click animations. Position-aware ripple effects and multiple color variants with TypeScript and shadcn/ui styling.

Building Material Design interactions?

Join our Discord community for help from other developers.


Button feedback is everywhere—form submissions, purchase flows, navigation. But most buttons just change color or scale slightly. Flat. Minimal. Forgettable. Meanwhile, users expect rich tactile feedback that responds to their exact interaction. This React component gives you Material Design ripple effects that emanate from the precise click position, creating satisfying visual waves that make every interaction feel responsive and intentional.

Ripple emanates from click position

Click anywhere on the button to see the ripple effect originate from that exact spot:

Loading component...

Built for React applications with TypeScript and Next.js. Uses Framer Motion for physics-based ripple animations that feel natural and fluid. The ripple isn't random—it calculates the exact click coordinates and expands outward with proper easing. Class Variance Authority provides type-safe variants while maintaining consistent Material Design principles. Perfect for shadcn/ui design systems.

Why most button feedback feels disconnected

Developers add a basic hover state and think they're done with interaction design. Maybe they throw in a scale transform for "premium" feel. The problem? Users touch a specific spot, but the feedback comes from everywhere. It's not responsive to their action—it's just a generic animation triggered by proximity.

Material Design solved this with ripple effects that originate from the interaction point. The visual feedback connects directly to user input. The expanding circle creates anticipation and confirms the action was registered. It's not just decoration—it's functional communication.

This component handles the complex coordinate calculation, animation orchestration, and cleanup automatically. Multiple ripples can overlap for rapid clicking. The animation respects accessibility preferences. And the variant system ensures visual hierarchy while maintaining the same delightful interaction pattern.

Installation

npx shadcn@latest add https://www.shadcn.io/registry/ripple-button.json
npx shadcn@latest add https://www.shadcn.io/registry/ripple-button.json
pnpm dlx shadcn@latest add https://www.shadcn.io/registry/ripple-button.json
bunx shadcn@latest add https://www.shadcn.io/registry/ripple-button.json

Examples

Button Variants

Five Material Design-inspired variants for different UI contexts:

Loading component...

Size Options

Four sizes optimized for different use cases and touch targets:

Loading component...

Features

  • Click-position ripples that emanate from exact interaction coordinates with physics-based expansion
  • Material Design variants including default, destructive, outline, secondary, and ghost styles
  • Size variations with responsive scaling (sm, default, lg, icon) using Class Variance Authority
  • Framer Motion animations with customizable transition duration and easing curves
  • Multiple ripple support allowing overlapping effects for rapid interactions
  • Automatic cleanup removing ripple elements after animation completion
  • TypeScript definitions with complete interface definitions and variant types
  • Accessibility integration respecting prefers-reduced-motion for inclusive design
  • shadcn/ui compatibility using design tokens and utility classes

Use Cases

This free open source React component works perfectly for:

  • Call-to-action buttons - Primary actions and form submissions built with Next.js
  • Interactive dashboards - Action buttons with visual feedback using TypeScript
  • E-commerce interfaces - Add to cart, purchase, and navigation buttons with shadcn/ui
  • Gaming interfaces - Interactive buttons that provide satisfying visual feedback
  • Mobile-first designs - Touch-responsive buttons that feel native on all devices
  • Admin panels - Professional interfaces with Material Design consistency

API Reference

RippleButton

The main component for Material Design ripple button interactions.

PropTypeDefaultDescription
childrenReact.ReactNoderequiredButton content to display
variant'default' | 'destructive' | 'outline' | 'secondary' | 'ghost''default'Visual style variant
size'default' | 'sm' | 'lg' | 'icon''default'Button size variant
scalenumber10Maximum scale factor for ripple animation
transitionTransition{ duration: 0.6, ease: 'easeOut' }Framer Motion transition for ripple effect
rippleClassNamestring-Additional CSS classes for ripple elements
classNamestring-Additional CSS classes for button
onClick(event: React.MouseEvent) => void-Click handler function
disabledbooleanfalseDisables button and prevents ripple effects
...propsButtonHTMLAttributes-All native button props supported

Variant Specifications

VariantBackgroundTextRippleUse Case
defaultPrimary blueWhiteLight overlayMain actions, CTAs
destructiveRedWhiteLight overlayDelete, remove actions
outlineTransparentPrimaryPrimary tintSecondary actions
secondaryMutedPrimaryPrimary tintSubtle actions
ghostTransparentPrimaryPrimary tintMinimal interactions

Size Specifications

SizeHeightPaddingRipple ScaleUse Case
sm36px12px 16px8xCompact interfaces, inline actions
default40px16px 24px10xStandard buttons, forms
lg44px20px 32px12xHero sections, primary CTAs
icon40px × 40px8px10xIcon-only actions, toolbars

Common gotchas

Ripple overflow issues: The button uses overflow: hidden to contain ripples, but parent containers with overflow: visible might show ripples bleeding out. Ensure proper container styling for clean boundaries.

Performance with rapid clicking: Multiple rapid clicks create overlapping ripples that can impact performance on low-end devices. The component handles cleanup, but consider debouncing for very high-frequency interactions.

Touch vs mouse coordinates: Touch events and mouse events report coordinates differently. The component normalizes these, but custom click handlers should be aware of the event type differences.

Ripple color inheritance: Ripple colors are calculated from the button variant's theme colors. Custom button colors might need corresponding ripple color overrides via the rippleClassName prop.

Animation interruption: If the button is unmounted during a ripple animation, cleanup might not complete properly. This is rare but can happen in dynamic interfaces with conditional rendering.

Z-index layering: Ripples are positioned absolutely within the button but can interfere with child elements that have their own positioning. Keep button content simple or adjust z-index values carefully.

You might also like

Explore other interactive button components for React applications:

Questions developers actually ask