@arolariu/components
Version:
🎨 70+ beautiful, accessible React components built on Radix UI. TypeScript-first, tree-shakeable, SSR-ready. Perfect for modern web apps, design systems & rapid prototyping. Zero config, maximum flexibility! ⚡
97 lines (96 loc) • 3.56 kB
JavaScript
"use client";
import { jsx, jsxs } from "react/jsx-runtime";
import { cn } from "../../lib/utilities.js";
import { motion } from "motion/react";
import { useEffect, useId, useRef, useState } from "react";
function DotBackground({ width = 16, height = 16, x = 0, y = 0, cx = 1, cy = 1, cr = 1, className, glow = false, ...props }) {
const id = useId();
const containerRef = useRef(null);
const [dimensions, setDimensions] = useState({
width: 0,
height: 0
});
useEffect(()=>{
const updateDimensions = ()=>{
if (containerRef.current) {
const { width, height } = containerRef.current.getBoundingClientRect();
setDimensions({
width,
height
});
}
};
updateDimensions();
window.addEventListener("resize", updateDimensions);
return ()=>window.removeEventListener("resize", updateDimensions);
}, []);
const dots = Array.from({
length: Math.ceil(dimensions.width / width) * Math.ceil(dimensions.height / height)
}, (_, i)=>{
const col = i % Math.ceil(dimensions.width / width);
const row = Math.floor(i / Math.ceil(dimensions.width / width));
return {
x: col * width + cx,
y: row * height + cy,
delay: 5 * Math.random(),
duration: 3 * Math.random() + 2
};
});
return /*#__PURE__*/ jsxs("svg", {
ref: containerRef,
"aria-hidden": "true",
className: cn("pointer-events-none absolute inset-0 h-full w-full", className),
...props,
children: [
/*#__PURE__*/ jsx("defs", {
children: /*#__PURE__*/ jsxs("radialGradient", {
id: `${id}-gradient`,
children: [
/*#__PURE__*/ jsx("stop", {
offset: "0%",
stopColor: "currentColor",
stopOpacity: "1"
}),
/*#__PURE__*/ jsx("stop", {
offset: "100%",
stopColor: "currentColor",
stopOpacity: "0"
})
]
})
}),
dots.map((dot)=>/*#__PURE__*/ jsx(motion.circle, {
cx: dot.x,
cy: dot.y,
r: cr,
fill: glow ? `url(#${id}-gradient)` : "currentColor",
className: "text-neutral-400/80",
initial: glow ? {
opacity: 0.4,
scale: 1
} : {},
animate: glow ? {
opacity: [
0.4,
1,
0.4
],
scale: [
1,
1.5,
1
]
} : {},
transition: glow ? {
duration: dot.duration,
repeat: 1 / 0,
repeatType: "reverse",
delay: dot.delay,
ease: "easeInOut"
} : {}
}, `${dot.x}-${dot.y}`))
]
});
}
export { DotBackground };
//# sourceMappingURL=dot-background.js.map