'use client';
import { useMemo } from 'react';
import { cn } from '@djangocfg/ui-core/lib';
import type { SpotlightRect } from './types';
/**
* SVG-mask spotlight renderer — adapted from the former Tour component.
*
* Draws a dimmed full-screen overlay with rounded cut-outs over the
* target rects, plus a brand-coloured border and an attention pulse.
* Pure presentation: it takes geometry, not DOM elements.
*/
// Injected once — keyframes + transition classes for the SVG rects.
const SPOTLIGHT_STYLES = `
@keyframes chat-spotlight-pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
@keyframes chat-spotlight-ring {
0% { transform: scale(1); opacity: 0.8; }
100% { transform: scale(1.15); opacity: 0; }
}
.chat-spotlight-rect {
transition: x 300ms ease-out, y 300ms ease-out,
width 300ms ease-out, height 300ms ease-out;
}
`;
/** Props for the spotlight canvas. */
export interface SpotlightCanvasProps {
/** Geometry of every element to spotlight. */
rects: SpotlightRect[];
/** Dim-overlay opacity, 0–1 (default: 0.5). */
opacity?: number;
/** Show an expanding attention ring (default: true). */
pulseRing?: boolean;
/** Dismiss the overlay when the scrim is clicked. */
onClick?: () => void;
className?: string;
}
export function SpotlightCanvas({
rects,
opacity = 0.5,
pulseRing = true,
onClick,
className,
}: SpotlightCanvasProps) {
// Expand each rect by its padding and pre-compute the rounded box.
// Hooks run unconditionally — no early return before this.
const boxes = useMemo(
() =>
rects.map((target, index) => {
const x = target.rect.x - target.padding;
const y = target.rect.y - target.padding;
const width = target.rect.width + target.padding * 2;
const height = target.rect.height + target.padding * 2;
const rx = target.radius + 2;
const centerX = target.rect.x + target.rect.width / 2;
const centerY = target.rect.y + target.rect.height / 2;
return {
key: index,
x,
y,
width,
height,
rx,
transformOrigin: `${centerX}px ${centerY}px`,
};
}),
[rects],
);
if (rects.length === 0) return null;
return (
<>
>
);
}