({
width = 16,
height = 16,
x = 0,
y = 0,
cx = 1,
cy = 1,
cr = 1,
className,
glow = false,
...props
}: DotPatternProps)
| 61 | */ |
| 62 | |
| 63 | export function DotPattern({ |
| 64 | width = 16, |
| 65 | height = 16, |
| 66 | x = 0, |
| 67 | y = 0, |
| 68 | cx = 1, |
| 69 | cy = 1, |
| 70 | cr = 1, |
| 71 | className, |
| 72 | glow = false, |
| 73 | ...props |
| 74 | }: DotPatternProps) { |
| 75 | const id = useId(); |
| 76 | const containerRef = useRef<SVGSVGElement>(null); |
| 77 | const [dimensions, setDimensions] = useState({ width: 0, height: 0 }); |
| 78 | |
| 79 | useEffect(() => { |
| 80 | const updateDimensions = () => { |
| 81 | if (containerRef.current) { |
| 82 | const { width, height } = containerRef.current.getBoundingClientRect(); |
| 83 | setDimensions({ width, height }); |
| 84 | } |
| 85 | }; |
| 86 | |
| 87 | updateDimensions(); |
| 88 | window.addEventListener("resize", updateDimensions); |
| 89 | return () => window.removeEventListener("resize", updateDimensions); |
| 90 | }, []); |
| 91 | |
| 92 | const dots = Array.from( |
| 93 | { |
| 94 | length: |
| 95 | Math.ceil(dimensions.width / width) * |
| 96 | Math.ceil(dimensions.height / height), |
| 97 | }, |
| 98 | (_, i) => { |
| 99 | const col = i % Math.ceil(dimensions.width / width); |
| 100 | const row = Math.floor(i / Math.ceil(dimensions.width / width)); |
| 101 | return { |
| 102 | x: col * width + cx, |
| 103 | y: row * height + cy, |
| 104 | delay: Math.random() * 5, |
| 105 | duration: Math.random() * 3 + 2, |
| 106 | }; |
| 107 | } |
| 108 | ); |
| 109 | |
| 110 | return ( |
| 111 | <svg |
| 112 | ref={containerRef} |
| 113 | aria-hidden="true" |
| 114 | className={cn( |
| 115 | "pointer-events-none absolute inset-0 h-full w-full", |
| 116 | className |
| 117 | )} |
| 118 | {...props} |
| 119 | > |
| 120 | <defs> |
nothing calls this directly
no test coverage detected