Confetti — <mv-confetti-button>
Physics-based canvas confetti (gravity, drag, 3D tumble, wobble): a standalone confetti() function, cannons / fireworks / stars / emoji presets, a trigger button and a press-and-hold “cool” mode.
| Category | Micro-interactions |
|---|---|
| Type | Web Component (<mv-confetti-button>) |
| Status | stable |
| Keywords | confetti, celebration, canvas, particles, emoji, cool-mode, success |
When to use
- A purchase, signup or completed milestone deserves a celebratory confetti burst
- A launch or achievement screen needs cannons, fireworks, stars or emoji raining across the screen
- A playful press-and-hold stream of particles should follow the pointer on a button
Avoid when
- Users need to know the outcome of the action; announce it with text → use Toast instead
- The action is routine and frequent; repeated celebrations quickly feel noisy
Install
node scripts/add.mjs confetti --out ./src/marvelousAI agent with the Marvelous UI MCP server: install_components({ slugs: ["confetti"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).
Files copied (dependencies included): tokens/tokens.css, core/base.css, core/canvas.js, core/element.js, core/motion.js, components/confetti/confetti.js.
Usage
Canonical markup — start from it and customize with attributes, data-* and CSS variables:
<div style="display:grid;gap:1.25rem;justify-items:center;text-align:center">
<div style="display:grid;gap:.35rem">
<strong style="font-size:1.05rem">Payment confirmed. Thanks, Priya!</strong>
<span style="color:var(--mv-fg-muted);font-size:.85rem">Order #48213 · arriving Thursday</span>
</div>
<div style="display:flex;flex-wrap:wrap;gap:.75rem;justify-content:center">
<mv-confetti-button>
<button class="mv-button" data-shape="pill">🎉 Celebrate</button>
</mv-confetti-button>
<mv-confetti-button preset="stars">
<button class="mv-button" data-variant="secondary" data-shape="pill">Stars</button>
</mv-confetti-button>
<mv-confetti-button emoji="🥯,☕,🥞" scalar="1.3" count="36" spread="100">
<button class="mv-button" data-variant="outline" data-shape="pill">Free breakfast</button>
</mv-confetti-button>
<mv-confetti-button preset="cannons">
<button class="mv-button" data-variant="outline" data-shape="pill">Cannons</button>
</mv-confetti-button>
<mv-confetti-button preset="fireworks">
<button class="mv-button" data-variant="outline" data-shape="pill">Fireworks</button>
</mv-confetti-button>
</div>
<div style="display:flex;flex-wrap:wrap;gap:.75rem;justify-content:center;align-items:center">
<mv-confetti-button preset="cool" emoji="💜,✨">
<button class="mv-button" data-variant="ghost">Hold for a shower of hearts</button>
</mv-confetti-button>
<button class="mv-button" data-variant="ghost" data-mv-confetti data-confetti-shapes="circle" data-confetti-colors="var(--mv-accent),var(--mv-success)">data-mv-confetti</button>
</div>
</div>API
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
preset | burst | stars | cannons | fireworks | cool | burst | burst/stars fire from the clicked button; cannons/fireworks cover the screen; cool = continuous stream while the pointer is held. |
count | number | 80 | Confetti pieces per burst. |
spread / angle | degrees | 70 / 90 | Cone width and direction (90 = straight up). |
velocity / gravity / scalar | number | 42 / 0.55 / 1 | Initial velocity, gravity, size. |
colors | comma-separated list of CSS colors | Colors (tokens accepted). Default: accent + a festive palette. | |
shapes | square,circle,star | square,square,circle | Shapes picked at random. |
emoji | comma-separated list | Replaces shapes with emoji/text (rasterized once). | |
disabled | boolean | Stops firing. | |
data-mv-confetti | preset (on any element) | Declarative trigger without a wrapper; options via data-confetti-count, -spread, -angle, -velocity, -gravity, -scalar, -colors, -shapes, -emoji. |
Methods
| Name | Description |
|---|---|
confetti(options) | Export: { particleCount, angle, spread, startVelocity, decay, gravity, drift, ticks, scalar, origin: {x,y} (0..1 viewport) | element, colors, shapes, emoji, flat, respectMotion }. Returns a Promise that resolves once everything has landed. |
confetti.cannons / .fireworks / .stars (options) | Presets; cannons and fireworks accept duration (ms). |
confetti.reset() | Clears everything immediately. |
coolMode(el, options) | Export: streams particles under the pointer while it is held on el; returns a cleanup function. |
fire(from?) | <mv-confetti-button> method: fires the preset from an element. |
Events
| Name | Description |
|---|---|
mv-fire | On every <mv-confetti-button> shot; detail = { preset }. |
Content structure
| Name | Description |
|---|---|
(child) | The trigger button or link (stays a real <button>). |
Accessibility
Decorative: a single aria-hidden canvas, pointer-events: none, placed in the top layer (above modals) and removed from the DOM as soon as the last piece has landed — no rAF loop when idle. Reduced motion: no confetti (the promise resolves immediately) and the button keeps its normal feedback; force it with respectMotion: false. The child button keeps its accessible name; announce the success itself with text or a live region.