Detent web components
By Shane Logsdon

Media & effects

Shooting Stars

Implemented

Deep space canvas cosmos with glowing shooting stars, radiant twinkling starfield, and interactive stardust

detent-shooting-stars

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

Fixed demo copy

A calm sky above your content

Move the pointer across the sky for multi-plane parallax, or click to summon a meteor through the pointer. The canvas is decorative: everything you can read here is real light DOM.

8.3 KB gzip for the class module

Variants

The sky follows the colour scheme: without an explicit background or starColors it paints from --detent-shooting-stars-bg and the star, head and trail variables. The slotted copy inherits --detent-shooting-stars-text, which defaults to the page text token. The component emits no events.

Recorded states

  • reduced motion recorded state; no setter

Usage

Import

import '/components/shooting-stars/define.js';

// or register it yourself
import { DetentShootingStars } from '/components/shooting-stars/shooting-stars.js';

Attributes

  • angle
  • background
  • click-to-spawn
  • head-color
  • interval
  • max-active-shooting-stars
  • max-star-size
  • min-star-size
  • nebula
  • parallax
  • paused
  • show-embers
  • star-count
  • trail-color
  • twinkle-speed

Properties

  • speed
  • starColors
  • trailLength

Slots

  • default

Events

No events are recorded for this component.

Example

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

<detent-shooting-stars
  angle="42"
  background="#020617"
  click-to-spawn
  head-color="#FFFFFF"
  interval="2200"
  max-active-shooting-stars="2"
  max-star-size="2.2"
  min-star-size="0.6"
  nebula
  parallax
  paused
  show-embers
  star-count="120"
  trail-color="#38BDF8"
  twinkle-speed="1"
></detent-shooting-stars>

Property-only values

const element = document.querySelector('detent-shooting-stars');
if (element !== null) {
  // starColors: string[]
  element.starColors = [];
  // speed: [number, number] | number
  element.speed = undefined;
  // trailLength: [number, number] | number
  element.trailLength = undefined;
}

Source

The pinned upstream source for this row:

  • src/components/ui/ShootingStars.tsx sha256 ec36fd45db4d…

Native files

The native module and its artifacts:

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

API

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

Attributes

Attributes
AttributePropertyTypeDefaultNotes
angleanglenumber42Kebab-case attribute; camelCase property.
backgroundbackgroundstring'#020617'Kebab-case attribute; camelCase property.
click-to-spawnclickToSpawnbooleantruePresence semantics: present means true, absent means false.
head-colorheadColorstring'#FFFFFF'Kebab-case attribute; camelCase property.
intervalintervalnumber2200Kebab-case attribute; camelCase property.
max-active-shooting-starsmaxActiveShootingStarsnumber2Kebab-case attribute; camelCase property.
max-star-sizemaxStarSizenumber2.2Kebab-case attribute; camelCase property.
min-star-sizeminStarSizenumber0.6Kebab-case attribute; camelCase property.
nebulanebulabooleantruePresence semantics: present means true, absent means false.
parallaxparallaxbooleantruePresence semantics: present means true, absent means false.
paused———Recorded in the catalog as an attribute.
show-embersshowEmbersbooleantruePresence semantics: present means true, absent means false.
star-countstarCountnumber120Kebab-case attribute; camelCase property.
trail-colortrailColorstring'#38BDF8'Kebab-case attribute; camelCase property.
twinkle-speedtwinkleSpeednumber1Kebab-case attribute; camelCase property.

Properties

Properties
PropertyTypeDefaultNotes
speed[number, number] | number[12, 22]Property-only: assign from script; not accepted as an attribute.
starColorsstring[]['#FFFFFF', '#E0F2FE', '#C7D2FE', '#FEF08A']Property-only: assign from script; not accepted as an attribute.
trailLength[number, number] | number[90, 180]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.
  • Each frame advances one bounded step with a re-baselined spawn clock, so a pause never produces a burst.
  • A hidden document pauses the loop (PC-10.6 addition; the source had no visibilitychange).
  • Work is bounded: 2000 stars, 24 meteors and 400 embers.
  • The background value refuses url( so it can never fetch a network resource.
  • The fixed dark surface publishes --detent-shooting-stars-text (#f8fafc) for legible slotted content (19.28:1).
  • paused is exposed as attribute and property with the pinned source default false.
  • The reduced-motion state is published as space[data-motion].
  • The canvas needs no id, so two instances cannot collide.

What it does

A deep-space canvas sky: stratified twinkling stars, three nebula hazes, meteors with tapered gradient trails, head flares and stardust embers, pointer parallax and click-to-spawn, with the caller's content above the sky.

Upstream behaviour
  • Zero external runtime dependencies: 100% native HTML5 Canvas 2D with sub-pixel DPR scaling
  • Multi-depth twinkling starfield with radiant 4-point celestial cross-sparkles and soft halo blooms
  • Cinematic meteors with radiant head bursts, tapered linear-gradient fading trails, and custom trajectory angles
  • Stardust ember particles dynamically shed from traveling meteor tails for realistic atmospheric burns
  • Subtle ambient cosmic nebula haze clouds rendering layered indigo, violet, and cyan deep-space depth
  • Interactive mouse parallax tilt creating multi-plane 3D astronomical perspective
  • Interactive click & tap summons custom meteors sweeping directly across the interaction point
  • Full prefers-reduced-motion compliance freezing meteors and twinkle to a serene static night sky
  • Stratified children wrapper supporting titles, hero copy, and buttons with intact pointer events
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.
  • Each frame advances one bounded step with a re-baselined spawn clock, so a pause never produces a burst.
  • A hidden document pauses the loop (PC-10.6 addition; the source had no visibilitychange).
  • Work is bounded: 2000 stars, 24 meteors and 400 embers.
  • The background value refuses url( so it can never fetch a network resource.
  • The fixed dark surface publishes --detent-shooting-stars-text (#f8fafc) for legible slotted content (19.28:1).
  • paused is exposed as attribute and property with the pinned source default false.
  • The reduced-motion state is published as space[data-motion].
  • The canvas needs no id, so two instances cannot collide.
Previous: Sheet Next: Sidebar

Docs

Components

Project