Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Buttons

Pro

Confetti Button for React

A button that throws a burst of confetti from where it was pressed, to celebrate a finished action. For React with Base UI, for a purchase, a milestone or a goal reached.

Framework
UI library

Each press throws a burst of small pieces out from the point it landed, a little upward, and they turn, fall and fade in about a second. A keyboard press throws them from the center.

Use it for real moments of success: an order placed, a course finished, a goal reached. On an everyday action it soon gets in the way; for feedback on every press, use the Ripple Button. It wraps the Button, so variant and size work as usual. The pieces are always in the button, hidden, each with its own direction, distance, spin and color worked out from its place in the list. Their flight is CSS keyframes, which the install adds to your stylesheet; a press only writes where it landed into two CSS variables and restarts the animation, so nothing re-renders. The pieces fly over the page without moving the layout. When the system asks for reduced motion they don't fly: they fade in and out close around the button.

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Usage

import { ConfettiButton } from "@/components/ui/confetti-button";
<ConfettiButton>Complete order</ConfettiButton>

Demos

Amount

particleCount is how many pieces one press throws, 16 by default. Eight is a small nod for an everyday task; 40, with a longer duration, is a big moment. duration is how long a piece flies in milliseconds, 1000 by default, and each piece varies a little around it.

Preview width

Colors

colors takes any CSS colors, dealt out to the pieces in turn. These are shades of the destructive color mixed with color-mix(), so they still follow the theme. By default the pieces use shades of the primary, foreground and destructive colors.

Preview width

Accessibility

The confetti is decoration and hidden from assistive tech: the button is announced and activated as any Button, and nothing is said about the burst. If the press finishes something, say so in text as well, such as Order placed, so everyone gets the news.

Enter
Activate the button and throw confetti from its center.
Space
Activate the button and throw confetti from its center.

FAQ

When should I use a confetti button?

For genuine success: an order confirmed, an achievement, a milestone. Used on every action it stops meaning anything, and it slows people down.

How do I throw more or fewer pieces?

Set particleCount; 16 is the default. The Amount demo shows 8 and 40. Each piece is a small element in the button, so keep it under a hundred or so.

Can I use my brand colors?

Yes. Pass colors, an array of any CSS colors, such as var(--primary) or a color-mix() of it. The pieces take them in turn. The default is shades of the theme's primary, foreground and destructive colors, so it changes with the theme.

Where does the confetti come from?

From where the press landed, measured against the button. A keyboard press has no point, so it comes from the center.

Is the burst random?

No, though it looks it. Each piece's angle steps around the circle by the golden angle, and its distance, size, spin and pace vary with its place in the list, so the burst is the same on every press and on the server, with nothing to mismatch when the page hydrates.

Will the pieces be cut off or push the layout?

They're drawn in a layer inside the button that lets them overflow, with no effect on layout and no pointer events, so they fly over neighbors. A parent with overflow: hidden still cuts them at its edge.

What happens when someone presses several times quickly?

Each press starts the burst again from the new point, so the pieces never pile up: there's only ever one set of them, however often it's pressed.

What happens with reduced motion?

Nothing flies. The pieces fade in and out where they are, close around the button, and the press works as usual.

API Reference

ConfettiButton

data-slot="confetti-button-burst"

PropType
children?ReactNode

The label, under the burst.

colors?string[]

The pieces' colors, any CSS colors, dealt out in turn. By default shades of the theme's primary, foreground and destructive colors, so the burst follows the theme.

Default
COLORS
duration?number

How long a piece flies before it has faded out, in milliseconds. Each piece varies a little around it.

Default
1000
focusableWhenDisabled?boolean

Whether the button should be focusable when disabled.

Default
false
nativeButton?boolean

Whether the component renders a native <button> element when replacing it via the render prop. Set to false if the rendered element is not a button (for example, <div>).

Default
true
particleCount?number

How many pieces one press throws.

Default
16
render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

CSS variableType
--confetti-button-colorstring
--confetti-button-durationstring

One piece's flight, give or take a fifth (1000ms).

--confetti-button-origin-xstring

Where the last press landed, from the left (50%).

--confetti-button-origin-ystring

Where the last press landed, from the top (50%).

--confetti-button-sizestring
All 35 buttons