All components
Border Beam
bordersAnimated glowing beam that travels along the border of its parent container, driven by CSS custom properties and a @keyframes animation.
responsive · 600px
Install
Same command in any shadcn project — React (Vite/CRA), Next.js, Remix, Astro, and more:
$
npx shadcn@latest add https://your-domain/r/border-beam.jsonUsage
"use client";
import { BorderBeam } from "@/registry/inspira-react/border-beam";
export default function BorderBeamDemo() {
return (
<div className="flex flex-wrap items-center justify-center gap-8 p-16">
{/* Card 1 – default orange→purple beam */}
<div className="relative flex h-40 w-64 flex-col items-center justify-center gap-2 overflow-hidden rounded-xl border bg-card p-6 shadow-sm">
<span className="text-sm font-semibold text-card-foreground">Default beam</span>
<span className="text-xs text-muted-foreground">#ffaa40 → #9c40ff</span>
<BorderBeam />
</div>
{/* Card 2 – custom cyan→pink beam, slower */}
<div className="relative flex h-40 w-64 flex-col items-center justify-center gap-2 overflow-hidden rounded-2xl border bg-card p-6 shadow-sm">
<span className="text-sm font-semibold text-card-foreground">Custom beam</span>
<span className="text-xs text-muted-foreground">cyan → pink, 8 s</span>
<BorderBeam
colorFrom="#06b6d4"
colorTo="#ec4899"
duration={8000}
borderWidth={2}
size={120}
/>
</div>
{/* Card 3 – delayed start */}
<div className="relative flex h-40 w-64 flex-col items-center justify-center gap-2 overflow-hidden rounded-xl border bg-card p-6 shadow-sm">
<span className="text-sm font-semibold text-card-foreground">Delayed</span>
<span className="text-xs text-muted-foreground">2 s delay</span>
<BorderBeam delay={2000} colorFrom="#22c55e" colorTo="#3b82f6" />
</div>
</div>
);
}Component source
"use client";
import * as React from "react";
import { cn } from "@/lib/utils";
export interface BorderBeamProps extends React.HTMLAttributes<HTMLDivElement> {
/** Size of the beam head (px). */
size?: number;
/** Full rotation duration in milliseconds. */
duration?: number;
/** Beam width in px. */
borderWidth?: number;
/** Anchor position along the border (percentage). */
anchor?: number;
/** Start colour of the gradient beam. */
colorFrom?: string;
/** End colour of the gradient beam. */
colorTo?: string;
/** Animation start delay in milliseconds. */
delay?: number;
}
/**
* Animates a glowing beam that travels along the border of its parent
* element. Drop it inside any `relative` container with a `rounded-*` class.
*/
export const BorderBeam = React.forwardRef<HTMLDivElement, BorderBeamProps>(
(
{
className,
size = 200,
duration = 15000,
anchor = 90,
borderWidth = 1.5,
colorFrom = "#ffaa40",
colorTo = "#9c40ff",
delay = 0,
style,
...props
},
ref,
) => {
const durationSec = `${duration / 1000}s`;
const delaySec = `${delay / 1000}s`;
return (
<>
<style>{`
@keyframes border-beam-anim {
to { offset-distance: 100%; }
}
`}</style>
<div
ref={ref}
style={
{
"--size": size,
"--duration": durationSec,
"--anchor": anchor,
"--border-width": borderWidth,
"--color-from": colorFrom,
"--color-to": colorTo,
"--delay": `-${delaySec}`,
...style,
} as React.CSSProperties
}
className={cn(
// Base: transparent border + mask to reveal only the border strip
"pointer-events-none absolute inset-0 rounded-[inherit]",
"[border:calc(var(--border-width)*1px)_solid_transparent]",
"[mask-clip:padding-box,border-box]",
"[mask:linear-gradient(transparent,transparent),linear-gradient(white,white)]",
// Beam element via ::after
"after:absolute after:aspect-square",
"after:w-[calc(var(--size)*1px)]",
"after:[animation-delay:var(--delay)]",
"after:[animation:border-beam-anim_var(--duration)_infinite_linear]",
"after:[background:linear-gradient(to_left,var(--color-from),var(--color-to),transparent)]",
"after:[offset-anchor:calc(var(--anchor)*1%)_50%]",
"after:[offset-path:rect(0_auto_auto_0_round_calc(var(--size)*1px))]",
className,
)}
{...props}
/>
</>
);
},
);
BorderBeam.displayName = "BorderBeam";