Animated CTA Buttons

Three call-to-action buttons for moments that deserve more than a click: an arrow tile that stretches across the button, a press-and-hold button that fills up before it fires, and a swipe-to-confirm track for actions nobody should trigger by accident.

Expanding Arrow Button

expanding-arrow-button.tsx

The accent block on the left widens to cover the button and lays out a dotted arrow trail when you hover or tab to it, while the label fades aside.

Animated CTA Buttons Expanding Arrow Button preview width

Install

$ bunx --bun shadcn add @karaui/expanding-arrow-button
@karaui not found? Add it to components.json
{
  "registries": {
    "@karaui": "https://karaui.kamisama-v0.my.id/r/{name}.json"
  }
}

@karaui is in shadcn's public registry directory, so the latest CLI needs no setup. On an older CLI, merge this into the existing file once and every @karaui/… install resolves.

API Reference

className?
string
—
accentClassName?
string
—
labelClassName?
string
—

Hold Action Button

hold-action-button.tsx

Keep pressing with a mouse, finger, Space or Enter and a liquid fill rises or sweeps across; onHoldComplete fires only when it finishes, and letting go or sliding off cancels. Duration and labels are configurable.

Animated CTA Buttons Hold Action Button preview width

Install

$ bunx --bun shadcn add @karaui/hold-action-button

API Reference

type?
"horizontal" | "vertical"
vertical
className?
string
—
labelClassName?
string
—
holdingLabel?
ReactNode
Keep holding
completeLabel?
ReactNode
Done
holdDuration?
number
1600
onHoldComplete?
(() => void)
—
fillClassName?
string
—

Slide Action Button

slide-action-button.tsx

A thumb you drag along a track: past the threshold it locks in and calls onComplete, short of it the thumb springs home. Enter or Space completes it from the keyboard, and it resets after resetDelay.

Animated CTA Buttons Slide Action Button preview width

Install

$ bunx --bun shadcn add @karaui/slide-action-button

API Reference

completeLabel?
ReactNode
Complete
threshold?
number
0.82
resetDelay?
number
1200
onComplete?
(() => void)
—
thumbClassName?
string
—
fillClassName?
string
—
className?
string
—

Updated