cursor-card
vengenceui/cursor-cardFreeComponent
vengenceui publishes no description for this item.
Live preview
live · rendered by the registry
Rendered by vengenceui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://www.vengenceui.com/r/cursor-card.jsonSource
1"use client";23import React, { useState, useEffect } from "react";4import { createPortal } from "react-dom";5import { motion, useMotionValue, useSpring, AnimatePresence } from "framer-motion";6import { cn } from "@/lib/utils";78export interface CursorCardProps {9 children: React.ReactNode;10 image: string;11 description: string;12 href?: string;13 className?: string;14}1516export function CursorCard({ children, image, description, href = "#", className }: CursorCardProps) {17 const [isHovered, setIsHovered] = useState(false);18 const [mounted, setMounted] = useState(false);1920 const x = useMotionValue(0);21 const y = useMotionValue(0);2223 const springConfig = { damping: 25, stiffness: 300 };24 const springX = useSpring(x, springConfig);25 const springY = useSpring(y, springConfig);2627 useEffect(() => {28 setMounted(true);29 }, []);3031 const handleMouseMove = (e: React.MouseEvent) => {32 x.set(e.clientX - 120); // Center horizontally (width 240 / 2)33 y.set(e.clientY + 20); // Offset vertically slightly below cursor34 };3536 return (37 <>38 <a39 href={href}40 className={cn(41 "relative inline-block font-bold text-neutral-900 dark:text-neutral-100 transition-colors",42 "hover:bg-orange-100 dark:hover:bg-orange-900/40 rounded px-1 -mx-1",43 className44 )}45 onMouseEnter={() => setIsHovered(true)}46 onMouseLeave={() => setIsHovered(false)}47 onMouseMove={handleMouseMove}48 >49 {children}50 </a>5152 {mounted && typeof document !== "undefined" && createPortal(53 <AnimatePresence>54 {isHovered && (55 <motion.div56 initial={{ opacity: 0, scale: 0.8 }}57 animate={{ opacity: 1, scale: 1 }}58 exit={{ opacity: 0, scale: 0.8 }}59 transition={{ duration: 0.15, ease: "easeOut" }}60 style={{61 x: springX,62 y: springY,63 }}64 className={cn(65 "fixed top-0 left-0 pointer-events-none z-50 w-[240px]",66 "bg-white dark:bg-neutral-900 p-3 shadow-2xl rounded-xl border border-neutral-200 dark:border-neutral-800"67 )}68 >69 {/* eslint-disable-next-line @next/next/no-img-element */}70 <img src={image} alt="hover preview" className="w-full h-auto rounded-md mb-3 object-cover" />71 <p className="text-sm text-neutral-600 dark:text-neutral-400 m-0 leading-relaxed">72// … truncated
What it pulls in
npm packages
Files it writes
More from vengenceui
All 128 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| accordionaccordion | vengenceui | Components | Free | 2 deps | |
| agent-bento-gridagent-bento-grid | vengenceui | Components | Free | 1 dep | |
| alertalert | vengenceui | Components | Free | no deps | |
| animated-buttonanimated-button | vengenceui | Components | Free | 1 dep | |
| animated-footeranimated-footer | vengenceui | Components | Free | 2 deps | |
| animated-numberanimated-number | vengenceui | Components | Free | 1 dep | |
| animated-raysanimated-rays | vengenceui | Components | Free | no deps | |
| animated-tooltipanimated-tooltip | vengenceui | Components | Free | 1 dep |
