Gitea Actions Runner Test / test-job (push) Successful in 1s
CI / check (push) Successful in 29s
CI / tests-unit (push) Successful in 1m48s
CI / tests-integration (push) Successful in 1m52s
CI / tests-ui (push) Successful in 2m35s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 3m7s
40 lines
950 B
TypeScript
40 lines
950 B
TypeScript
"use client";
|
|
|
|
import type { CSSProperties, MouseEvent, ReactNode } from "react";
|
|
|
|
interface SpotlightCardProps {
|
|
children: ReactNode;
|
|
className?: string;
|
|
style?: CSSProperties;
|
|
}
|
|
|
|
/**
|
|
* Wraps a card with a mouse-tracking radial glow. The pointer position is
|
|
* written to `--spot-x` / `--spot-y` and consumed by the `.spotlight::before`
|
|
* overlay in globals.css.
|
|
*/
|
|
export function SpotlightCard({
|
|
children,
|
|
className,
|
|
style,
|
|
}: SpotlightCardProps) {
|
|
const handlePointerMove = (event: MouseEvent<HTMLDivElement>) => {
|
|
const el = event.currentTarget;
|
|
const rect = el.getBoundingClientRect();
|
|
el.style.setProperty("--spot-x", `${event.clientX - rect.left}px`);
|
|
el.style.setProperty("--spot-y", `${event.clientY - rect.top}px`);
|
|
};
|
|
|
|
return (
|
|
<div
|
|
className={className}
|
|
style={
|
|
{ "--spot-x": "50%", "--spot-y": "50%", ...style } as CSSProperties
|
|
}
|
|
onPointerMove={handlePointerMove}
|
|
>
|
|
{children}
|
|
</div>
|
|
);
|
|
}
|