All components
Glow Border
bordersAnimated radial-gradient rotating border overlay using injected @keyframes and useMemo-computed inline styles. Vue v-bind() CSS replaced with CSS custom properties on the element style.
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/glow-border.jsonUsage
"use client";
import { GlowBorder } from "@/registry/inspira-react/glow-border";
export default function GlowBorderDemo() {
return (
<div className="flex flex-wrap items-center justify-center gap-8 p-12 bg-neutral-950 min-h-[200px]">
<div className="relative w-48 h-24 bg-neutral-900 rounded-[10px] flex items-center justify-center">
<GlowBorder color="#06b6d4" borderRadius={10} />
<span className="text-white text-sm font-medium">Cyan Glow</span>
</div>
<div className="relative w-48 h-24 bg-neutral-900 rounded-2xl flex items-center justify-center">
<GlowBorder color={["#ff0080", "#7928ca", "#0070f3"]} borderRadius={16} duration={5} borderWidth={2} />
<span className="text-white text-sm font-medium">Multi Color</span>
</div>
<div className="relative w-48 h-24 bg-neutral-900 rounded-full flex items-center justify-center">
<GlowBorder color="#f59e0b" borderRadius={9999} borderWidth={3} duration={8} />
<span className="text-white text-sm font-medium">Amber Pill</span>
</div>
</div>
);
}Component source
"use client";
import React, { useMemo } from "react";
import { cn } from "@/lib/utils";
interface GlowBorderProps {
borderRadius?: number;
color?: string | string[];
borderWidth?: number;
duration?: number;
className?: string;
}
export function GlowBorder({
borderRadius = 10,
color = "#FFF",
borderWidth = 2,
duration = 10,
className,
}: GlowBorderProps) {
const colorValue = Array.isArray(color) ? color.join(",") : color;
const styles: React.CSSProperties = useMemo(
() => ({
"--border-radius": `${borderRadius}px`,
"--border-width": `${borderWidth}px`,
"--duration": `${duration}s`,
backgroundImage: `radial-gradient(transparent,transparent, ${colorValue},transparent,transparent)`,
backgroundSize: "300% 300%",
mask: "linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)",
WebkitMask: "linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)",
WebkitMaskComposite: "xor",
maskComposite: "exclude",
padding: "var(--border-width)",
borderRadius: "var(--border-radius)",
animation: `glow-border-spin var(--duration) linear infinite`,
} as React.CSSProperties),
[borderRadius, borderWidth, duration, colorValue],
);
return (
<>
<style>{`
@keyframes glow-border-spin {
0% { background-position: 0% 0%; }
50% { background-position: 100% 100%; }
100% { background-position: 0% 0%; }
}
`}</style>
<div
style={styles}
className={cn(
"pointer-events-none absolute inset-0 size-full rounded-[inherit] will-change-[background-position]",
className,
)}
/>
</>
);
}