Streaks that fall across a container, for a hero or an empty background. They are real DOM positioned from the index, so the server and the browser agree.
Optional, and kept apart.
Nothing here is included in a project unless you add it, and the plain component it builds on is unchanged. This effect is decoration: it is hidden from screen readers, stands still for visitors who prefer reduced motion, and can be paused. Use Still on a preview to see that version.
import { Meteors } from "@rdloom/react";
export default function MeteorsBasicExample() {
return (
<div className="flex w-full justify-center">
<div className="relative h-96 w-full overflow-hidden rounded-[var(--rd-radius-overlay)] border border-[var(--rd-color-border-default)] bg-[var(--rd-color-surface-default)]">
<Meteors />
<div className="relative flex h-full items-center justify-center text-sm font-medium">Quiet night</div>
</div>
</div>
);
}Installation
npx rdloom add meteorsCopies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes.
It also adds rdloom-motion.css next to your tokens and imports it from the tokens file, once: no setup, and no inline styles. The plain components you already use are untouched.
Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/meteors.jsonWorks, but without upgrade tracking, and you import the motion CSS yourself.
Usage
import { Meteors } from "@rdloom/react";
<div className="flex w-full justify-center">
<div className="relative h-96 w-full overflow-hidden rounded-[var(--rd-radius-overlay)] border border-[var(--rd-color-border-default)] bg-[var(--rd-color-surface-default)]">
<Meteors />
<div className="relative flex h-full items-center justify-center text-sm font-medium">Quiet night</div>
</div>
</div>Dense
import { Meteors } from "@rdloom/react";
export default function MeteorsDenseExample() {
return (
<div className="flex w-full justify-center">
<div className="relative h-96 w-full overflow-hidden rounded-[var(--rd-radius-overlay)] border border-[var(--rd-color-border-default)] bg-[var(--rd-color-surface-default)]">
<Meteors count={36} angle={200} duration={4} />
<div className="relative flex h-full items-center justify-center text-sm font-medium">Meteor shower</div>
</div>
</div>
);
}API Reference
Defined by the spec. Components also accept the props of the React Aria component they wrap.
| Prop | Type | Default |
|---|---|---|
countHow many streaks. | number | 28 |
angleDirection of travel in degrees. 215 falls toward the lower right. | number | 215 |
colorColour of the streaks, any CSS colour. Defaults to the muted text colour. | string | none |
durationAverage seconds for a streak to cross. | number | 6 |
isPausedStops the effect and shows it still. | boolean | false |
Accessibility
Role presentation, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.
Keyboard
Not interactive.
Screen readers announce
- Not announced: the whole layer is hidden from assistive technology
What your code must do
- Decoration only: the effect is aria-hidden, never takes focus and never blocks the pointer
- Stands still for visitors who ask for less motion (prefers-reduced-motion) and inside an rdm-still container, and isPaused stops it too
- Does not flash: nothing changes more than three times in a second (WCAG 2.3.1)
- Streaks use slow, soft motion and the amount is capped, and isPaused or a Still switch stops them (WCAG 2.2.2)
- Hidden entirely for reduced motion and in forced-colors mode
- Place it behind content: it fills its container, which needs position: relative and overflow hidden
Guidelines
Use it when
- A hero or banner background
- A quiet empty state
Avoid it when
- Behind long text
- Any place that must stay calm
Don't
- Too many streaks, which reads as noise
- Putting it above the content
Design tokens
The semantic tokens this component uses. Change them once and every component follows; see Design tokens.
--rd-color-text-muted