Components / Layout & Overlay
Tooltip
Contextual hints that appear on hover.
Positions
Source TooltipDemo.tsx
The exact code behind the live demo above. Fetch it raw at /components/source/tooltip.txt.
import React, { useState } from "react";
function Section({ title, children }: { title: string; children: React.ReactNode }) {
return (
<div className="mb-8">
<h3 className="text-sm font-bold text-[var(--flux-heading)] mb-3">{title}</h3>
<div className="p-6 rounded border border-[var(--flux-grey-100)] bg-[var(--flux-surface)]">
{children}
</div>
</div>
);
}
type Position = "top" | "right" | "bottom" | "left";
const positionClasses: Record<Position, string> = {
top: "bottom-full left-1/2 -translate-x-1/2 mb-2",
right: "left-full top-1/2 -translate-y-1/2 ml-2",
bottom: "top-full left-1/2 -translate-x-1/2 mt-2",
left: "right-full top-1/2 -translate-y-1/2 mr-2",
};
const arrowClasses: Record<Position, string> = {
top: "top-full left-1/2 -translate-x-1/2 border-t-[var(--flux-primary-800)] border-x-transparent border-b-transparent",
right: "right-full top-1/2 -translate-y-1/2 border-r-[var(--flux-primary-800)] border-y-transparent border-l-transparent",
bottom: "bottom-full left-1/2 -translate-x-1/2 border-b-[var(--flux-primary-800)] border-x-transparent border-t-transparent",
left: "left-full top-1/2 -translate-y-1/2 border-l-[var(--flux-primary-800)] border-y-transparent border-r-transparent",
};
function TooltipButton({
label,
position,
tooltipText,
}: {
label: string;
position: Position;
tooltipText: string;
}) {
const [visible, setVisible] = useState(false);
return (
<div className="relative inline-flex">
<button
onMouseEnter={() => setVisible(true)}
onMouseLeave={() => setVisible(false)}
className="px-4 py-2 text-sm font-bold rounded border border-[var(--flux-grey-200)] text-[var(--flux-black)] hover:bg-[var(--flux-grey-100)] transition-colors"
>
{label}
</button>
{visible && (
<div
className={`absolute ${positionClasses[position]} bg-[var(--flux-primary-800)] text-white text-xs px-2.5 py-1.5 rounded shadow-lg whitespace-nowrap z-10`}
>
{tooltipText}
<span
className={`absolute ${arrowClasses[position]} border-4 w-0 h-0`}
/>
</div>
)}
</div>
);
}
export default function TooltipDemo() {
return (
<div>
<Section title="Positions">
<div className="flex items-center justify-center gap-6 py-8">
<TooltipButton label="Top" position="top" tooltipText="Tooltip on top" />
<TooltipButton label="Right" position="right" tooltipText="Tooltip on right" />
<TooltipButton label="Bottom" position="bottom" tooltipText="Tooltip on bottom" />
<TooltipButton label="Left" position="left" tooltipText="Tooltip on left" />
</div>
</Section>
</div>
);
}