This component no longer exists. It was in ruixen-ui’s manifest when we first indexed it and is not there now — the registry served its inventory on 2026-08-12 and this item was not on it. The install command below will fail. It is kept here because a tutorial somewhere still tells people to run it.
Avatar Hover Card
ruixen-ui/avatar-hover-cardRemovedComponent
An interactive avatar that reveals a profile card on hover with spring physics, staggered content, and delayed open/close.
Live preview
live · rendered by the registry
Rendered by ruixen-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://ruixen.com/r/avatar-hover-card.jsonSource
1"use client";23import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";4import { cn } from "@/lib/utils";5import { AnimatePresence, motion } from "motion/react";6import { type ReactNode, useId, useRef, useState } from "react";78export interface AvatarHoverCardProps {9 imageSrc: string;10 imageAlt?: string;11 name: string;12 username?: string;13 description?: string;14 stats?: { label: string; value: string }[];15 actions?: ReactNode;16 size?: "sm" | "md" | "lg";17 align?: "start" | "center" | "end";18 className?: string;19}2021const triggerSizes = {22 sm: "size-8",23 md: "size-10",24 lg: "size-12",25};2627function initials(name: string) {28 return name29 .split(" ")30 .map((w) => w[0])31 .join("")32 .toUpperCase()33 .slice(0, 2);34}3536export default function AvatarHoverCard({37 imageSrc,38 imageAlt,39 name,40 username,41 description,42 stats,43 actions,44 size = "md",45 align = "start",46 className,47}: AvatarHoverCardProps) {48 const [open, setOpen] = useState(false);49 const timer = useRef<ReturnType<typeof setTimeout> | null>(null);50 const uid = useId();5152 const show = () => {53 if (timer.current) clearTimeout(timer.current);54 timer.current = setTimeout(() => setOpen(true), 80);55 };5657 const hide = () => {58 if (timer.current) clearTimeout(timer.current);59 timer.current = setTimeout(() => setOpen(false), 100);60 };6162 const alignClass: Record<string, string> = {63 start: "left-0",64 center: "left-1/2 -translate-x-1/2",65 end: "right-0",66 };6768 const spring = { type: "spring" as const, stiffness: 500, damping: 35 };6970 const avatarContent = (71 <Avatar className="size-full">72 <AvatarImage src={imageSrc} alt={imageAlt || name} />73 <AvatarFallback className="text-xs font-medium">74 {initials(name)}75 </AvatarFallback>76 </Avatar>77 );7879 return (80 <div81 className={cn("relative inline-flex", className)}82 onMouseEnter={show}83 onMouseLeave={hide}84 >85 {/* Trigger — always in flow for layout stability */}86 <div87 className={cn(88 "rounded-full transition-shadow duration-200",89 triggerSizes[size],90 open91 ? "ring-[1.5px] ring-foreground/8"92 : "ring-[1.5px] ring-transparent",93 )}94 >95 {!open && (96 <motion.div97 layoutId={`${uid}-av`}98 className="size-full cursor-pointer overflow-hidden rounded-full"99 transition={spring}100 >101// … truncated
What it pulls in
npm packages
Other registry items
