A React tooltip component from Radix UI Primitives, part of an open-source UI component library for building high-quality, accessible design systems and web apps
Overall
score
96%
The TooltipPortal and TooltipContent components work together to render tooltip content outside the normal DOM hierarchy with sophisticated positioning, collision detection, and accessibility features.
Portal component that renders children in a different part of the DOM, typically at the document body level.
/**
* Portal component for rendering tooltip content outside normal DOM flow
* @param children - Content to portal (typically TooltipContent)
* @param container - Container element to portal into (default: document.body)
* @param forceMount - Force mounting when controlling animation externally
*/
interface TooltipPortalProps {
children?: React.ReactNode;
container?: HTMLElement;
forceMount?: true;
}
const TooltipPortal: React.FC<TooltipPortalProps>;Main tooltip content component with positioning, collision detection, and accessibility features.
/**
* Main tooltip content component with positioning and accessibility
* @param children - Content to display in tooltip
* @param side - Preferred side relative to trigger
* @param sideOffset - Distance in pixels from trigger
* @param align - Alignment relative to trigger
* @param alignOffset - Offset in pixels along alignment axis
* @param avoidCollisions - Whether to avoid viewport collisions
* @param collisionBoundary - Boundary elements for collision detection
* @param collisionPadding - Padding around collision boundary
* @param arrowPadding - Minimum distance between arrow and content edges
* @param sticky - Sticky behavior when trigger moves
* @param hideWhenDetached - Hide when trigger is no longer visible
* @param aria-label - Accessible label for tooltip
* @param onEscapeKeyDown - Handler for escape key
* @param onPointerDownOutside - Handler for outside pointer events
* @param forceMount - Force mounting for animation control
*/
type TooltipContentElement = React.ComponentRef<"div">;
interface TooltipContentProps extends React.ComponentPropsWithoutRef<"div"> {
side?: "top" | "right" | "bottom" | "left";
sideOffset?: number;
align?: "start" | "center" | "end";
alignOffset?: number;
avoidCollisions?: boolean;
collisionBoundary?: Element | Element[];
collisionPadding?: number | Partial<Record<"top" | "right" | "bottom" | "left", number>>;
arrowPadding?: number;
sticky?: "partial" | "always";
hideWhenDetached?: boolean;
'aria-label'?: string;
onEscapeKeyDown?: (event: KeyboardEvent) => void;
onPointerDownOutside?: (event: CustomEvent) => void;
forceMount?: true;
}
const TooltipContent: React.forwardRef<TooltipContentElement, TooltipContentProps>;Usage Examples:
import {
TooltipProvider,
Tooltip,
TooltipTrigger,
TooltipPortal,
TooltipContent,
TooltipArrow
} from "@radix-ui/react-tooltip";
// Basic portal and content
function BasicTooltip() {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger>Hover me</TooltipTrigger>
<TooltipPortal>
<TooltipContent>
Simple tooltip content
</TooltipContent>
</TooltipPortal>
</Tooltip>
</TooltipProvider>
);
}
// Custom positioning
function PositionedTooltip() {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger>Hover me</TooltipTrigger>
<TooltipPortal>
<TooltipContent
side="right"
align="start"
sideOffset={10}
alignOffset={5}
>
Positioned tooltip
<TooltipArrow />
</TooltipContent>
</TooltipPortal>
</Tooltip>
</TooltipProvider>
);
}
// Collision avoidance
function SmartTooltip() {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger>Near edge</TooltipTrigger>
<TooltipPortal>
<TooltipContent
side="top"
avoidCollisions={true}
collisionPadding={10}
>
This tooltip avoids viewport edges
</TooltipContent>
</TooltipPortal>
</Tooltip>
</TooltipProvider>
);
}
// Custom portal container
function CustomPortalTooltip() {
const containerRef = useRef<HTMLDivElement>(null);
return (
<div>
<div ref={containerRef} className="custom-portal-container" />
<TooltipProvider>
<Tooltip>
<TooltipTrigger>Hover me</TooltipTrigger>
<TooltipPortal container={containerRef.current}>
<TooltipContent>
Rendered in custom container
</TooltipContent>
</TooltipPortal>
</Tooltip>
</TooltipProvider>
</div>
);
}
// Rich content tooltip
function RichContentTooltip() {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger>Product info</TooltipTrigger>
<TooltipPortal>
<TooltipContent className="rich-tooltip">
<div>
<h3>Product Details</h3>
<p>Price: $29.99</p>
<p>In stock: 15 items</p>
</div>
<TooltipArrow />
</TooltipContent>
</TooltipPortal>
</Tooltip>
</TooltipProvider>
);
}Specifies container element for portal rendering.
HTMLElementdocument.bodyForces mounting regardless of open state for animation control.
trueside: Preferred side relative to trigger
"top" | "right" | "bottom" | "left""top"sideOffset: Distance from trigger
number0align: Alignment relative to trigger
"start" | "center" | "end""center"alignOffset: Offset along alignment axis
number0avoidCollisions: Enable collision detection
booleantruecollisionBoundary: Elements to consider for collisions
Element | Element[]collisionPadding: Padding around collision boundary
number | Partial<Record<"top" | "right" | "bottom" | "left", number>>0arrowPadding: Minimum distance between arrow and content edges
number0sticky: Sticky behavior when trigger moves
"partial" | "always""partial"hideWhenDetached: Hide when trigger is no longer visible
booleanfalsearia-label: Accessible label
stringonEscapeKeyDown: Escape key handler
(event: KeyboardEvent) => voidonPointerDownOutside: Outside click handler
(event: CustomEvent) => voidContent supports sophisticated hover behavior with grace areas:
Content exposes positioning data via CSS custom properties:
--radix-tooltip-content-transform-origin--radix-tooltip-content-available-width--radix-tooltip-content-available-height--radix-tooltip-trigger-width--radix-tooltip-trigger-heightContent element receives data attributes for styling:
data-state: "closed" | "delayed-open" | "instant-open"data-side: Current side placementdata-align: Current alignmentconst Portal: React.FC<TooltipPortalProps>;
const Content: React.forwardRef<TooltipContentElement, TooltipContentProps>;The Portal and Content components are aliases for shorter import names.
type TooltipPortalProps = {
children?: React.ReactNode;
container?: HTMLElement;
forceMount?: true;
};
type TooltipContentElement = React.ComponentRef<"div">;
type TooltipContentProps = React.ComponentPropsWithoutRef<"div"> & {
side?: "top" | "right" | "bottom" | "left";
sideOffset?: number;
align?: "start" | "center" | "end";
alignOffset?: number;
avoidCollisions?: boolean;
collisionBoundary?: Element | Element[];
collisionPadding?: number | Partial<Record<"top" | "right" | "bottom" | "left", number>>;
arrowPadding?: number;
sticky?: "partial" | "always";
hideWhenDetached?: boolean;
'aria-label'?: string;
onEscapeKeyDown?: (event: KeyboardEvent) => void;
onPointerDownOutside?: (event: CustomEvent) => void;
forceMount?: true;
};Install with Tessl CLI
npx tessl i tessl/npm-radix-ui--react-tooltipevals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10