This component no longer exists. It was in Svelte Animations’s manifest when we first indexed it and is not there now — the registry served its inventory on 2026-08-05 and this item was not on it. The install command below will fail. It is kept here because a tutorial somewhere still tells people to run it.
Ripple Button
svelte-animations/ripple-buttonRemovedBlock
A button component with a ripple effect that appears on click, expanding from the click position.
Install it
npx shadcn@latest add https://sv-animations.vercel.app/r/ripple-button.jsonSource
1<script lang="ts">2 import { cn } from "$UTILS$";3 import { watch } from "runed";4 import type { Snippet } from "svelte";5 import type { HTMLButtonAttributes } from "svelte/elements";67 interface RippleButtonProps extends HTMLButtonAttributes {8 children: Snippet;9 class?: string;10 rippleColor?: string;11 duration?: string;12 }1314 let {15 class: className,16 children,17 rippleColor = "#ffffff",18 duration = "600ms",19 onclick,20 ...props21 }: RippleButtonProps = $props();2223 let buttonRipples = $state<Array<{ x: number; y: number; size: number; key: number }>>([]);2425 const handleClick = (event: MouseEvent & { currentTarget: HTMLButtonElement }) => {26 createRipple(event);27 onclick?.(event);28 };2930 const createRipple = (event: MouseEvent & { currentTarget: HTMLButtonElement }) => {31 const button = event.currentTarget;32 const rect = button.getBoundingClientRect();33 const size = Math.max(rect.width, rect.height);34 const x = event.clientX - rect.left - size / 2;35 const y = event.clientY - rect.top - size / 2;3637 const newRipple = { x, y, size, key: Date.now() };38 buttonRipples = [...buttonRipples, newRipple];39 };4041 watch([() => buttonRipples, () => duration], () => {42 if (buttonRipples.length > 0) {43 const lastRipple = buttonRipples[buttonRipples.length - 1];44 const timeout = setTimeout(() => {45 buttonRipples = buttonRipples.filter((ripple) => ripple.key !== lastRipple.key);46 }, parseInt(duration));47 return () => clearTimeout(timeout);48 }49 });50</script>5152<button53 class={cn(54 "bg-muted text-primary relative flex cursor-pointer items-center justify-center overflow-hidden rounded-lg border-2 px-4 py-2 text-center",55 className56 )}57 onclick={handleClick}58 {...props}59>60 <div class="relative z-10">61 {@render children()}62 </div>63 <span class="pointer-events-none absolute inset-0">64 {#each buttonRipples as ripple}65 <span66 class="animate-rippling absolute rounded-full"67 style="68 --duration: {duration};69 width: {ripple.size}px;70 height: {ripple.size}px;71 top: {ripple.y}px;72 left: {ripple.x}px;73 background-color: {rippleColor};74 transform: scale(0);75 "76 >77 </span>78 {/each}79 </span>80</button>
What it pulls in
npm packages
