Detent web components
By Shane Logsdon

Media & effects

Sparkles

Implemented

Zero-dependency GPU canvas particle sparkles with celestial stars, organic twinkle, and cursor reactions

detent-sparkles

Port status
Catalog status
implemented
Origin
upstream
Phase
4
Wave
phase-4-canvas
Group
Media & effects

Fixed demo copy

Sparkles above your content

Four shapes, four tints, organic twinkle, repulsion on move and a burst on click. The field paints nothing behind this copy, so its colour and contrast are yours.

7.1 KB gzip for the class module

Variants

background defaults to transparent: the canvas is decorative and aria-hidden, the caller's text keeps its own colour, and the component emits no events.

Recorded states

  • reduced motion recorded state; no setter

Usage

Import

import '/components/sparkles/define.js';

// or register it yourself
import { DetentSparkles } from '/components/sparkles/sparkles.js';

Attributes

  • background
  • blur
  • click-push
  • cursor-mode
  • cursor-radius
  • direction
  • id
  • interactive
  • max-size
  • min-size
  • opacity
  • particle-color
  • particle-count
  • particle-density
  • particle-shape
  • particle-size
  • paused
  • speed
  • twinkle
  • twinkle-speed

Properties

  • particleColors

Slots

  • default

Events

No events are recorded for this component.

Example

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

<detent-sparkles
  background="transparent"
  blur="0"
  click-push="6"
  cursor-mode="repulse"
  cursor-radius="140"
  direction="none"
  id
  interactive
  max-size="2.4"
  min-size="0.6"
  opacity="1"
  particle-color="#FFFFFF"
  particle-count
  particle-density="120"
  particle-shape="circle"
  particle-size
  paused
  speed="1"
  twinkle
  twinkle-speed="1"
></detent-sparkles>

Property-only values

const element = document.querySelector('detent-sparkles');
if (element !== null) {
  // particleColors: string[]
  element.particleColors = [];
}

Source

The pinned upstream source for this row:

  • src/components/ui/SparklesCore.tsx sha256 f46c811024be…

Native files

The native module and its artifacts:

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

API

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

Attributes

Attributes
AttributePropertyTypeDefaultNotes
backgroundbackgroundstring'transparent'Kebab-case attribute; camelCase property.
blurblurnumber0Kebab-case attribute; camelCase property.
click-pushclickPushnumber6Kebab-case attribute; camelCase property.
cursor-modecursorMode'repulse' | 'attract' | 'sparkle' | 'none''repulse'Kebab-case attribute; camelCase property.
cursor-radiuscursorRadiusnumber140Kebab-case attribute; camelCase property.
directiondirection'none' | 'top' | 'bottom' | 'left' | 'right''none'Kebab-case attribute; camelCase property.
ididstring—Kebab-case attribute; camelCase property.
interactiveinteractivebooleantruePresence semantics: present means true, absent means false.
max-sizemaxSizenumber2.4Kebab-case attribute; camelCase property.
min-sizeminSizenumber0.6Kebab-case attribute; camelCase property.
opacityopacitynumber1Kebab-case attribute; camelCase property.
particle-colorparticleColorstring'#FFFFFF'Kebab-case attribute; camelCase property.
particle-countparticleCountnumber—Kebab-case attribute; camelCase property.
particle-densityparticleDensitynumber120Kebab-case attribute; camelCase property.
particle-shapeparticleShape'circle' | 'star' | 'cross' | 'mixed''circle'Kebab-case attribute; camelCase property.
particle-sizeparticleSizenumber—Kebab-case attribute; camelCase property.
paused———Recorded in the catalog as an attribute.
speedspeednumber1Kebab-case attribute; camelCase property.
twinkletwinklebooleantruePresence semantics: present means true, absent means false.
twinkle-speedtwinkleSpeednumber1Kebab-case attribute; camelCase property.

Properties

Properties
PropertyTypeDefaultNotes
particleColorsstring[]—Property-only: assign from script; not accepted as an attribute.

Events

No custom events are recorded for this component.

Slots

Slots
SlotNotes
defaultConsumer content; rendered through a slot, never re-created.

CSS customisation

  • React `children`/`ReactNode` props become DOM slots; caller content stays light DOM.
  • `className` prop is replaced by documented CSS parts/custom properties; no Tailwind in consumers.
  • Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
  • React state/hooks replaced by element-owned state with pre-upgrade property preservation.
  • blur is attribute-only because the property name collides with HTMLElement.blur(); it is asserted through filter: blur().
  • id is the platform attribute; the canvas falls back to a generated sparkles-<n> id when the host has none.
  • The burst is bounded to 0..4000 particles and the loop pauses while the document is hidden.
  • The background value refuses url( so it can never fetch a network resource.
  • The reduced-motion state is published as surface[data-motion].

What it does

A canvas sparkle field: four particle shapes, a colour palette, organic twinkle, five drift directions, three cursor reactions, click bursts and the caller's content on top.

Upstream behaviour
  • Zero external particle dependencies: 100% native HTML5 Canvas 2D with sub-pixel DPR scaling
  • Full backward compatibility with Aceternity Sparkles props signature
  • Multiple particle shapes: circle, 4-pointed diamond star, celestial cross starlet, or mixed
  • Multi-color palette distribution supporting chromatic nebulae and gradient sparkle fields
  • Organic twinkle brightness pulsation with phase modulation and customizable twinkle speeds
  • Directional drift flows: float organically in all directions, or drift top, bottom, left, or right
  • Interactive cursor modes: repulsion, attraction, or proximity radiant enlargement
  • Click & tap particle burst generation spawning dynamic kinetic firework sparks
  • Wraps arbitrary children effortlessly with pointer event pass-through and depth stratification
  • Full accessibility: aria-hidden canvas and prefers-reduced-motion compliance
Differences from upstream
  • React `children`/`ReactNode` props become DOM slots; caller content stays light DOM.
  • `className` prop is replaced by documented CSS parts/custom properties; no Tailwind in consumers.
  • Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
  • React state/hooks replaced by element-owned state with pre-upgrade property preservation.
  • blur is attribute-only because the property name collides with HTMLElement.blur(); it is asserted through filter: blur().
  • id is the platform attribute; the canvas falls back to a generated sparkles-<n> id when the host has none.
  • The burst is bounded to 0..4000 particles and the loop pauses while the document is hidden.
  • The background value refuses url( so it can never fetch a network resource.
  • The reduced-motion state is published as surface[data-motion].
Previous: Animated Accordion Next: Speed Warp

Docs

Components

Project