Clawscale

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.

p50 latency 212 ms
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.

QueuedHealthyDegradedFailing
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.

Deploy
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
PropsDescription
autoFocus
boolean = true
Whether the overlay should acquire application focus when it first opens.
Inherited from OverlayableProps
boundary
Boundary
A boundary element supplied to the "flip" and "preventOverflow" modifiers. This is a shorthand for overriding Popper.js modifier options with the modifiers prop.
Inherited from PopoverSharedProps
canEscapeKeyClose
boolean = true
Whether pressing the esc key should invoke onClose.
Inherited from OverlayableProps
captureDismiss
boolean = false
When enabled, clicks inside a 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.
Inherited from PopoverSharedProps
children
React.ReactNode
Interactive element which will trigger the popover.
Inherited from PopoverSharedProps
className
string
A space-delimited list of class names to pass along to a child element.
Inherited from Props
compact
boolean = false
Whether to use a compact appearance, which reduces the visual padding around tooltip content.
contentrequired
React.JSX.Element | string
The content that will be displayed inside of the tooltip.
defaultIsOpen
boolean = false
Initial opened state when uncontrolled.
Inherited from PopoverSharedProps
disabled
boolean = false
Prevents the popover from appearing when true.
Inherited from PopoverSharedProps
enforceFocus
boolean = true
Whether 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 usePortal={false}.
Inherited from OverlayableProps
fill
boolean
Whether the wrapper and target should take up the full width of their container. Note that supplying true for this prop will force targetTagName="div".
Inherited from PopoverSharedProps
hoverCloseDelay
number = 0
The 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 = 100
The 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 = true
Whether a popover that uses a Portal should automatically inherit the dark theme from its parent.
Inherited from PopoverSharedProps
intent
Intent
Visual intent color to apply to element.
Inherited from IntentProps
interactionKind
typeof PopoverInteractionKind.HOVER | typeof PopoverInteractionKind.HOVER_TARGET_ONLY = PopoverInteractionKind.HOVER_TARGET_ONLY
The kind of hover interaction that triggers the display of the tooltip. Tooltips do not support click interactions.
isOpen
boolean = undefined
Whether 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 disabled={true}, this prop will be ignored, and the popover will remain closed.
Inherited from PopoverSharedProps
lazy
boolean = true
If 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.
Inherited from OverlayableProps
matchTargetWidth
boolean = false
Whether 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 = false
Whether 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
PopperModifierOverrides
Overrides 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>) => void
A callback that is invoked when user interaction causes the overlay to close, such as clicking on the overlay or pressing the esc key (if enabled).
Inherited from OverlayableProps
onClosed
(node: HTMLElement) => void
Lifecycle 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) => void
Lifecycle 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>) => void
Callback invoked in controlled mode when the popover open state would change due to user interaction.
Inherited from PopoverSharedProps
onOpened
(node: HTMLElement) => void
Lifecycle method invoked just after the CSS _open_ transition ends. Receives the DOM element of the child being opened.
Inherited from OverlayLifecycleProps
onOpening
(node: HTMLElement) => void
Lifecycle 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 = true
Whether the popover should open when its target is focused. If true, target will render with tabindex="0" to make it focusable via keyboard navigation.
Inherited from PopoverSharedProps
placement
Placement = "auto"
The placement (relative to the target) at which the popover should appear. Mutually exclusive with position prop. Prefer using this over position, as it more closely aligns with Popper.js semantics.
Inherited from PopoverSharedProps
popoverClassName
string
A space-delimited string of class names applied to the popover element.
Inherited from PopoverSharedProps
popoverRef
React.Ref<HTMLElement>
DOM ref attached to the Classes.POPOVER element.
Inherited from PopoverSharedProps
portalClassName
string
Space-delimited string of class names applied to the Portal element if usePortal={true}.
Inherited from OverlayableProps
portalContainer
HTMLElement = document.body
The container element into which the overlay renders its contents, when usePortal is true. This prop is ignored if usePortal is false.
Inherited from 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 placement prop.
Inherited from PopoverSharedProps
renderTarget
(props: PopoverTargetProps & PopoverHoverTargetHandlers<TProps> & PopoverClickTargetHandlers<TProps>) => React.JSX.Element
Target 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
RootBoundary
A root boundary element supplied to the "flip" and "preventOverflow" modifiers. This is a shorthand for overriding Popper.js modifier options with the modifiers prop.
Inherited from PopoverSharedProps
targetProps
TProps
HTML 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 = 100
Indicates 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 = true
Whether the popover should be rendered inside a Portal attached to portalContainer prop.
Inherited from PopoverSharedProps