Loaders
PulseCore
A bright core beats while rings ripple out from it and fade.
Download
- React
- Tailwind CSS v4
- motion
components/ui/pulse-core.tsx
"use client";
import { motion, useReducedMotion } from "motion/react";
type PulseCoreProps = {
className?: string;
color?: string;
/** Loader width in pixels. */
size?: number;
/** 1 is the default pace; 2 is twice as fast. */
speed?: number;
/** Read out by screen readers. */
label?: string;
};
/* PulseCore: a bright core beats while rings ripple out from it and fade. */
export function PulseCore({
className = "",
color = "#a78bfa",
size = 72,
speed = 1,
label = "Loading",
}: PulseCoreProps) {
const reduce = useReducedMotion();
const beat = 1.8 / speed;
return (
<div role="status" className={`relative inline-block ${className}`} style={{ width: size, height: size }}>
<span className="sr-only">{label}</span>
{!reduce &&
[0, 1, 2].map((i) => (
<motion.span
key={i}
aria-hidden
className="absolute inset-0 rounded-full border-2"
style={{ borderColor: color }}
initial={{ scale: 0.25, opacity: 0.9 }}
animate={{ scale: 1, opacity: 0 }}
transition={{ duration: beat, repeat: Infinity, ease: "easeOut", delay: (i * beat) / 3 }}
/>
))}
<motion.span
aria-hidden
className="absolute inset-0 m-auto rounded-full"
style={{
width: size * 0.3,
height: size * 0.3,
background: `radial-gradient(circle at 35% 35%, #fff, ${color} 60%)`,
boxShadow: `0 0 ${size / 3}px ${color}`,
}}
animate={reduce ? { opacity: [0.6, 1, 0.6] } : { scale: [1, 1.18, 0.96, 1] }}
transition={{ duration: reduce ? 3 : beat / 3, repeat: Infinity, repeatDelay: reduce ? 0 : (beat * 2) / 3, ease: "easeOut" }}
/>
</div>
);
}
1. Install the dependency.
npm i motion2. Paste the Code tab into
components/ui/pulse-core.tsx. The styles are Tailwind CSS v4 classes.3. Use it. This is the preview above:
app/pulse-core-demo.tsx
import { PulseCore } from "@/components/ui/pulse-core"; export default function PulseCoreExample() { return ( <div className="grid h-full place-items-center bg-[radial-gradient(circle_at_50%_50%,#1d1a33,#0d0c14_70%)]"> <PulseCore size={96} /> </div> ); }
Props
| Name | Type | Default | What it does |
|---|---|---|---|
| color | string | "#a78bfa" | Main colour. |
| size | number | 72 | Width in pixels. |
| speed | number | 1 | 1 is the default pace; 2 is twice as fast. |
| label | string | "Loading" | Read out by screen readers (role=status). |
| className | string | "" | Extra classes on the wrapper. |