Tooltip
A Tooltip shows a short hint while the pointer is over its target or the target has focus. It is a hover-only PopoverNext.
Usage#
import { Tooltip } from "@clawscale/react";Pass the target as the only child and the hint as content. Keep it to a few words. Put interactive content in a popover instead.
Examples#
Basic#
A tooltip opens 100 ms after the pointer enters the target and closes when it leaves. Keyboard focus opens it too.
import { Button, Tag, Tooltip } from "@clawscale/react";
export default function TooltipBasic() {
return (
<>
<Tooltip content="Median time from ingest to query, last 24 hours">
<Tag minimal>p50 latency 212 ms</Tag>
</Tooltip>
<Tooltip content="Runs every day at 02:15 UTC">
<Button icon="time" text="Daily" />
</Tooltip>
</>
);
}Placement#
placement sets the side. The tooltip flips when that side runs out of room.
import { Button, Tooltip } from "@clawscale/react";
const placements = ["top", "right", "bottom", "left"] as const;
export default function TooltipPlacement() {
return (
<>
{placements.map((placement) => (
<Tooltip content={`placement="${placement}"`} key={placement} placement={placement}>
<Button text={placement} />
</Tooltip>
))}
</>
);
}Intent#
intent colors the tooltip, for example to match a status.
import { Tag, Tooltip } from "@clawscale/react";
const statuses = [
{ intent: "primary", label: "Queued", hint: "12 runs wait for a free worker" },
{ intent: "success", label: "Healthy", hint: "24 of 24 replicas passed their health check" },
{ intent: "warning", label: "Degraded", hint: "p95 latency is 1.8 s, above the 1 s target" },
{ intent: "danger", label: "Failing", hint: "4 of the last 5 runs failed" },
] as const;
export default function TooltipIntent() {
return (
<>
{statuses.map((status) => (
<Tooltip content={status.hint} intent={status.intent} key={status.label}>
<Tag intent={status.intent} minimal>
{status.label}
</Tag>
</Tooltip>
))}
</>
);
}Compact#
compact reduces the padding for dense screens.
import { Button, Tooltip } from "@clawscale/react";
export default function TooltipCompact() {
return (
<>
<Tooltip content="1,284,112 rows written in the last hour">
<Button text="Default" />
</Tooltip>
<Tooltip compact content="1,284,112 rows written in the last hour">
<Button text="Compact" />
</Tooltip>
</>
);
}Icon buttons#
Icon-only buttons need a tooltip for sighted users and an aria-label for screen readers. Use the same text for both.
import { Button, ButtonGroup, type IconName, Tooltip } from "@clawscale/react";
const actions: [IconName, string][] = [
["refresh", "Refresh"],
["filter", "Filter rows"],
["download", "Download CSV"],
["cog", "Table settings"],
];
export default function TooltipIconButtons() {
return (
<ButtonGroup variant="minimal">
{actions.map(([icon, label]) => (
<Tooltip content={label} key={icon} placement="bottom">
<Button aria-label={label} icon={icon} />
</Tooltip>
))}
</ButtonGroup>
);
}Disabled buttons#
Some browsers send no mouse events to a disabled <button>, so its tooltip never opens. Use AnchorButton, which stays hoverable when disabled. Or wrap the button in a span and turn off the button's pointer events.
import { AnchorButton, Button, Tooltip } from "@clawscale/react";
export default function TooltipDisabled() {
return (
<>
<Tooltip content="Deploys are frozen until 18:00 UTC">
<AnchorButton disabled icon="cloud-upload" text="Deploy" />
</Tooltip>
<Tooltip content="Only owners can delete pipelines">
<span style={{ display: "inline-block", cursor: "not-allowed" }}>
<Button disabled icon="trash" style={{ pointerEvents: "none" }} text="Delete" />
</span>
</Tooltip>
</>
);
}With a popover#
A target can have both a tooltip and a popover. Put the Tooltip inside the PopoverNext. The tooltip then hides while the popover is open. Set openOnTargetFocus={false} so it does not reopen when focus returns to the target.
<PopoverNext content={exportMenu} placement="bottom-start">
<Tooltip content="Export" openOnTargetFocus={false}>
<Button aria-label="Export" icon="export" />
</Tooltip>
</PopoverNext>Props interface#
interface TooltipProps extends Omit<PopoverSharedProps<TProps>, "shouldReturnFocusOnClose">, IntentProps@clawscale/react| Props | Description |
|---|---|
autoFocus | boolean = trueWhether the overlay should acquire application focus when it first opens. Inherited from OverlayableProps |
boundary | BoundaryA boundary element supplied to the "flip" and "preventOverflow" modifiers. This is a shorthand for overriding Popper.js modifier options with the Inherited from modifiers prop.PopoverSharedProps |
canEscapeKeyClose | boolean = trueWhether pressing the Inherited from esc key should invoke onClose.OverlayableProps |
captureDismiss | boolean = falseWhen enabled, clicks inside a Inherited from Classes.POPOVER_DISMISS element will only close the current popover and not outer popovers. When disabled, the current popover and any ancestor popovers will be closed.PopoverSharedProps |
children | React.ReactNodeInteractive element which will trigger the popover. Inherited from PopoverSharedProps |
className | stringA space-delimited list of class names to pass along to a child element. Inherited from Props |
compact | boolean = falseWhether to use a compact appearance, which reduces the visual padding around tooltip content. |
contentrequired | React.JSX.Element | stringThe content that will be displayed inside of the tooltip. |
defaultIsOpen | boolean = falseInitial opened state when uncontrolled. Inherited from PopoverSharedProps |
disabled | boolean = falsePrevents the popover from appearing when Inherited from true.PopoverSharedProps |
enforceFocus | boolean = trueWhether the overlay should prevent focus from leaving itself. That is, if the user attempts to focus an element outside the overlay and this prop is enabled, then the overlay will immediately bring focus back to itself. If you are nesting overlay components, either disable this prop on the "outermost" overlays or mark the nested ones Inherited from usePortal={false}.OverlayableProps |
fill | booleanWhether the wrapper and target should take up the full width of their container. Note that supplying Inherited from true for this prop will force targetTagName="div".PopoverSharedProps |
hoverCloseDelay | number = 0The amount of time in milliseconds the tooltip should remain open after the user hovers off the trigger. The timer is canceled if the user mouses over the target before it expires. |
hoverOpenDelay | number = 100The amount of time in milliseconds the tooltip should wait before opening after the user hovers over the trigger. The timer is canceled if the user mouses away from the target before it expires. |
inheritDarkTheme | boolean = trueWhether a popover that uses a Inherited from Portal should automatically inherit the dark theme from its parent.PopoverSharedProps |
intent | IntentVisual intent color to apply to element. Inherited from IntentProps |
interactionKind | typeof PopoverInteractionKind.HOVER | typeof PopoverInteractionKind.HOVER_TARGET_ONLY = PopoverInteractionKind.HOVER_TARGET_ONLYThe kind of hover interaction that triggers the display of the tooltip. Tooltips do not support click interactions. |
isOpen | boolean = undefinedWhether the popover is visible. Passing this prop puts the popover in controlled mode, where the only way to change visibility is by updating this property. If Inherited from disabled={true}, this prop will be ignored, and the popover will remain closed.PopoverSharedProps |
lazy | boolean = trueIf Inherited from true and usePortal={true}, the Portal containing the children is created and attached to the DOM when the overlay is opened for the first time; otherwise this happens when the component mounts. Lazy mounting provides noticeable performance improvements if you have lots of overlays at once, such as on each row of a table.OverlayableProps |
matchTargetWidth | boolean = falseWhether the popover content should be sized to match the width of the target. This is sometimes useful for dropdown menus. This prop is implemented using a Popper.js custom modifier. Inherited from PopoverSharedProps |
minimal | boolean = falseWhether to apply minimal styling to this popover or tooltip. Minimal popovers do not have an arrow pointing to their target and use a subtler animation. Inherited from PopoverSharedProps |
modifiers | PopperModifierOverridesOverrides for Popper.js built-in modifiers. Each override is is a full modifier object (omitting its name), keyed by its modifier name. Inherited from PopoverSharedProps |
modifiersCustom | readonly PopperCustomModifier[]Custom modifiers to add to the popper instance. Inherited from PopoverSharedProps |
onClose | (event: React.SyntheticEvent<HTMLElement>) => voidA callback that is invoked when user interaction causes the overlay to close, such as clicking on the overlay or pressing the Inherited from esc key (if enabled).OverlayableProps |
onClosed | (node: HTMLElement) => voidLifecycle method invoked just after the CSS _close_ transition ends but before the child has been removed from the DOM. Receives the DOM element of the child being closed. Inherited from OverlayLifecycleProps |
onClosing | (node: HTMLElement) => voidLifecycle method invoked just before the CSS _close_ transition begins on a child. Receives the DOM element of the child being closed. Inherited from OverlayLifecycleProps |
onInteraction | (nextOpenState: boolean, e?: React.SyntheticEvent<HTMLElement>) => voidCallback invoked in controlled mode when the popover open state would change due to user interaction. Inherited from PopoverSharedProps |
onOpened | (node: HTMLElement) => voidLifecycle method invoked just after the CSS _open_ transition ends. Receives the DOM element of the child being opened. Inherited from OverlayLifecycleProps |
onOpening | (node: HTMLElement) => voidLifecycle method invoked just after mounting the child in the DOM but just before the CSS _open_ transition begins. Receives the DOM element of the child being opened. Inherited from OverlayLifecycleProps |
openOnTargetFocus | boolean = trueWhether the popover should open when its target is focused. If Inherited from true, target will render with tabindex="0" to make it focusable via keyboard navigation.PopoverSharedProps |
placement | Placement = "auto"The placement (relative to the target) at which the popover should appear. Mutually exclusive with Inherited from position prop. Prefer using this over position, as it more closely aligns with Popper.js semantics.PopoverSharedProps |
popoverClassName | stringA space-delimited string of class names applied to the popover element. Inherited from PopoverSharedProps |
popoverRef | React.Ref<HTMLElement>DOM ref attached to the Inherited from Classes.POPOVER element.PopoverSharedProps |
portalClassName | stringSpace-delimited string of class names applied to the Inherited from Portal element if usePortal={true}.OverlayableProps |
portalContainer | HTMLElement = document.bodyThe container element into which the overlay renders its contents, when Inherited from usePortal is true. This prop is ignored if usePortal is false.OverlayableProps |
portalStopPropagationEventsdeprecated | Array<keyof HTMLElementEventMap>A list of DOM events which should be stopped from propagating through the Portal. This prop is ignored if usePortal is false.this prop's implementation no longer works in React v17+ Inherited from OverlayableProps |
position | PopoverPosition = "auto"The position (relative to the target) at which the popover should appear. Mutually exclusive with Inherited from placement prop.PopoverSharedProps |
renderTarget | (props: PopoverTargetProps & PopoverHoverTargetHandlers<TProps> & PopoverClickTargetHandlers<TProps>) => React.JSX.ElementTarget renderer which receives props injected by Popover which should be spread onto the rendered element. This function should return a single React node. Inherited from PopoverSharedProps |
rootBoundary | RootBoundaryA root boundary element supplied to the "flip" and "preventOverflow" modifiers. This is a shorthand for overriding Popper.js modifier options with the Inherited from modifiers prop.PopoverSharedProps |
targetProps | TPropsHTML props for the target element. This is useful in some cases where you need to render some simple attributes on the generated target element. Inherited from PopoverSharedProps |
targetTagName | keyof React.JSX.IntrinsicElements = "span" ("div" if `fill={true}`)HTML tag name for the target element. This must be an HTML element to ensure that it supports the necessary DOM event handlers. Inherited from PopoverSharedProps |
transitionDuration | number = 100Indicates how long (in milliseconds) the tooltip's appear/disappear transition takes. This is used by React CSSTransition to know when a transition completes and must match the duration of the animation in CSS. Only set this prop if you override Blueprint's default transitions with new transitions of a different length. |
usePortal | boolean = trueWhether the popover should be rendered inside a Inherited from Portal attached to portalContainer prop.PopoverSharedProps |