All components
Magnified Doc Tooltip
tooltipsUi-Layouts component.
responsive · 380px
Install
Same command in any shadcn project — React (Vite/CRA), Next.js, Remix, Astro, and more:
$
npx shadcn@latest add https://your-domain/r/magnified-doc.jsonUsage
"use client";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/registry/ui-layouts/magnified-doc";
import {
AnimatePresence,
motion,
useMotionValue,
useSpring,
useTransform,
} from "motion/react";
import { useRef } from "react";
const dockItems = [
{ label: "Home", icon: "⌂" },
{ label: "Search", icon: "⌕" },
{ label: "Files", icon: "⊟" },
{ label: "Messages", icon: "✉" },
{ label: "Settings", icon: "⚙" },
];
function DockIcon({
mouseX,
label,
icon,
}: {
mouseX: ReturnType<typeof useMotionValue<number>>;
label: string;
icon: string;
}) {
const ref = useRef<HTMLButtonElement>(null);
const distance = useTransform(mouseX, (val) => {
const bounds = ref.current?.getBoundingClientRect() ?? { x: 0, width: 0 };
return val - bounds.x - bounds.width / 2;
});
const size = useSpring(useTransform(distance, [-80, 0, 80], [40, 60, 40]), {
mass: 0.1,
stiffness: 150,
damping: 12,
});
return (
<Tooltip>
<TooltipTrigger asChild>
<motion.button
ref={ref}
style={{ width: size, height: size }}
className="flex items-center justify-center rounded-xl border border-border bg-background text-xl shadow-sm transition-colors hover:bg-muted focus:outline-none"
aria-label={label}
>
{icon}
</motion.button>
</TooltipTrigger>
<TooltipContent side="top" sideOffset={8}>
<p className="text-xs font-medium">{label}</p>
</TooltipContent>
</Tooltip>
);
}
export default function Demo() {
const mouseX = useMotionValue(Infinity);
return (
<div className="flex min-h-[280px] flex-col items-center justify-end pb-10">
<TooltipProvider delayDuration={0}>
<motion.div
onMouseMove={(e) => mouseX.set(e.pageX)}
onMouseLeave={() => mouseX.set(Infinity)}
className="flex h-16 items-end gap-2 rounded-2xl border border-border bg-background/80 px-4 pb-2 shadow-lg backdrop-blur-sm"
>
{dockItems.map((item) => (
<DockIcon
key={item.label}
mouseX={mouseX}
label={item.label}
icon={item.icon}
/>
))}
</motion.div>
</TooltipProvider>
</div>
);
}Component source
'use client';
import { cn } from '@/lib/utils';
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
import * as React from 'react';
const TooltipProvider = TooltipPrimitive.Provider;
const Tooltip = TooltipPrimitive.Root;
const TooltipTrigger = TooltipPrimitive.Trigger;
const TooltipContent = React.forwardRef<
React.ElementRef<typeof TooltipPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
>(({ className, sideOffset = 4, ...props }, ref) => (
<TooltipPrimitive.Portal>
<TooltipPrimitive.Content
ref={ref}
sideOffset={sideOffset}
className={cn(
'z-50 overflow-hidden rounded-lg border dark:bg-neutral-800 bg-neutral-50 backdrop-filter dark:border-[#2C2C2C] backdrop-blur-lg dark:bg-[#1A1A1A]/95 px-4 py-3 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
className
)}
{...props}
/>
</TooltipPrimitive.Portal>
));
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };Dependencies
motion@radix-ui/react-tooltip
Source: Ui-Layouts