Tooltip Card
- Source
- Aceternity UI ↗
- Author
- Aceternity UI
- Licence
- Aceternity UI licence (free component)
Loading…
Hovering highlighted words opens a card that follows the pointer and springs open.
Code
"use client";
import { useRef } from "react";
import { Tooltip } from "@/lab/aceternity/ui/tooltip-card";
const P = "text-[clamp(0.7rem,2.3cqw,0.95rem)] leading-relaxed text-neutral-600 dark:text-neutral-400";
const TIP = "text-neutral-600 dark:text-neutral-400";
export default function TooltipCardDemo() {
const stageRef = useRef<HTMLDivElement>(null);
return (
<div
ref={stageRef}
className="relative flex h-full w-full items-center justify-center overflow-hidden [container-type:size]"
>
<div className="mx-auto max-w-2xl px-[6cqw]">
<p className={P}>
There was a problem with the server. Once{" "}
<Tooltip
boundaryRef={stageRef}
containerClassName={TIP}
content="AWS markets itself as the “world's most comprehensive and broadly adopted cloud platform” offering over 200 fully featured services globally."
>
<span className="font-bold">AWS</span>
</Tooltip>{" "}
went down, we had to quickly migrate to a new provider. AWS in general is a great
service, but sometimes it's not available.
</p>
<p className={`mt-[5cqh] ${P}`}>
The server was administered by{" "}
<Tooltip boundaryRef={stageRef} containerClassName={TIP} content={<TooltipCard />}>
{" "}
<span className="cursor-pointer font-bold">Tyler Durden.</span>
</Tooltip>{" "}
Tyler has been with us for a long time. He is a great asset to the team and sometimes
tries to act in different ways which can be difficult to manage.{" "}
</p>
<p className={`mt-[5cqh] ${P}`}>
That is when we approached Tyler for a cute little{" "}
<Tooltip boundaryRef={stageRef} containerClassName={TIP} content={<TestimonialCard />}>
{" "}
<span className="cursor-pointer font-bold">testimonial.</span>
</Tooltip>{" "}
Instead of a testimonial, he started yapping about project mayhem and how we should be
using our skills to build a better future.
</p>
</div>
</div>
);
}
const TooltipCard = () => {
return (
<div>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
src="https://assets.aceternity.com/screenshots/tyler.webp"
alt="Tyler Durden"
className="h-28 w-full rounded-sm object-cover object-top"
/>
<div className="my-3 flex flex-col">
<p className="text-base font-bold">Tyler Durden</p>
<p className="mt-1 text-xs text-neutral-600 dark:text-neutral-400">
Soap Developer from a Tier 3 college. Enthusiastic and exhibits entrepreneurial spirit.
</p>
</div>
</div>
);
};
const TestimonialCard = () => {
return (
<div>
<blockquote className="mb-4 text-neutral-700 dark:text-neutral-300">
This product is absolutely, grade A horse shit.
</blockquote>
<div className="flex items-center gap-2">
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
src="https://assets.aceternity.com/screenshots/tyler.webp"
alt="Tyler Durden"
className="size-6 rounded-full object-cover"
/>
<div>
<p className="text-xs font-semibold text-neutral-900 dark:text-neutral-100">Tyler Durden</p>
<p className="text-[10px] text-neutral-600 dark:text-neutral-400">
Senior Product Manager at FC
</p>
</div>
</div>
</div>
);
};
Prompt
Build "Tooltip Card", a cursor animation. What it does: Hovering highlighted words opens a card that follows the pointer and springs open. Write it as a single self-contained React component in TypeScript that fills its parent (w-full h-full), styled with Tailwind CSS, using motion. Technique: the Motion library, pointer tracking. It sits on a dark background, in a 16:10 frame. Respect prefers-reduced-motion with a still state, pause work when the element is off screen, and keep it accessible. Original: https://ui.aceternity.com/components/tooltip-card (Aceternity UI, Aceternity UI licence (free component)).