Text Icons Effect
An interactive React component that enhances the cursor with dynamic text and icons, adapting in real time based on the hovered element to provide contextual feedback.
An interactive React component that enhances the cursor with dynamic text and icons, adapting in real time based on the hovered element to provide contextual feedback.
1// @ts-nocheck2'use client';34import React, { useState } from 'react';5import { useMouse } from '@/hooks/use-mouse';6import { Edit, Search, Play, Link } from 'lucide-react';78const TextIconCursor = () => {9const [mouseState, ref] = useMouse();10const [cursorContent, setCursorContent] = useState(null);1112const icons = {13edit: <Edit size={16} />,14search: <Search size={16} />,15play: <Play size={16} />,16link: <Link size={16} />,17};1819return (20<div className='relative w-full h-full ' ref={ref}>21{mouseState.x !== null && mouseState.y !== null && (22<div23className='fixed pointer-events-none z-50'24style={{25left: mouseState.x,26top: mouseState.y,27transform: 'translate(-50%, -50%)',28}}29>30{/* Main cursor */}31<div className='w-4 h-4 bg-white rounded-full mix-blend-screen' />3233{/* Text/Icon container */}34{cursorContent && (35<div36className='absolute left-6 top-0 bg-white/90 text-gray-900 px-3 py-1.5 rounded-full whitespace-nowrap flex items-center gap-2 text-sm animate-fade-in'37style={{38animation: 'fadeIn 0.2s ease-out',39}}40>41{typeof cursorContent === 'string'42? cursorContent43: icons[cursorContent]}44</div>45)}46</div>47)}4849<div className='flex flex-col items-center justify-center h-full gap-6'>50<button51className='px-6 py-3 bg-white/10 text-white rounded-lg transition-colors'52onMouseEnter={() => setCursorContent('edit')}53onMouseLeave={() => setCursorContent(null)}54>55Edit Button56</button>5758<div59className='px-6 py-3 bg-white/10 text-white rounded-lg cursor-help'60onMouseEnter={() => setCursorContent('Click to search')}61onMouseLeave={() => setCursorContent(null)}62>63Search Area64</div>6566<a67href='#'68className='px-6 py-3 bg-white/10 text-white rounded-lg'69onMouseEnter={() => setCursorContent('link')}70onMouseLeave={() => setCursorContent(null)}71>72Click to Navigate73</a>7475<div76className='w-32 h-32 bg-white/10 rounded-lg flex items-center justify-center'77onMouseEnter={() => setCursorContent('play')}78onMouseLeave={() => setCursorContent(null)}79>80<span className='text-white'>Video Area</span>81</div>82</div>8384<style jsx>{`85@keyframes fadeIn {86from {87opacity: 0;88transform: translateX(-10px);89}90to {91opacity: 1;92transform: translateX(0);93}94}95`}</style>96</div>97);98};99100export default TextIconCursor;101
1npm install lucide-react
1'use client';2import { type RefObject, useLayoutEffect, useRef, useState } from 'react';34interface MouseState {5x: number | null;6y: number | null;7elementX: number | null;8elementY: number | null;9elementPositionX: number | null;10elementPositionY: number | null;11}1213export function useMouse(): [MouseState, RefObject<HTMLDivElement>] {14const [state, setState] = useState<MouseState>({15x: null,16y: null,17elementX: null,18elementY: null,19elementPositionX: null,20elementPositionY: null,21});2223const ref = useRef<HTMLDivElement | null>(null);2425useLayoutEffect(() => {26const handleMouseMove = (event: MouseEvent) => {27const newState: Partial<MouseState> = {28x: event.pageX,29y: event.pageY,30};3132if (ref.current instanceof Element) {33const { left, top } = ref.current.getBoundingClientRect();34const elementPositionX = left + window.scrollX;35const elementPositionY = top + window.scrollY;36const elementX = event.pageX - elementPositionX;37const elementY = event.pageY - elementPositionY;3839newState.elementX = elementX;40newState.elementY = elementY;41newState.elementPositionX = elementPositionX;42newState.elementPositionY = elementPositionY;43}4445setState((s) => ({46...s,47...newState,48}));49};5051document.addEventListener('mousemove', handleMouseMove);5253return () => {54document.removeEventListener('mousemove', handleMouseMove);55};56}, []);5758return [state, ref];59}
| Prop | Type | Default | Description |
|---|---|---|---|
text | string | 'Hello!' | The text to display next to the cursor. |
color | string | '#000' | The color of the text and the dot. |
font | string | 'Arial, sans-serif' | The font of the text. |
textSize | number | 14 | The size of the text in pixels. |
gap | number | 5 | The gap between the dot and the text in pixels. |
element | HTMLElement | undefined | The HTML element where the cursor effect will be applied. If not specified, the effect applies to the document. |
size | number | 10 | The size of the dot in pixels. |