Components
Button
Glass button that swells under the finger, stretches on drag, and morphs its width and content. Includes a prominent tinted variant.

Press and hold: the glass swells toward you. Tap Edit to morph it into a check.
Installation
pnpm dlx shadcn@latest add https://liquidcn.snmandela.com/r/liquid-button.jsonThe command copies these files into your project:
components/ui/liquid/button.tsxcomponents/ui/liquid/liquid.csslib/liquid/motion.tslib/liquid/press.ts
It extends the shadcn button component, whichever primitive library yours is built on. If your project doesn't have it yet, the CLI adds it from shadcn's registry; if it does, yours stays as it is, and the CLI asks before replacing it.
Usage
import { Button } from "@/components/ui/liquid/button"
<Button onClick={save}>Save</Button>
<Button variant="prominent" size="icon-lg" aria-label="Done">
<Check />
</Button>Examples
Variants
Every shadcn variant, plus prominent: accent-tinted glass for the primary action.

Icons
Icon sizes are 44 px circles, the minimum touch target on iOS.

API reference
Button
Every prop of the shadcn Button is forwarded, including refs and asChild.
| Prop | Type | Default |
|---|---|---|
variant
| "default" | "prominent" | "secondary" | "outline" | "ghost" | "destructive" | "link" | "default" |
sizeText sizes keep a 44 px minimum height; icon sizes are 44 px circles. | "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | "default" |
asChildRender the child element, such as a link, with the button's glass. | boolean | false |
Motion
| Parameter | Value |
|---|---|
| Press swell | 1 + clamp(8 / √(width × height), 0.04, 0.18) |
| Press drag | Rubber band, up to 10 px across and 7 px down |
| Content pop | Scale impulse of 2.4/s on the press spring |
| Content morph | Width springs to the new size; new content blurs in over 420 ms |
Springs keep their velocity when interrupted, and every value here is removed under reduced motion. How the motion works
Accessibility
- Renders a native
button(or your element withasChild), so focus, Enter, and Space work as usual. - Icon-only buttons need an
aria-label. When content morphs, update the label with it. - Under reduced motion the swell, stretch, and morph are removed; the button still changes instantly.