Skip to content
Buttons Fancy Stable

Pressable

.md

A wrapper that gives any interactive child a consistent, cross-browser press animation — scale down on pointerdown/keydown, back to rest on release, with a static opacity fallback under reduced motion

Available for Svelte 5, React, and Vue 3.

Preview

Installation

pnpm add fancy-ui-svelte
import { Pressable } from "fancy-ui-svelte";

Usage

svelte
<script lang="ts">
	import { Pressable } from "fancy-ui-svelte";

	const REPLIES = ["Sounds good", "Not today", "Let's talk"];
</script>

<div class="flex w-full items-center justify-center p-6">
	<div class="border-border bg-card w-full max-w-[280px] rounded-[1.75rem] border p-4 shadow-sm">
		<p class="text-muted-foreground mb-3 text-xs">Quick replies</p>
		<div class="flex flex-wrap gap-2">
			{#each REPLIES as reply}
				<Pressable>
					<button
						type="button"
						class="border-border bg-muted text-foreground rounded-full border px-3.5 py-1.5 text-sm"
					>
						{reply}
					</button>
				</Pressable>
			{/each}
		</div>
		<p class="text-muted-foreground mt-4 text-xs">
			Tap a chip (or focus one and press Space/Enter) — it gives under the press, then settles back
			the instant you let go. With reduced motion it dims instead of shrinking.
		</p>
	</div>
</div>

Examples

Basic Usage

With Haptics

Touch-only vibration patterns alongside the press scale.

Props

PropTypeDefaultDescription
scale number0.97Target scale() factor while pressed
haptic false | "light" | "medium" | "heavy" | "success" | "error"falseTouch-only vibration pattern fired on pointerdown; false never vibrates
disabled booleanfalseSuppresses every listener; data-pressed never appears
class string-Additional CSS classes, merged onto the wrapper
ref HTMLDivElement | nullnullBindable reference to the wrapper element

Slots

SlotDescription
children Exactly one interactive child (documented, not enforced at runtime)