# Jelly Button

> Jelly candy button with gloss highlight that wobbles on hover and squishes on press.

- Author: Atelier UI
- License: MIT
- Page: https://chromotion.dev/en/components/jelly-button
- Site: Atelier UI (https://chromotion.dev)

## Install

```bash
npx shadcn@latest add https://chromotion.dev/r/jelly-button.json
```

Stack: React + TypeScript + Tailwind CSS v4, shadcn/ui conventions. `cn` comes from `@/lib/utils`.

## Dependencies

No extra dependencies.

## Usage

```tsx title="components/jelly-button-demo.tsx"
import { JellyButton } from "@/components/jelly-button"

export default function JellyButtonDemo() {
  return (
    <div className="flex flex-wrap items-center justify-center gap-8 rounded-2xl bg-rose-50 p-14 dark:bg-neutral-900">
      <JellyButton>Play</JellyButton>
      <JellyButton className="from-sky-400 to-blue-500 shadow-[0_6px_0_#1d4ed8,0_12px_20px_rgb(59_130_246/0.4),inset_0_2px_4px_rgb(255_255_255/0.5)]">
        Boing
      </JellyButton>
    </div>
  )
}
```

## Source

```tsx title="components/jelly-button.tsx"
import * as React from "react"

import { cn } from "@/lib/utils"

const keyframes = `@keyframes jelly-button-wobble{0%{transform:scale(1,1)}25%{transform:scale(.88,1.12)}50%{transform:scale(1.1,.9)}70%{transform:scale(.96,1.04)}100%{transform:scale(1,1)}}`

export function JellyButton({ className, children, ...props }: React.ComponentProps<"button">) {
  return (
    <button
      type="button"
      className={cn(
        "group relative inline-flex h-12 items-center justify-center gap-2 rounded-full bg-gradient-to-b from-pink-400 to-rose-500 px-9 text-base font-bold text-white select-none",
        "shadow-[0_6px_0_#be123c,0_12px_20px_rgb(244_63_94/0.4),inset_0_2px_4px_rgb(255_255_255/0.5)]",
        "transition-[transform,box-shadow] duration-150 hover:animate-[jelly-button-wobble_0.6s_ease-out]",
        "active:translate-y-1 active:scale-95 active:shadow-[0_2px_0_#be123c,0_6px_12px_rgb(244_63_94/0.4),inset_0_2px_4px_rgb(255_255_255/0.5)]",
        "focus-visible:ring-2 focus-visible:ring-pink-300 focus-visible:ring-offset-2 focus-visible:outline-none",
        "disabled:pointer-events-none disabled:opacity-50 motion-reduce:hover:animate-none",
        className
      )}
      {...props}
    >
      <style href="jelly-button" precedence="default">
        {keyframes}
      </style>
      <span aria-hidden className="pointer-events-none absolute top-1.5 left-5 h-2 w-8 rounded-full bg-white/50 blur-[1px]" />
      <span className="relative drop-shadow-sm">{children}</span>
    </button>
  )
}
```
