Detent web components
By Shane Logsdon

Feedback & status

Confetti Burst

Implemented

Lift-off milestone celebration with colorful confetti blast

detent-confetti-burst

Port status
Catalog status
implemented
Origin
upstream
Phase
4
Wave
phase-4-cinematic
Group
Feedback & status

7.8 KB gzip for the class module · inlines the shared spring

Variants

Press Launch celebration (or click the rocket) to run the pinned three-phase flow: the rocket flies for 600 ms while the trigger is disabled, then the confetti blast and the milestone card follow. The card is a role="status" region, and Launch again resets the whole element.

A milestone that was already reached: default-launched seeds the revealed state without animating, without a confetti blast and without an event.

No launch yet.

With prefers-reduced-motion: reduce a launch reaches the card immediately, draws no confetti and schedules no animation frame; every control stays usable.

Recorded states

  • reduced motion recorded state; no setter

Usage

Import

import '/components/confetti-burst/define.js';

// or register it yourself
import { DetentConfettiBurst } from '/components/confetti-burst/confetti-burst.js';

Attributes

  • confetti-count
  • default-launched
  • description
  • metric
  • title
  • trigger-label

Properties

  • onLaunch
  • onReset

Slots

No slots are recorded for this component.

Events

  • detent-launch — null
  • detent-reset — null

Example

Runnable example: site/examples/confetti-burst.ts. The snippet below is generated from the catalogued attributes.

<detent-confetti-burst
  confetti-count="50"
  default-launched
  description="All checks passed and your release is ready to deploy."
  metric="100% Production Ready"
  title="Mission Accomplished"
  trigger-label="Launch celebration"
></detent-confetti-burst>

Property-only values

const element = document.querySelector('detent-confetti-burst');
if (element !== null) {
  // onLaunch: () => void
  element.onLaunch = () => {};
  // onReset: () => void
  element.onReset = () => {};
}

Source

The pinned upstream source for this row:

  • src/components/ui/RocketPartyPopper.tsx sha256 ba250a547da7…

Native files

The native module and its artifacts:

  • src/components/confetti-burst/confetti-burst.ts
  • src/components/confetti-burst/styles.css
  • src/components/confetti-burst/define.ts
  • docs/components/confetti-burst.md
  • site/examples/confetti-burst.ts
  • tests/browser/confetti-burst.spec.ts
  • evidence/components/confetti-burst.md

API

Boolean attributes follow HTML presence semantics: present means true, absent means false, and disabled="false" still means disabled.

Attributes

Attributes
AttributePropertyTypeDefaultNotes
confetti-countconfettiCountnumber50Kebab-case attribute; camelCase property.
default-launcheddefaultLaunchedbooleanfalsePresence semantics: present means true, absent means false.
descriptiondescriptionstring'All checks passed and your release is ready to deploy.'Kebab-case attribute; camelCase property.
metricmetricstring'100% Production Ready'Kebab-case attribute; camelCase property.
titletitlestring'Mission Accomplished'Kebab-case attribute; camelCase property.
trigger-labeltriggerLabelstring'Launch celebration'Kebab-case attribute; camelCase property.

Properties

Properties
PropertyTypeDefaultNotes
onLaunch() => voidundefinedProperty-only: assign from script; not accepted as an attribute.
onReset() => voidundefinedProperty-only: assign from script; not accepted as an attribute.

Events

Events
EventUpstream propPayload typeNotes
detent-launchonLaunch() => voidComposed, bubbles; fires only for a user action.
detent-resetonReset() => voidComposed, bubbles; fires only for a user action.

Slots

No slots are recorded for this component.

CSS customisation

  • React callback props become typed composed CustomEvents; programmatic state assignment emits none.
  • Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
  • `lucide-react` icon components replaced with local SVG assets (ISC notice retained).
  • React state/hooks replaced by element-owned state with pre-upgrade property preservation.
  • The recorded title, description and metric props are declared but never rendered upstream; they render in the milestone card here, which the recorded feature and the role=status announcement require.
  • The revealed card is role=status with aria-live=polite (the recorded accessibility requirement); the upstream card had no role and no text.
  • confettiCount clamps to 0..400 as a documented work bound.
  • title shadows Element.title because the catalog records that prop name, so the native tooltip attribute is unavailable.
  • The confetti canvas spans the card width instead of the upstream overscan, so a narrow viewport never gains a horizontal scrollbar.
  • Idle float and ember are CSS keyframes paused while the document is hidden.
  • onLaunch and onReset are kept as property-only callback mirrors that fire once after the event.

What it does

A matte-black rocket launches, a confetti blast follows and a milestone card is revealed; "Launch again" resets the whole component.

Upstream behaviour
  • Sleek matte black rocket capsule with thruster ember anticipation
  • Smooth lift-off acceleration trailing thruster flame and smoke
  • 360° Colorful party popper confetti explosion with physics gravity and flutter
  • Apple-grade fluid spring reveal for celebratory milestone cards
  • Built-in replay and reset support for repeatable celebratory interactions
Differences from upstream
  • React callback props become typed composed CustomEvents; programmatic state assignment emits none.
  • Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
  • `lucide-react` icon components replaced with local SVG assets (ISC notice retained).
  • React state/hooks replaced by element-owned state with pre-upgrade property preservation.
  • The recorded title, description and metric props are declared but never rendered upstream; they render in the milestone card here, which the recorded feature and the role=status announcement require.
  • The revealed card is role=status with aria-live=polite (the recorded accessibility requirement); the upstream card had no role and no text.
  • confettiCount clamps to 0..400 as a documented work bound.
  • title shadows Element.title because the catalog records that prop name, so the native tooltip attribute is unavailable.
  • The confetti canvas spans the card width instead of the upstream overscan, so a narrow viewport never gains a horizontal scrollbar.
  • Idle float and ember are CSS keyframes paused while the document is hidden.
  • onLaunch and onReset are kept as property-only callback mirrors that fire once after the event.
Previous: Reveal Card Next: Scroll Progress Navigation

Docs

Components

Project