Detent web components
By Shane Logsdon

Media & effects

Meteors

Implemented

Luminous diagonal meteor trails streaming across cards and hero containers

detent-meteors

Port status
Catalog status
implemented
Origin
upstream
Phase
4
Wave
phase-4-canvas
Group
Media & effects
20 streaks, 215°

3.9 KB gzip for the class module

Variants

The streaks are pure CSS keyframe animations, so nothing schedules an animation frame. The decorative layer is aria-hidden and clipped; the headings below are the readable layer and stay in the light DOM. The streaks pause while offscreen or while the tab is hidden, and stop entirely with prefers-reduced-motion: reduce.

8 streaks, faster 190°, warm palette

Every setting above is a scalar attribute with a matching property. className is gone: the documented parts (surface, meteor, tail, content) and the --detent-meteors-radius/--detent-meteors-surface custom properties are the supported knobs.

Recorded states

  • reduced motion recorded state; no setter

Usage

Import

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

// or register it yourself
import { DetentMeteors } from '/components/meteors/meteors.js';

Attributes

  • angle
  • color
  • max-delay
  • max-duration
  • min-delay
  • min-duration
  • number
  • tail-length
  • trail-color

Properties

No properties are recorded for this component.

Slots

  • default

Events

No events are recorded for this component.

Example

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

<detent-meteors
  angle="215"
  color="#94A3B8"
  max-delay="1.2"
  max-duration="8"
  min-delay="0.2"
  min-duration="2"
  number="20"
  tail-length="60"
  trail-color="#64748B"
></detent-meteors>

Source

The pinned upstream source for this row:

  • src/components/ui/Meteors.tsx sha256 9ba0698f940d…

Native files

The native module and its artifacts:

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

API

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

Attributes

Attributes
AttributePropertyTypeDefaultNotes
angleanglenumber215Kebab-case attribute; camelCase property.
colorcolorstring'#94A3B8'Kebab-case attribute; camelCase property.
max-delaymaxDelaynumber1.2Kebab-case attribute; camelCase property.
max-durationmaxDurationnumber8Kebab-case attribute; camelCase property.
min-delayminDelaynumber0.2Kebab-case attribute; camelCase property.
min-durationminDurationnumber2Kebab-case attribute; camelCase property.
numbernumbernumber20Kebab-case attribute; camelCase property.
tail-lengthtailLengthnumber60Kebab-case attribute; camelCase property.
trail-colortrailColorstring'#64748B'Kebab-case attribute; camelCase property.

Properties

No property-only values are recorded for this component.

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.
  • React state/hooks replaced by element-owned state with pre-upgrade property preservation.
  • aria-hidden covers only the decoration layer: upstream applied aria-hidden=true to the container that also wrapped children, which hid the caller content from assistive technology (PC-12.6 correction).
  • The streaks pause with animation-play-state while offscreen, while the document is hidden and while disconnected (PC-10.6); upstream animated regardless of visibility.
  • The trajectory angle travels through a per-streak --detent-meteors-angle custom property instead of a generated style block with a global keyframe name, so two instances cannot collide.
  • number is bounded to 200, tail-length clamps at 0, durations clamp at 0.1 s and inverted ranges are normalised (the bound written last wins).
  • Colours are validated with CSS.supports(color, ...) and fall back with one development warning.
  • The host is position: relative rather than absolute inset-0, so it drops into a card or hero without a consumer wrapper; the decoration is the absolutely positioned clipped layer.

What it does

Luminous diagonal meteor trails running behind cards, hero banners and button containers.

Upstream behaviour
  • Super lightweight pure CSS keyframe hardware-accelerated animations
  • Configurable trajectory angle (default 215° diagonal down-left)
  • Customizable head color, tail gradient, tail length, and speed
  • Randomized distribution and staggered delays preventing rhythmic clustering
  • Drop-in compatible with cards, hero banners, and button containers
  • Full prefers-reduced-motion support disabling animations automatically
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.
  • React state/hooks replaced by element-owned state with pre-upgrade property preservation.
  • aria-hidden covers only the decoration layer: upstream applied aria-hidden=true to the container that also wrapped children, which hid the caller content from assistive technology (PC-12.6 correction).
  • The streaks pause with animation-play-state while offscreen, while the document is hidden and while disconnected (PC-10.6); upstream animated regardless of visibility.
  • The trajectory angle travels through a per-streak --detent-meteors-angle custom property instead of a generated style block with a global keyframe name, so two instances cannot collide.
  • number is bounded to 200, tail-length clamps at 0, durations clamp at 0.1 s and inverted ranges are normalised (the bound written last wins).
  • Colours are validated with CSS.supports(color, ...) and fall back with one development warning.
  • The host is position: relative rather than absolute inset-0, so it drops into a card or hero without a consumer wrapper; the decoration is the absolutely positioned clipped layer.
Previous: Magnetic Button Next: Metric Sparkline

Docs

Components

Project