Components

Arrow Tile Button

A label slab paired with a detached arrow tile, in a springy tilt and a sliding swap variant.

A label slab sits beside its own square arrow tile, and the pair animates two ways. In tilt, the tile knocks the word: it leans into the slab, the slab is shoved back and springs into place, and the letters topple in a wave that travels away from the tile before bouncing upright. In swap, the tile takes the lead: it rolls across to the front of the label, its arrow spinning a full turn, while the label slides aside and its letters lift in a wake behind it. Pressing either variant squashes the whole button. It is a real <button>, so onClick, type, disabled, and refs all work. Pure CSS — no GSAP dependency.

New tab

Installation

pnpm dlx shadcn@latest add @tween-ui/arrow-tile-button

Using an AI editor? Set up MCP once, then just ask for it in plain words.

Usage

app/page.tsx
app/page.tsx
import ArrowTileButton from '@/components/tweenui/arrow-tile-button';
 
export default function Page() {
  return (
    <ArrowTileButton variant="swap" onClick={() => console.log('clicked')}>
      Book a call
    </ArrowTileButton>
  );
}

Props

Extends every native <button> attribute (onClick, type, disabled, ref, …).

PropTypeDefaultDescription
childrenstring—Button label (a string — split into letters for the wave).
variant'tilt' | 'swap''tilt'tilt knocks the letters over from the tile, swap rolls the tile to the front of the lime slab.
type'button' | 'submit' | 'reset''button'Native button type.
classNamestring—Merged with the base styles.

Accessibility

It renders a native <button>; the visible label supplies its accessible name, while the split letters and the arrow tile are aria-hidden. Hover and keyboard focus both trigger the motion, and a focus ring is included. Under prefers-reduced-motion: reduce the transitions are switched off.