Tooltip components

FREE

Free and open-source React tooltip components built for modern applications and websites. These tooltips are built using React Aria and styled with Tailwind CSS.

Installation

You can add this Tooltip component using our CLI or manually:

npx untitledui@latest add tooltip

Tooltip examples

Below are examples and variations of this tooltip component:

Default

Tooltips are used to display additional information when hovering over an element. This is how our tooltip component looks by default:

With arrow

You can add an arrow to the tooltip by passing the arrow boolean prop to the Tooltip component. This will add an arrow to the tooltip that points to the element being hovered over.

With supporting text

In situations where you want to provide more context for the tooltip, you can pass a description to the Tooltip component. This will display the description below the tooltip title.

Placements

Since our tooltip component is built with React Aria, it supports all the placements that React Aria supports. You can set the placement using the placement prop on the Tooltip component. To see the full list of placements, check out the tooltip props in the React Aria documentation.

Top left
Top
Top right
Bottom left
Bottom
Bottom right
Left
Right

API reference

Tooltip

Import Tooltip from @/components/base/tooltip/tooltip. Renders React Aria’s TooltipTrigger — all of its props are supported.

Tooltip props
PropTypeDefaultDescription
title* (required)ReactNode—The title of the tooltip.
descriptionReactNode—The description of the tooltip.
arrowbooleanfalseWhether to show the arrow on the tooltip.
delaynumber300Delay in milliseconds before the tooltip is shown.
Props from React Aria Components (24)
Tooltip inherited props
PropTypeDefaultDescription
arrowBoundaryOffsetnumber0The minimum distance the arrow's edge should be from the edge of the overlay element.
children* (required)ReactNode——
closeDelaynumber0The delay time for the tooltip to close. See guidelines.
containerPaddingnumber12The placement padding that should be applied between the element and its surrounding container.
crossOffsetnumber0The additional offset applied along the cross axis between the element and its anchor element.
defaultOpenboolean—Whether the overlay is open by default (uncontrolled).
isDisabledboolean—Whether the tooltip should be disabled, independent from the trigger.
isEnteringboolean—Whether the tooltip is currently performing an entry animation.
isExitingboolean—Whether the tooltip is currently performing an exit animation.
isOpenboolean—Whether the overlay is open by default (controlled).
offsetnumber6The additional offset applied along the main axis between the element and its anchor element.
onOpenChange((isOpen: boolean) => void)—Handler that is called when the overlay's open state changes.
placement
"bottom""end""left""right""start""top""bottom left""bottom right""bottom start""bottom end""top left""top right""top start""top end"
+8 more
"left top""left bottom""start top""start bottom""right top""right bottom""end top""end bottom"
"top"The placement of the tooltip with respect to the trigger.
shouldCloseOnPressbooleantrueWhether the tooltip should close when the trigger is pressed.
shouldFlipbooleantrueWhether the element should flip its orientation (e.g. top to bottom or left to right) when there is insufficient room for it to render completely.
trigger
"hover""focus"
"hover"By default, opens for both focus and hover. Can be made to open only for focus.
triggerRefRefObject<Element | null>—The ref for the element which the tooltip positions itself with respect to.When used within a TooltipTrigger this is set automatically. It is only required when used standalone.
styleStyleOrFunction<TooltipRenderProps>—The inline style for the element. A function may be provided to compute the style based on component state.
classNameClassNameOrFunction<TooltipRenderProps>—The CSS className for the element. A function may be provided to compute the class based on component state.
renderDOMRenderFunction<"div", TooltipRenderProps>—Overrides the default DOM element with a custom render function. This allows rendering existing components with built-in styles and behaviors such as router links, animation libraries, and pre-styled components.Requirements:
  • You must render the expected element type (e.g. if <button> is expected, you cannot render an <a>).
  • Only a single root DOM element can be rendered (no fragments).
  • You must pass through props and ref to the underlying DOM element, merging with your own prop as appropriate.
aria-describedbystring—Identifies the element (or elements) that describes the object.
aria-detailsstring—Identifies the element (or elements) that provide a detailed, extended description for the object.
aria-labelstring—Defines a string value that labels the current element.
aria-labelledbystring—Identifies the element (or elements) that labels the current element.

Also accepts the global HTML attributes (dir, lang, hidden, inert, translate), all standard React DOM event handlers.

TooltipTrigger

Import TooltipTrigger from @/components/base/tooltip/tooltip. Renders React Aria’s Button — all of its props are supported.

TooltipTrigger props
PropTypeDefaultDescription
onClick((e: MouseEvent<FocusableElement>) => void)—Not recommended – use onPress instead. onClick is an alias for onPress provided for compatibility with other libraries. onPress provides additional event details for non-mouse interactions.
onPress((e: PressEvent) => void)—Handler that is called when the press is released over the target.
onPressChange((isPressed: boolean) => void)—Handler that is called when the press state changes.
onPressEnd((e: PressEvent) => void)—Handler that is called when a press interaction ends, either over the target or when the pointer leaves the target.
onPressStart((e: PressEvent) => void)—Handler that is called when a press interaction starts.
onPressUp((e: PressEvent) => void)—Handler that is called when a press is released over the target, regardless of whether it started on the target or not.
onHoverChange((isHovering: boolean) => void)—Handler that is called when the hover state changes.
onHoverEnd((e: HoverEvent) => void)—Handler that is called when a hover interaction ends.
onHoverStart((e: HoverEvent) => void)—Handler that is called when a hover interaction starts.
onBlur((e: FocusEvent<Element, Element>) => void)—Handler that is called when the element loses focus.
onFocus((e: FocusEvent<Element, Element>) => void)—Handler that is called when the element receives focus.
onFocusChange((isFocused: boolean) => void)—Handler that is called when the element's focus status changes.
autoFocusboolean—Whether the element should receive focus on render.
excludeFromTabOrderboolean—Whether to exclude the element from the sequential tab order. If true, the element will not be focusable via the keyboard by tabbing. This should be avoided except in rare scenarios where an alternative means of accessing the element or its functionality via the keyboard is available.
onKeyDown((e: KeyboardEvent) => void)—Handler that is called when a key is pressed.
onKeyUp((e: KeyboardEvent) => void)—Handler that is called when a key is released.
formstring—The <form> element to associate the button with. The value of this attribute must be the id of a <form> in the same document.
formActionstring | ((formData: FormData) => void | Promise<void>)—The URL that processes the information submitted by the button. Overrides the action attribute of the button's form owner.
formEncTypestring—Indicates how to encode the form data that is submitted.
formMethodstring—Indicates the HTTP method used to submit the form.
formNoValidateboolean—Indicates that the form is not to be validated when it is submitted.
formTargetstring—Overrides the target attribute of the button's form owner.
idstring—The element's unique identifier.
isDisabledboolean—Whether the button is disabled.
isPendingboolean—Whether the button is in a pending state. This disables press and hover events while retaining focusability, and announces the pending state to screen readers.
namestring—Submitted as a pair with the button's value as part of the form data.
preventFocusOnPressboolean—Whether to prevent focus from moving to the button when pressing it.Caution, this can make the button inaccessible and should only be used when alternative keyboard interaction is provided, such as ComboBox's MenuTrigger or a NumberField's increment/decrement control.
type
"button""submit""reset"
"button"The behavior of the button when used in an HTML form.
valuestring—The value associated with the button's name when it's submitted with the form data.
Styling (5)
TooltipTrigger styling props
PropTypeDefaultDescription
styleStyleOrFunction<ButtonRenderProps>—The inline style for the element. A function may be provided to compute the style based on component state.
childrenChildrenOrFunction<ButtonRenderProps>—The children of the component. A function may be provided to alter the children based on component state.
slotstring | null—A slot name for the component. Slots allow the component to receive props from a parent component. An explicit null value indicates that the local props completely override all props received from a parent.
classNameClassNameOrFunction<ButtonRenderProps>—The CSS className for the element. A function may be provided to compute the class based on component state.
renderDOMRenderFunction<"button", ButtonRenderProps>—Overrides the default DOM element with a custom render function. This allows rendering existing components with built-in styles and behaviors such as router links, animation libraries, and pre-styled components.Requirements:
  • You must render the expected element type (e.g. if <button> is expected, you cannot render an <a>).
  • Only a single root DOM element can be rendered (no fragments).
  • You must pass through props and ref to the underlying DOM element, merging with your own prop as appropriate.
Accessibility (10)
TooltipTrigger accessibility props
PropTypeDefaultDescription
aria-describedbystring—Identifies the element (or elements) that describes the object.
aria-detailsstring—Identifies the element (or elements) that provide a detailed, extended description for the object.
aria-labelstring—Defines a string value that labels the current element.
aria-labelledbystring—Identifies the element (or elements) that labels the current element.
aria-controlsstring—Identifies the element (or elements) whose contents or presence are controlled by the current element.
aria-current
falsetrue"step""true""false""page""location""date""time"
—Indicates whether this element represents the current item within a container or set of related elements.
aria-disabled
falsetrue"true""false"
—Indicates whether the element is disabled to users of assistive technology.
aria-expanded
falsetrue"true""false"
—Indicates whether the element, or another grouping element it controls, is currently expanded or collapsed.
aria-haspopup
falsetrue"true""false""menu""listbox""tree""grid""dialog"
—Indicates the availability and type of interactive popup element, such as menu or dialog, that can be triggered by an element.
aria-pressed
falsetrue"true""false""mixed"
—Indicates the current "pressed" state of toggle buttons.

Also accepts the global HTML attributes (dir, lang, hidden, inert, translate), all standard React DOM event handlers.

FAQs

Please refer to our frequently asked questions page for more.

Pass a focusable trigger as the child of Tooltip. The simplest option is TooltipTrigger, which renders an unstyled React Aria Button, so the tooltip opens on hover and on keyboard focus. React Aria based components like Button also work as triggers, and utility buttons have a built-in tooltip prop.

Use description to show a second line of text below the title, and set arrow to true to show an arrow pointing at the trigger. arrow is false by default.

Set the placement prop. It defaults to "top" and accepts React Aria placements such as "bottom", "left" or "top start". The tooltip sits 6px from the trigger by default; change that with offset, or shift it along the trigger with crossOffset.

Use delay to set how long to wait before opening, in milliseconds. It defaults to 300. closeDelay sets the delay before closing and defaults to 0.

Yes, pass isOpen with onOpenChange for a controlled tooltip, or defaultOpen to set the initial state. Set isDisabled to true to stop the tooltip from opening at all.

Yes, set trigger to "focus". By default the tooltip opens on both hover and focus.