Kobalte.v0.12.5

Tooltip

A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.

Import

ts
import { Tooltip } from "@kobalte/core";
ts
import { Tooltip } from "@kobalte/core";

Features

  • Exposed as a tooltip to assistive technology via ARIA.
  • Opens when the trigger is focused or hovered.
  • Closes when the trigger is activated or when pressing escape.
  • Only one tooltip shows at a time.
  • Labeling support for screen readers via aria-describedby.
  • Custom show and hide delay support.
  • Matches native tooltip behavior with delay on hover of first tooltip and no delay on subsequent tooltips.

Anatomy

The tooltip consists of:

  • Tooltip.Root: The root container for a tooltip.
  • Tooltip.Trigger: The button that toggles the tooltip.
  • Tooltip.Portal: Portals its children into the body when the tooltip is open.
  • Tooltip.Content: Contains the content to be rendered when the tooltip is open.
  • Tooltip.Arrow: An optional arrow element to render alongside the tooltip.
tsx
<Tooltip.Root>
<Tooltip.Trigger />
<Tooltip.Portal>
<Tooltip.Content>
<Tooltip.Arrow />
</Tooltip.Content>
</Tooltip.Portal>
</Tooltip.Root>
tsx
<Tooltip.Root>
<Tooltip.Trigger />
<Tooltip.Portal>
<Tooltip.Content>
<Tooltip.Arrow />
</Tooltip.Content>
</Tooltip.Portal>
</Tooltip.Root>

Example

Usage

Default open

An initial, uncontrolled open value can be provided using the defaultOpen prop.

tsx
<Tooltip.Root defaultOpen>...</Tooltip.Root>
tsx
<Tooltip.Root defaultOpen>...</Tooltip.Root>

Controlled open

The open prop can be used to make the open state controlled. The onOpenChange event is fired when the user presses the trigger, close button or interact outside, and receives the new value.

Tooltip is not showing.

tsx
import { createSignal } from "solid-js";
function ControlledExample() {
const [open, setOpen] = createSignal(false);
return (
<>
<p>Tooltip is {open() ? "showing" : "not showing"}.</p>
<Tooltip.Root open={open()} onOpenChange={setOpen}>
<Tooltip.Trigger>Trigger</Tooltip.Trigger>
<Tooltip.Portal>
<Tooltip.Content>
<Tooltip.Arrow />
<p>Tooltip content</p>
</Tooltip.Content>
</Tooltip.Portal>
</Tooltip.Root>
</>
);
}
tsx
import { createSignal } from "solid-js";
function ControlledExample() {
const [open, setOpen] = createSignal(false);
return (
<>
<p>Tooltip is {open() ? "showing" : "not showing"}.</p>
<Tooltip.Root open={open()} onOpenChange={setOpen}>
<Tooltip.Trigger>Trigger</Tooltip.Trigger>
<Tooltip.Portal>
<Tooltip.Content>
<Tooltip.Arrow />
<p>Tooltip content</p>
</Tooltip.Content>
</Tooltip.Portal>
</Tooltip.Root>
</>
);
}

Origin-aware animations

We expose a CSS custom property --kb-tooltip-content-transform-origin which can be used to animate the content from its computed origin.

css
/* style.css */
.tooltip__content {
transform-origin: var(--kb-tooltip-content-transform-origin);
animation: contentHide 250ms ease-in forwards;
}
.tooltip__content[data-expanded] {
animation: contentShow 250ms ease-out;
}
@keyframes contentShow {
from {
opacity: 0;
transform: scale(0.96);
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes contentHide {
from {
opacity: 1;
transform: scale(1);
}
to {
opacity: 0;
transform: scale(0.96);
}
}
css
/* style.css */
.tooltip__content {
transform-origin: var(--kb-tooltip-content-transform-origin);
animation: contentHide 250ms ease-in forwards;
}
.tooltip__content[data-expanded] {
animation: contentShow 250ms ease-out;
}
@keyframes contentShow {
from {
opacity: 0;
transform: scale(0.96);
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes contentHide {
from {
opacity: 1;
transform: scale(1);
}
to {
opacity: 0;
transform: scale(0.96);
}
}

API Reference

Tooltip.Root

PropDescription
openboolean
The controlled open state of the tooltip.
defaultOpenboolean
The default open state when initially rendered. Useful when you do not need to control the open state.
onOpenChange(open: boolean) => void
Event handler called when the open state of the tooltip changes.
triggerOnFocusOnlyboolean
Whether to open the tooltip only when the trigger is focused. By default, opens for both focus and hover.
openDelaynumber
The duration from when the mouse enters the trigger until the tooltip opens.
closeDelaynumber
The duration from when the mouse leaves the trigger or content until the tooltip closes.
ignoreSafeAreaboolean
Whether to close the tooltip even if the user cursor is inside the safe area between the trigger and tooltip.
idstring
A unique identifier for the component. The id is used to generate id attributes for nested components. If no id prop is provided, a generated id will be used.
forceMountboolean
Used to force mounting the tooltip (portal and content) when more control is needed. Useful when controlling animation with SolidJS animation libraries.

Tooltip.Root also accepts the following props to customize the placement of the Tooltip.Content.

PropDescription
getAnchorRect(anchor?: HTMLElement) => AnchorRect | undefined
Function that returns the anchor element's DOMRect.
placementPlacement
The placement of the tooltip.
gutternumber
The distance between the tooltip and the trigger/anchor element. By default, it's 0 plus half of the arrow offset, if it exists.
shiftnumber
The skidding of the tooltip along the anchor element.
flipboolean | string
Controls the behavior of the tooltip when it overflows the viewport:
- If a boolean, specifies whether the tooltip should flip to the opposite side when it overflows.
- If a string, indicates the preferred fallback placements when it overflows.
The placements must be spaced-delimited, e.g. "top left".
slideboolean
Whether the tooltip should slide when it overflows.
overlapboolean
Whether the tooltip can overlap the anchor element when it overflows.
sameWidthboolean
Whether the tooltip should have the same width as the anchor element. This will be exposed to CSS as --kb-popper-anchor-width.
fitViewportboolean
Whether the tooltip should fit the viewport. If this is set to true, the tooltip content will have maxWidth and maxHeight set to the viewport size. This will be exposed to CSS as --kb-popper-available-width and --kb-popper-available-height.
hideWhenDetachedboolean
Whether to hide the tooltip when the anchor element becomes occluded.
detachedPaddingnumber
The minimum padding in order to consider the anchor element occluded.
arrowPaddingnumber
The minimum padding between the arrow and the tooltip corner.
overflowPaddingnumber
The minimum padding between the tooltip and the viewport edge. This will be exposed to CSS as --kb-popper-overflow-padding.

Tooltip.Trigger

Data attributeDescription
data-expandedPresent when the tooltip is open.
data-closedPresent when the tooltip is close.

Tooltip.Content and Tooltip.Arrow share the same data-attributes.

Tooltip.Content

PropDescription
onEscapeKeyDown(event: KeyboardEvent) => void
Event handler called when the escape key is down. It can be prevented by calling event.preventDefault.
onPointerDownOutside(event: PointerDownOutsideEvent) => void
Event handler called when a pointer event occurs outside the bounds of the component. It can be prevented by calling event.preventDefault.

Tooltip.Arrow

PropDescription
sizenumber
The size of the arrow.

Rendered elements

ComponentDefault rendered element
Tooltip.Rootnone
Tooltip.Triggerbutton
Tooltip.PortalPortal
Tooltip.Contentdiv
Tooltip.Arrowdiv

Accessibility

Keyboard Interactions

KeyDescription
TabOpens/closes the tooltip without delay.
SpaceWhen open, closes the tooltip without delay.
EnterWhen open, closes the tooltip without delay.
EscWhen open, closes the tooltip without delay.