Skip to content
Template Empire
Browse components

Press Ripple Button

A free native button with feedback that starts where you press.

The Saturday workshop

Make room for something handmade.

A morning of clay, conversation and a first pot to take home. Six places at the table, materials included.

Saturday, 10am to 1pm

Press Ripple Button is a free ripple button React component for Next.js and Tailwind. Each activation sends one soft radial pulse from the pointer position, while keyboard and assistive activation start at the centre.

The real button keeps native form, focus and disabled behaviour. Only the decorative disc's transform and opacity animate; reduced-motion users receive an instant pressed highlight without expansion.

Install

Add the @te registry to your components.json once:

{
  "registries": {
    "@te": "https://templateempire.io/r/{name}.json"
  }
}

Then install the component:

npx shadcn@latest add @te/btn-press-ripple

Usage

import { BtnPressRipple } from "@/components/ui/btn-press-ripple";

export default function ReservationForm() {
  return (
    <form action="/reservations" method="post">
      <BtnPressRipple type="submit" name="workshop" value="clay">
        Reserve my place
      </BtnPressRipple>
    </form>
  );
}

Props

PropTypeDefaultDescription
childrenReactNoderequiredVisible accessible label content. Do not nest interactive controls.
type"button" | "submit" | "reset""button"Native button behaviour; opt into submit or reset explicitly.
disabledbooleanfalseNative disabled state, preventing activation and ripple feedback.
onClickMouseEventHandler<HTMLButtonElement>undefinedReceives each native click once. preventDefault keeps its normal meaning.
classNamestringundefinedRoot classes for dimensions, radius and typography. Labels wrap.
...native propsButtonHTMLAttributes<HTMLButtonElement>undefinedNative form, name, value, style and accessible description attributes pass through.

Customisation

Scope --press-ripple-surface, --press-ripple-label and --press-ripple-ink to your semantic colour pair, and --press-ripple-duration to the expansion beat. Defaults are foreground, background, background and var(--dur-3, 600ms). Retest contrast with your own pair, including the translucent pulse. Use className for compact, full-width or rounded-corner actions; the focus outline sits outside the clipped decoration.

.print-card {
  --press-ripple-surface: var(--primary);
  --press-ripple-label: var(--primary-foreground);
  --press-ripple-ink: var(--foreground);
  --press-ripple-duration: 450ms;
}

Frequently asked questions

Is Press Ripple Button free for commercial use?
Yes. The repository's MIT with Commons Clause licence permits personal and commercial products, including client websites. Keep the licence notice in your source. Selling or repackaging the component catalogue itself is excluded; see LICENCE.md for the full terms.
How does the ripple button support keyboard and reduced motion?
Enter and Space activate the native button and centre the decoration. A distinct focus outline remains outside the clipping layer. Reduced motion skips the expanding disc, including when the preference changes during an activation.
How do I customise the ripple colour, timing and shape?
Override --press-ripple-surface and --press-ripple-label with a contrasting semantic pair, --press-ripple-ink with the pulse colour and --press-ripple-duration with its expansion time. Use className for size and corner radius. CSS animates one transient disc with no ambient loop or animation-library dependency; physical-device performance has not been certified.

Related components

Build the rest of the experienceExplore complete Next.js templates from Template Empire to give your actions a considered home.Explore Template Empire templates