Confetti

Confetti that falls like paper. Each piece leaves fast, slows in the air, and flutters and tumbles on the way down, showing its darker back as it flips. Burst it from a button and the pieces that land on the button settle along its top edge, slide to a stop, and fade.

Launch notesDraft

Installation

Terminalbash
npx @neelshha/ui@latest add confetti

Usage

page.tsxtsx
import { confetti } from "@/components/ui/confetti";

<button onClick={(event) => confetti(event.currentTarget)}>
  Publish
</button>

It's a function, not a component. One canvas over the page draws every burst, and it goes once the last piece has. The burst moves with its element, so it scrolls with the page. The promise it returns resolves when the burst is over.

From a point

Give it a point in the viewport instead of an element. There's nothing there to land on, so every piece falls away.

page.tsxtsx
confetti({ x: event.clientX, y: event.clientY }, { land: false });

Colours and size

Fewer pieces in a narrower cone, in your own colours.

page.tsxtsx
confetti(button, {
  count: 40,
  spread: 50,
  colors: ["#3a7bf0", "#8ab6ff"],
});

Accessibility

The canvas is hidden from screen readers, so say what happened in words as well, the way the button above changes to Published. With reduced motion there's no burst at all, and the promise resolves at once.

API

confetti(from, options) takes an element or an { x, y } point in the viewport, and returns a promise.

PropTypeDefaultDescription
countnumber80How many pieces.
spreadnumber70The width of the cone they fly out in, in degrees.
powernumber1300How fast the fastest pieces leave, in pixels per second.
colorsstring[]Any CSS colours. Each piece takes one, and its back is a shade darker.
landbooleantruePieces that come down on the element they burst from settle on its top edge.
withinElement | nullKeeps the burst inside this element's box.