Sportlight Cards

Spotlight cards with a mouse-sensitive spotlight effect that highlights the border of the div or section as you move your cursor

grid

grid

grid

grid

grid

Track Goals

Keeping track of your goals helps you stay organized, motivated, and focused. Regularly monitoring your progress ensures you stay on course.

Usage

1
'use client';
2
3
import { cn } from '@/lib/utils';
4
import React, {
5
useRef,
6
useState,
7
MouseEvent,
8
useContext,
9
createContext,
10
} from 'react';
11
interface MousePosition {
12
x: number;
13
y: number;
14
}
15
16
interface SpotlightProps {
17
children: React.ReactNode;
18
className?: string;
19
ProximitySpotlight?: boolean;
20
HoverFocusSpotlight?: boolean;
21
CursorFlowGradient?: boolean;
22
}
23
interface SpotlightItemProps {
24
children: React.ReactNode;
25
className?: string;
26
}
27
28
interface SpotLightContextType {
29
ProximitySpotlight: boolean;
30
HoverFocusSpotlight: boolean;
31
CursorFlowGradient: boolean;
32
}
33
34
const SpotLightContext = createContext<SpotLightContextType | undefined>(
35
undefined
36
);
37
export const useSpotlight = () => {
38
const context = useContext(SpotLightContext);
39
if (!context) {
40
throw new Error('useSpotlight must be used within a SpotlightProvider');
41
}
42
return context;
43
};
44
export const Spotlight = ({
45
children,
46
className,
47
ProximitySpotlight = true,
48
HoverFocusSpotlight = false,
49
CursorFlowGradient = true,
50
}: SpotlightProps) => {
51
return (
52
<SpotLightContext.Provider
53
value={{
54
ProximitySpotlight,
55
HoverFocusSpotlight,
56
CursorFlowGradient,
57
}}
58
>
59
<div
60
className={cn(
61
className,
62
'group relative z-10 rounded-md grid grid-cols-4 gap-2 '
63
)}
64
>
65
{children}
66
</div>
67
</SpotLightContext.Provider>
68
);
69
};
70
export function SpotLightItem({ children, className }: SpotlightItemProps) {
71
const { HoverFocusSpotlight, ProximitySpotlight, CursorFlowGradient } =
72
useSpotlight();
73
const boxWrapper = useRef(null);
74
const [isHovered, setIsHovered] = useState(false);
75
const [mousePosition, setMousePosition] = React.useState({
76
x: null,
77
y: null,
78
});
79
React.useEffect(() => {
80
const updateMousePosition = (ev: { clientX: any; clientY: any }) => {
81
setMousePosition({ x: ev.clientX, y: ev.clientY });
82
};
83
window.addEventListener('mousemove', updateMousePosition);
84
return () => {
85
window.removeEventListener('mousemove', updateMousePosition);
86
};
87
}, []);
88
89
const [overlayColor, setOverlayColor] = useState({ x: 0, y: 0 });
90
const handleMouemove = ({ currentTarget, clientX, clientY }): MouseEvent => {
91
let { left, top } = currentTarget.getBoundingClientRect();
92
93
const x = clientX - left;
94
const y = clientY - top;
95
96
setOverlayColor({ x, y });
97
};
98
// console.log(overlayColor)
99
100
return (
101
<div
102
onMouseMove={handleMouemove}
103
onMouseEnter={() => CursorFlowGradient && setIsHovered(true)}
104
onMouseLeave={() => setIsHovered(false)}
105
ref={boxWrapper}
106
className={cn(
107
className,
108
' relative rounded-lg justify-center items-center p-[2px] bg-[#ffffff15] overflow-hidden'
109
)}
110
>
111
{isHovered && (
112
<div
113
className='pointer-events-none absolute opacity-0 z-50 rounded-xl w-full h-full group-hover:opacity-100 transition duration-300 '
114
style={{
115
background: `
116
radial-gradient(
117
250px circle at ${overlayColor.x}px ${overlayColor.y}px,
118
rgba(255, 255, 255, 0.137),
119
transparent 80%
120
)
121
`,
122
}}
123
/>
124
)}
125
{HoverFocusSpotlight && (
126
<div
127
className='absolute opacity-0 group-hover:opacity-100 z-10 inset-0 bg-fixed rounded-lg'
128
style={{
129
background: `radial-gradient(circle at ${mousePosition.x}px ${mousePosition.y}px, #ffffff76 0%,transparent 20%,transparent) fixed `,
130
}}
131
></div>
132
)}
133
{ProximitySpotlight && (
134
<div
135
className='absolute inset-0 z-0 bg-fixed rounded-lg'
136
style={{
137
background: `radial-gradient(circle at ${mousePosition.x}px ${mousePosition.y}px, #ffffff6e 0%,transparent 20%,transparent) fixed`,
138
}}
139
></div>
140
)}
141
{children}
142
</div>
143
);
144
}
145
146
type SpotlightCardProps = {
147
children: React.ReactNode;
148
className?: string;
149
};
150
151
export function SpotlightCard({
152
children,
153
className = '',
154
}: SpotlightCardProps) {
155
return (
156
<div
157
className={`relative h-full bg-slate-800 rounded-3xl p-px before:absolute before:w-80 before:h-80 before:-left-40 before:-top-40 before:bg-slate-400 before:rounded-full before:opacity-0 before:pointer-events-none before:transition-opacity before:duration-500 before:translate-x-[var(--mouse-x)] before:translate-y-[var(--mouse-y)] before:group-hover:opacity-100 before:z-10 before:blur-[100px] after:absolute after:w-96 after:h-96 after:-left-48 after:-top-48 after:bg-indigo-500 after:rounded-full after:opacity-0 after:pointer-events-none after:transition-opacity after:duration-500 after:translate-x-[var(--mouse-x)] after:translate-y-[var(--mouse-y)] after:hover:opacity-10 after:z-30 after:blur-[100px] overflow-hidden ${className}`}
158
>
159
{children}
160
</div>
161
);
162
}

Control the border by chaning padding p-[2px] from spotlight.tsx file:

spotlight.tsx
<div
onMouseMove={handleMouemove}
onMouseEnter={() => CursorFlowGradient && setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
ref={boxWrapper}
className={cn(
className,
' relative rounded-lg justify-center items-center p-[2px] bg-[#ffffff15] overflow-hidden'
)}
></div>

Props

PropTypeDefaultDescription
childrenReactNodeThe content to be rendered inside the Spotlight component.
classNamestringOptional CSS class for styling the Spotlight component.
ProximitySpotlightbooleantrueWhether to enable proximity-based spotlight effect.
HoverFocusSpotlightbooleanfalseWhether to enable spotlight effect on hover or focus.
CursorFlowGradientbooleantrueWhether to enable gradient flow based on cursor movement.

Examples

Spotlight

grid

Create Group Effortlessly

Seamless chats, crystal-clear videos, and
premium audio quality

FocuseHover

grid

Subscriber Growth

Experience a significant boost in your subscriber
count, achieving 3x growth.

Proximity

grid

Seamless Animation For All

Effortlessly connect with today's leading technologies including React, TypeScript, Next.js, Tailwind CSS, Motion, and Cypress.