{
	"$schema": "https://shadcn-svelte.com/schema/registry-item.json",
	"name": "ripple-button",
	"title": "Ripple Button",
	"type": "registry:block",
	"description": "A button component with a ripple effect that appears on click, expanding from the click position.",
	"dependencies": [
		"runed"
	],
	"css": {
		"@keyframes rippling": {
			"0%": {
				"opacity": "1",
				"transform": "scale(0)"
			},
			"100%": {
				"transform": "scale(2)",
				"opacity": "0"
			}
		}
	},
	"cssVars": {
		"theme": {
			"animate-rippling": "rippling var(--duration) ease-out"
		}
	},
	"files": [
		{
			"content": "<script lang=\"ts\">\n\timport { cn } from \"$UTILS$\";\n\timport { watch } from \"runed\";\n\timport type { Snippet } from \"svelte\";\n\timport type { HTMLButtonAttributes } from \"svelte/elements\";\n\n\tinterface RippleButtonProps extends HTMLButtonAttributes {\n\t\tchildren: Snippet;\n\t\tclass?: string;\n\t\trippleColor?: string;\n\t\tduration?: string;\n\t}\n\n\tlet {\n\t\tclass: className,\n\t\tchildren,\n\t\trippleColor = \"#ffffff\",\n\t\tduration = \"600ms\",\n\t\tonclick,\n\t\t...props\n\t}: RippleButtonProps = $props();\n\n\tlet buttonRipples = $state<Array<{ x: number; y: number; size: number; key: number }>>([]);\n\n\tconst handleClick = (event: MouseEvent & { currentTarget: HTMLButtonElement }) => {\n\t\tcreateRipple(event);\n\t\tonclick?.(event);\n\t};\n\n\tconst createRipple = (event: MouseEvent & { currentTarget: HTMLButtonElement }) => {\n\t\tconst button = event.currentTarget;\n\t\tconst rect = button.getBoundingClientRect();\n\t\tconst size = Math.max(rect.width, rect.height);\n\t\tconst x = event.clientX - rect.left - size / 2;\n\t\tconst y = event.clientY - rect.top - size / 2;\n\n\t\tconst newRipple = { x, y, size, key: Date.now() };\n\t\tbuttonRipples = [...buttonRipples, newRipple];\n\t};\n\n\twatch([() => buttonRipples, () => duration], () => {\n\t\tif (buttonRipples.length > 0) {\n\t\t\tconst lastRipple = buttonRipples[buttonRipples.length - 1];\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tbuttonRipples = buttonRipples.filter((ripple) => ripple.key !== lastRipple.key);\n\t\t\t}, parseInt(duration));\n\t\t\treturn () => clearTimeout(timeout);\n\t\t}\n\t});\n</script>\n\n<button\n\tclass={cn(\n\t\t\"bg-muted text-primary relative flex cursor-pointer items-center justify-center overflow-hidden rounded-lg border-2 px-4 py-2 text-center\",\n\t\tclassName\n\t)}\n\tonclick={handleClick}\n\t{...props}\n>\n\t<div class=\"relative z-10\">\n\t\t{@render children()}\n\t</div>\n\t<span class=\"pointer-events-none absolute inset-0\">\n\t\t{#each buttonRipples as ripple}\n\t\t\t<span\n\t\t\t\tclass=\"animate-rippling absolute rounded-full\"\n\t\t\t\tstyle=\"\n\t\t\t\t\t--duration: {duration};\n\t\t\t\t\twidth: {ripple.size}px;\n\t\t\t\t\theight: {ripple.size}px;\n\t\t\t\t\ttop: {ripple.y}px;\n\t\t\t\t\tleft: {ripple.x}px;\n\t\t\t\t\tbackground-color: {rippleColor};\n\t\t\t\t\ttransform: scale(0);\n\t\t\t\t\"\n\t\t\t>\n\t\t\t</span>\n\t\t{/each}\n\t</span>\n</button>\n",
			"type": "registry:component",
			"target": "magic/ripple-button/ripple-button.svelte"
		},
		{
			"content": "export { default as RippleButton } from \"./ripple-button.svelte\";\n",
			"type": "registry:file",
			"target": "magic/ripple-button/index.ts"
		}
	]
}