Confetti
Confetti is a confetti cannon for celebration moments: completed onboarding, first payment,
level up. It renders an invisible mount point and draws each burst on a temporary full-screen
canvas, with zero JavaScript dependencies. It requires the PetalConfetti
hook from the petal_components JS bundle and respects prefers-reduced-motion:
bursts are skipped for users who opt out of animation.
Basic Confetti
Mount the component once with an id, then fire at it from any trigger on the page. Mounting is idempotent per id, so one mount serves every button that targets it. The button below fires via JS.dispatch, which runs entirely in the browser: no server round trip.
Server Burst
Fire the same cannon from the server with push_event, for when the celebration follows something the server decides: a successful form submit, a completed payment, a finished import. This button reuses the docs-confetti mount from the section above.
Custom Options
Defaults set on the mount apply to every burst fired at that id. The same options can also be passed per burst, in the push_event payload or in the JS.dispatch detail: particle_count, spread, angle, velocity, colors and origin (x and y from 0 to 1, in viewport coordinates).
Properties
attr :id, :string, required: true
attr :particle_count, :integer, default: 100, doc: "default number of particles per burst"
attr :spread, :integer, default: 70, doc: "default spread of a burst, in degrees"
attr :colors, :list, default: [], doc: "default particle colors as hex strings"
attr :rest, :global