Tooltip
A label that provides information on hover or focus.
You can explore the tooltip component in the following curated examples.
Popover with Tooltip
Render a Popover with a Tooltip that shows upon hovering over the Popover Trigger.
Slider with Tooltip
Render a Slider with a Tooltip that shows the current value of the Slider.
Tooltip with following cursor
Render a Tooltip that follows the cursor when hovering over the target element.
Dialog with Tooltip
Render a Dialog with a Tooltip that shows upon hovering over the Dialog Trigger.
Anatomy
To set up the tooltip correctly, you'll need to understand its anatomy and how we name its parts.
Each part includes a
data-part
attribute to help identify them in the DOM.
Examples
Learn how to use the Tooltip
component in your project. Let's take a look at the most basic
example:
import { Tooltip } from '@ark-ui/react/tooltip'
export const Basic = () => (
<Tooltip.Root>
<Tooltip.Trigger disabled>Hover Me</Tooltip.Trigger>
<Tooltip.Positioner>
<Tooltip.Content>I am a tooltip!</Tooltip.Content>
</Tooltip.Positioner>
</Tooltip.Root>
)
import { Tooltip } from '@ark-ui/solid/tooltip'
import { Portal } from 'solid-js/web'
export const Basic = () => (
<Tooltip.Root>
<Tooltip.Trigger>Hover Me</Tooltip.Trigger>
<Portal>
<Tooltip.Positioner>
<Tooltip.Content>I am a tooltip!</Tooltip.Content>
</Tooltip.Positioner>
</Portal>
</Tooltip.Root>
)
<script setup lang="ts">
import { Tooltip } from '@ark-ui/vue/tooltip'
</script>
<template>
<Tooltip.Root>
<Tooltip.Trigger>Hover Me</Tooltip.Trigger>
<Tooltip.Positioner>
<Tooltip.Content>I am a tooltip!</Tooltip.Content>
</Tooltip.Positioner>
</Tooltip.Root>
</template>
Controlled Tooltip
To create a controlled Tooltip component, manage the state of whether the tooltip is open using the
open
prop:
import { Tooltip } from '@ark-ui/react/tooltip'
import { useState } from 'react'
export const Controlled = () => {
const [isOpen, setIsOpen] = useState(false)
return (
<>
<button type="button" onClick={() => setIsOpen(!isOpen)}>
Toggle
</button>
<Tooltip.Root open={isOpen}>
<Tooltip.Trigger>Hover Me</Tooltip.Trigger>
<Tooltip.Positioner>
<Tooltip.Content>I am a tooltip!</Tooltip.Content>
</Tooltip.Positioner>
</Tooltip.Root>
</>
)
}
import { Tooltip } from '@ark-ui/solid/tooltip'
import { createSignal } from 'solid-js'
import { Portal } from 'solid-js/web'
export const Controlled = () => {
const [isOpen, setIsOpen] = createSignal(false)
return (
<>
<button type="button" onClick={() => setIsOpen(!isOpen())}>
Toggle
</button>
<Tooltip.Root open={isOpen()}>
<Tooltip.Trigger>Hover Me</Tooltip.Trigger>
<Portal>
<Tooltip.Positioner>
<Tooltip.Content>I am a tooltip!</Tooltip.Content>
</Tooltip.Positioner>
</Portal>
</Tooltip.Root>
</>
)
}
<script setup lang="ts">
import { Tooltip } from '@ark-ui/vue/tooltip'
import { ref } from 'vue'
const isOpen = ref(false)
</script>
<template>
<button @click="isOpen = !isOpen">Toggle</button>
<Tooltip.Root :open="isOpen">
<Tooltip.Trigger>Hover Me</Tooltip.Trigger>
<Tooltip.Positioner>
<Tooltip.Content>I am a tooltip!</Tooltip.Content>
</Tooltip.Positioner>
</Tooltip.Root>
</template>
Using a Render Function
For more control over the Tooltip's functionality, you can use a function as a child, which provides access to the Tooltip API:
import { Tooltip } from '@ark-ui/react/tooltip'
export const RenderFn = () => (
<Tooltip.Root>
<Tooltip.Trigger>Hover Me</Tooltip.Trigger>
<Tooltip.Positioner>
<Tooltip.Context>
{(tooltip) => (
<Tooltip.Content>This tooltip is open: {tooltip.open.toString()}</Tooltip.Content>
)}
</Tooltip.Context>
</Tooltip.Positioner>
</Tooltip.Root>
)
import { Tooltip } from '@ark-ui/solid/tooltip'
import { Portal } from 'solid-js/web'
export const RenderFn = () => (
<Tooltip.Root>
<Tooltip.Trigger>Hover Me</Tooltip.Trigger>
<Portal>
<Tooltip.Positioner>
<Tooltip.Context>
{(context) => (
<Tooltip.Content>This tooltip is open: {context().open.toString()}</Tooltip.Content>
)}
</Tooltip.Context>
</Tooltip.Positioner>
</Portal>
</Tooltip.Root>
)
<script setup lang="ts">
import { Tooltip } from '@ark-ui/vue/tooltip'
</script>
<template>
<Tooltip.Root>
<Tooltip.Trigger>Hover Me</Tooltip.Trigger>
<Tooltip.Positioner>
<Tooltip.Context v-slot="tooltip">
<Tooltip.Content>This tooltip is open: {{ tooltip.open.toString() }}</Tooltip.Content>
</Tooltip.Context>
</Tooltip.Positioner>
</Tooltip.Root>
</template>
Adding an Arrow
To display an arrow pointing to the trigger from the tooltip, use the Tooltip.Arrow
and
Tooltip.ArrowTip
components:
import { Tooltip } from '@ark-ui/react/tooltip'
export const Arrow = () => (
<Tooltip.Root>
<Tooltip.Trigger>Hover Me</Tooltip.Trigger>
<Tooltip.Positioner>
<Tooltip.Content>
<Tooltip.Arrow>
<Tooltip.ArrowTip />
</Tooltip.Arrow>
I am a tooltip!
</Tooltip.Content>
</Tooltip.Positioner>
</Tooltip.Root>
)
import { Tooltip } from '@ark-ui/solid/tooltip'
import { Portal } from 'solid-js/web'
export const Arrow = () => (
<Tooltip.Root>
<Tooltip.Trigger>Hover Me</Tooltip.Trigger>
<Portal>
<Tooltip.Positioner>
<Tooltip.Arrow>
<Tooltip.ArrowTip />
</Tooltip.Arrow>
<Tooltip.Content>I am a tooltip!</Tooltip.Content>
</Tooltip.Positioner>
</Portal>
</Tooltip.Root>
)
<script setup lang="ts">
import { Tooltip } from '@ark-ui/vue/tooltip'
</script>
<template>
<Tooltip.Root>
<Tooltip.Trigger>Hover Me</Tooltip.Trigger>
<Tooltip.Positioner>
<Tooltip.Content>
<Tooltip.Arrow>
<Tooltip.ArrowTip />
</Tooltip.Arrow>
I am a tooltip!
</Tooltip.Content>
</Tooltip.Positioner>
</Tooltip.Root>
</template>
Configuring Delay Timings
To configure the delay timings for the Tooltip, use the closeDelay
and openDelay
props:
import { Tooltip } from '@ark-ui/react/tooltip'
export const Timings = () => (
<Tooltip.Root closeDelay={0} openDelay={0}>
<Tooltip.Trigger>Hover Me</Tooltip.Trigger>
<Tooltip.Positioner>
<Tooltip.Content>I am a tooltip!</Tooltip.Content>
</Tooltip.Positioner>
</Tooltip.Root>
)
import { Tooltip } from '@ark-ui/solid/tooltip'
import { Portal } from 'solid-js/web'
export const Timings = () => (
<Tooltip.Root closeDelay={0} openDelay={0}>
<Tooltip.Trigger>Hover Me</Tooltip.Trigger>
<Portal>
<Tooltip.Positioner>
<Tooltip.Content>I am a tooltip!</Tooltip.Content>
</Tooltip.Positioner>
</Portal>
</Tooltip.Root>
)
<script setup lang="ts">
import { Tooltip } from '@ark-ui/vue/tooltip'
</script>
<template>
<Tooltip.Root :closeDelay="0" :openDelay="0">
<Tooltip.Trigger>Hover Me</Tooltip.Trigger>
<Tooltip.Positioner>
<Tooltip.Content>I am a tooltip!</Tooltip.Content>
</Tooltip.Positioner>
</Tooltip.Root>
</template>
Custom Positioning
To customize the position of the Tooltip relative to the trigger, use the positioning
prop:
import { Tooltip } from '@ark-ui/react/tooltip'
export const Positioning = () => (
<Tooltip.Root
positioning={{
placement: 'left-start',
offset: { mainAxis: 12, crossAxis: 12 },
}}
>
<Tooltip.Trigger>Hover Me</Tooltip.Trigger>
<Tooltip.Positioner>
<Tooltip.Content>I am a tooltip!</Tooltip.Content>
</Tooltip.Positioner>
</Tooltip.Root>
)
import { Tooltip } from '@ark-ui/solid/tooltip'
import { Portal } from 'solid-js/web'
export const Positioning = () => (
<Tooltip.Root
positioning={{
placement: 'left-start',
offset: { mainAxis: 12, crossAxis: 12 },
}}
>
<Tooltip.Trigger>Hover Me</Tooltip.Trigger>
<Portal>
<Tooltip.Positioner>
<Tooltip.Content>I am a tooltip!</Tooltip.Content>
</Tooltip.Positioner>
</Portal>
</Tooltip.Root>
)
<script setup lang="ts">
import { Tooltip } from '@ark-ui/vue/tooltip'
</script>
<template>
<Tooltip.Root
:positioning="{
placement: 'left-start',
gutter: 16,
offset: { mainAxis: 12, crossAxis: 12 },
}"
>
<Tooltip.Trigger>Hover Me</Tooltip.Trigger>
<Tooltip.Positioner>
<Tooltip.Content>I am a tooltip!</Tooltip.Content>
</Tooltip.Positioner>
</Tooltip.Root>
</template>
Using the Root Provider
The RootProvider
component provides a context for the tooltip. It accepts the value of the useTooltip
hook.
You can leverage it to access the component state and methods from outside the tooltip.
import { Tooltip, useTooltip } from '@ark-ui/react/tooltip'
export const RootProvider = () => {
const tooltip = useTooltip()
return (
<>
<button onClick={() => tooltip.setOpen(true)}>Open</button>
<Tooltip.RootProvider value={tooltip}>
<Tooltip.Trigger disabled>Hover Me</Tooltip.Trigger>
<Tooltip.Positioner>
<Tooltip.Content>I am a tooltip!</Tooltip.Content>
</Tooltip.Positioner>
</Tooltip.RootProvider>
</>
)
}
import { Tooltip, useTooltip } from '@ark-ui/solid/tooltip'
import { Portal } from 'solid-js/web'
export const RootProvider = () => {
const tooltip = useTooltip()
return (
<>
<button onClick={() => tooltip().setOpen(true)}>Open</button>
<Tooltip.RootProvider value={tooltip}>
<Tooltip.Trigger>Hover Me</Tooltip.Trigger>
<Portal>
<Tooltip.Positioner>
<Tooltip.Content>I am a tooltip!</Tooltip.Content>
</Tooltip.Positioner>
</Portal>
</Tooltip.RootProvider>
</>
)
}
<script setup lang="ts">
import { Tooltip, useTooltip } from '@ark-ui/vue/tooltip'
const tooltip = useTooltip()
</script>
<template>
<button @click="tooltip.setOpen(true)">Open</button>
<Tooltip.RootProvider :value="tooltip">
<Tooltip.Trigger>Hover Me</Tooltip.Trigger>
<Tooltip.Positioner>
<Tooltip.Content>I am a tooltip!</Tooltip.Content>
</Tooltip.Positioner>
</Tooltip.RootProvider>
</template>
If you're using the
RootProvider
component, you don't need to use theRoot
component.
API Reference
Root
Prop | Default | Type |
---|---|---|
aria-label | string Custom label for the tooltip. | |
closeDelay | 500 | number The close delay of the tooltip. |
closeOnClick | true | boolean Whether the tooltip should close on click |
closeOnEscape | true | boolean Whether to close the tooltip when the Escape key is pressed. |
closeOnPointerDown | true | boolean Whether to close the tooltip on pointerdown. |
closeOnScroll | true | boolean Whether the tooltip should close on scroll |
defaultOpen | boolean The initial open state of the tooltip when it is first rendered. Use when you do not need to control its open state. | |
disabled | boolean Whether the tooltip is disabled | |
id | string The `id` of the tooltip. | |
ids | Partial<{
trigger: string
content: string
arrow: string
positioner: string
}> The ids of the elements in the tooltip. Useful for composition. | |
immediate | boolean Whether to synchronize the present change immediately or defer it to the next frame | |
interactive | false | boolean Whether the tooltip's content is interactive. In this mode, the tooltip will remain open when user hovers over the content. |
lazyMount | false | boolean Whether to enable lazy mounting |
onExitComplete | () => void Function called when the animation ends in the closed state | |
onOpenChange | (details: OpenChangeDetails) => void Function called when the tooltip is opened. | |
open | boolean Whether the tooltip is open | |
openDelay | 1000 | number The open delay of the tooltip. |
positioning | PositioningOptions The user provided options used to position the popover content | |
present | boolean Whether the node is present (controlled by the user) | |
unmountOnExit | false | boolean Whether to unmount on exit. |
Arrow
Prop | Default | Type |
---|---|---|
asChild | (props: ParentProps<'div'>) => Element Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
ArrowTip
Prop | Default | Type |
---|---|---|
asChild | (props: ParentProps<'div'>) => Element Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
Content
Prop | Default | Type |
---|---|---|
asChild | (props: ParentProps<'div'>) => Element Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
Data Attribute | Value |
---|---|
[data-scope] | tooltip |
[data-part] | content |
[data-state] | "open" | "closed" |
[data-placement] | The placement of the content |
Positioner
Prop | Default | Type |
---|---|---|
asChild | (props: ParentProps<'div'>) => Element Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
RootProvider
Prop | Default | Type |
---|---|---|
value | UseTooltipReturn | |
immediate | boolean Whether to synchronize the present change immediately or defer it to the next frame | |
lazyMount | false | boolean Whether to enable lazy mounting |
onExitComplete | () => void Function called when the animation ends in the closed state | |
present | boolean Whether the node is present (controlled by the user) | |
unmountOnExit | false | boolean Whether to unmount on exit. |
Trigger
Prop | Default | Type |
---|---|---|
asChild | (props: ParentProps<'button'>) => Element Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
Data Attribute | Value |
---|---|
[data-scope] | tooltip |
[data-part] | trigger |
[data-expanded] | Present when expanded |
[data-state] | "open" | "closed" |
Accessibility
Complies with the Tooltip WAI-ARIA design pattern.
Keyboard Support
Key | Description |
---|---|
Tab | Opens/closes the tooltip without delay. |
Escape | If open, closes the tooltip without delay. |