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-rippleUsage
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
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | required | Visible accessible label content. Do not nest interactive controls. |
| type | "button" | "submit" | "reset" | "button" | Native button behaviour; opt into submit or reset explicitly. |
| disabled | boolean | false | Native disabled state, preventing activation and ripple feedback. |
| onClick | MouseEventHandler<HTMLButtonElement> | undefined | Receives each native click once. preventDefault keeps its normal meaning. |
| className | string | undefined | Root classes for dimensions, radius and typography. Labels wrap. |
| ...native props | ButtonHTMLAttributes<HTMLButtonElement> | undefined | Native 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.