Tooltip
It is commonly used to display prompt information when the mouse hover.
Basic Usage
Use placement to set position of Tooltip, and use content to set content of Tooltip.
<template>
<div class="max-w-600px mx-auto">
<div class="flex justify-center">
<re-tooltip placement="top-start" content="Top Start Text Prompt">
<re-button>top-start</re-button>
</re-tooltip>
<re-tooltip placement="top" content="Top Center Text Prompt">
<re-button>top</re-button>
</re-tooltip>
<re-tooltip placement="top-end" content="Top End Text Prompt">
<re-button>top-end</re-button>
</re-tooltip>
</div>
<div class="flex justify-between">
<div class="flex flex-col items-start">
<re-tooltip placement="left-start" width="120" content="Left Start Text Prompt">
<re-button>left-start</re-button>
</re-tooltip>
<re-tooltip placement="left" width="120px" content="Left Middle Text Prompt">
<re-button class="mt-1em ml-0!">left</re-button>
</re-tooltip>
<re-tooltip placement="left-end" width="120px" content="Left End Text Prompt">
<re-button class="mt-1em ml-0!">left-end</re-button>
</re-tooltip>
</div>
<div class="flex flex-col items-end">
<re-tooltip placement="right-start" width="120px" content="Right Start Text Prompt">
<re-button>right-start</re-button>
</re-tooltip>
<re-tooltip placement="right" width="120px" content="Right Center Text Prompt">
<re-button class="mt-1em ml-0!">right</re-button>
</re-tooltip>
<re-tooltip placement="right-end" width="120px" content="Right End Text Prompt">
<re-button class="mt-1em ml-0!">right-end</re-button>
</re-tooltip>
</div>
</div>
<div class="flex justify-center">
<re-tooltip placement="bottom-start" content="Bottom Start Text Prompt">
<re-button>bottom-start</re-button>
</re-tooltip>
<re-tooltip placement="bottom" content="Bottom Center Text Prompt">
<re-button>bottom</re-button>
</re-tooltip>
<re-tooltip placement="bottom-end" content="Bottom End Text Prompt">
<re-button>bottom-end</re-button>
</re-tooltip>
</div>
</div>
</template>Trigger
Use hover 、 click 、 focus and contextmenu to display Tooltip by trigger attribute.
<template>
<re-tooltip content="Tooltip text" trigger="hover">
<re-button>Hover</re-button>
</re-tooltip>
<re-tooltip content="Tooltip text" trigger="click">
<re-button>Click</re-button>
</re-tooltip>
<re-tooltip content="Tooltip text" trigger="focus">
<re-button>Focus</re-button>
</re-tooltip>
<re-tooltip content="Tooltip text" trigger="contextmenu" placement="right">
<re-button>Contextmenu</re-button>
</re-tooltip>
</template>Content
Use content or slot#content to set Tooltip content, is-html for render HTML content.
<template>
<re-tooltip content="<i>Text Content</i>" trigger="hover">
<re-button>Text Content</re-button>
</re-tooltip>
<re-tooltip content="<i>HTML Content</i>" is-html trigger="hover">
<re-button>HTML Content</re-button>
</re-tooltip>
<re-tooltip trigger="hover">
<re-button>Slot Content</re-button>
<template #content>
<span style="color: var(--re-color-primary-base)">The Slot Content</span>
</template>
</re-tooltip>
</template>Disabled
Use disabled to disable Tooltip.
<template>
<div>
<re-tooltip :disabled="disabled" content="Disabled tooltip" trigger="hover">
<re-button type="success" :disabled="disabled">
{{ disabled ? 'Disabled' : 'Enabled' }}
</re-button>
</re-tooltip>
<re-button class="ml-5em!" @click="toggle">Click to toggle</re-button>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const disabled = ref(false)
const toggle = () => {
disabled.value = !disabled.value
}
</script>Customize Boundary
Use boundary and rootBoundary to set Tooltip boundary.
<template>
<div>
<div class="flex flex-wrap">
<div
ref="container1"
class="h-300px grow basis-300px of-x-hidden of-y-auto text-center demo-border"
>
<div class="h-300px"></div>
<re-tooltip
v-if="container1"
:boundary="container1"
content="Scroll me to top boundary"
:visible="visible"
>
<re-button>boundary: container</re-button>
</re-tooltip>
<div class="h-300px"></div>
</div>
<div
ref="container2"
class="h-300px grow flex basis-300px items-center of-x-auto demo-border"
>
<div class="w-500px shrink-0"></div>
<re-tooltip
v-if="container2"
content="Scroll me to left boundary"
:boundary="container2"
:visible="visible"
placement="left"
>
<re-button>boundary: container</re-button>
</re-tooltip>
<div class="w-500px shrink-0"></div>
</div>
</div>
<div
ref="container3"
class="h-300px flex-1 of-hidden of-y-auto shrink-0 text-center demo-border"
>
<div class="h-300px"></div>
<re-tooltip content="Scroll me to body top boundary" :visible="visible">
<re-button>rootBoundary: 'viewport'</re-button>
</re-tooltip>
<div class="h-300px"></div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
const visible = ref<boolean>(true)
const container1 = ref()
const container2 = ref()
const container3 = ref()
onMounted(() => {
container1.value.scrollTo(0, 160)
container2.value.scrollTo(220, 0)
container3.value.scrollTo(0, 160)
})
</script>Flip
By default, the Tooltip layer will auto flip based on the viewport, but when one of the below:
1、boundary: 'clippingAncestors' and altBoundary: true.
2、elementContext: 'reference'.
it will flip based on the parent container of the reference which is overflow: hidden/auto/scroll.
Otherwise, use flipOptions attribute for more behaviors.
<template>
<div class="flex flex-wrap">
<div
ref="container1"
class="h-300px grow basis-300px of-hidden of-y-auto shrink-0 text-center demo-border"
>
<div class="h-300px"></div>
<re-tooltip v-model:visible="visible" alt-boundary content="Scroll me to top boundary">
<re-button>altBoundary: true</re-button>
</re-tooltip>
<div class="h-300px"></div>
</div>
<div
ref="container2"
class="h-300px grow basis-300px flex items-center min-w-0 of-x-auto demo-border"
>
<div class="w-500px shrink-0"></div>
<re-tooltip
content="Scroll me to left boundary"
alt-boundary
:visible="visible"
placement="left"
>
<re-button>altBoundary: true</re-button>
</re-tooltip>
<div class="w-500px shrink-0"></div>
</div>
</div>
<div class="flex flex-wrap">
<div
ref="container3"
class="h-300px grow basis-300px of-hidden of-y-auto shrink-0 text-center demo-border"
>
<div class="h-300px"></div>
<re-tooltip
element-context="reference"
content="elementContext: 'reference'"
:visible="visible"
>
<re-button>Scroll me to top boundary</re-button>
</re-tooltip>
<div class="h-300px"></div>
</div>
<div
ref="container4"
class="h-300px grow basis-300px flex items-center min-w-0 of-x-auto demo-border"
>
<div class="w-500px shrink-0"></div>
<re-tooltip
content="elementContext: 'reference'"
element-context="reference"
:visible="visible"
placement="left"
>
<re-button>Scroll me to left boundary</re-button>
</re-tooltip>
<div class="w-500px shrink-0"></div>
</div>
</div>
<div class="flex flex-wrap">
<div
ref="container5"
class="h-300px grow basis-300px of-hidden of-y-auto shrink-0 text-center demo-border"
>
<div class="h-300px"></div>
<re-tooltip
alt-boundary
:flip-options="{ fallbackPlacements: ['top', 'right', 'bottom'] }"
content="Scroll me to top boundary"
:visible="visible"
>
<re-button class="mr-15em">altBoundary: true</re-button>
</re-tooltip>
<div class="h-300px"></div>
</div>
<div
ref="container6"
class="h-300px grow basis-300px flex items-center min-w-0 of-x-auto demo-border"
>
<div class="w-500px shrink-0"></div>
<re-tooltip
content="Scroll me to left boundary"
alt-boundary
:flip-options="{ fallbackPlacements: ['top', 'right', 'bottom'] }"
:visible="visible"
placement="left"
>
<re-button>altBoundary: true</re-button>
</re-tooltip>
<div class="w-500px shrink-0"></div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
const visible = ref<boolean>(true)
const container1 = ref()
const container2 = ref()
const container3 = ref()
const container4 = ref()
const container5 = ref()
const container6 = ref()
onMounted(() => {
container1.value.scrollTo(0, 160)
container2.value.scrollTo(220, 0)
container3.value.scrollTo(0, 160)
container4.value.scrollTo(220, 0)
container5.value.scrollTo(0, 160)
container6.value.scrollTo(220, 0)
})
</script>External Reference
Use is-external to activate external-ref, this allows you to place the reference element outside Tooltip.
Basic External Trigger Reference
Multiple External Trigger References for singleton
<template>
<p>Basic External Trigger Reference</p>
<re-tooltip
content="Tooltip text"
trigger="hover"
is-external
:external-ref="externalRef"
></re-tooltip>
<re-button ref="buttonRef" @mouseenter="setExternal">Hover me</re-button>
<p>Multiple External Trigger References for singleton</p>
<re-tooltip
content="Tooltip text"
trigger="hover"
is-external
:external-ref="hoverRef"
></re-tooltip>
<re-button ref="buttonRef1" @mouseenter="setRef1()">Hover me 1</re-button>
<re-button ref="buttonRef2" @mouseenter="setRef2()">Hover me 2</re-button>
<re-button ref="buttonRef3" @mouseenter="setRef3()">Hover me 3</re-button>
<p></p>
<re-tooltip
content="Tooltip text"
trigger="click"
is-external
:external-ref="clickRef"
></re-tooltip>
<re-button ref="buttonRef4" @click="setRef4()">Click me 1</re-button>
<re-button ref="buttonRef5" @click="setRef5()">Click me 2</re-button>
<re-button ref="buttonRef6" @click="setRef6()">Click me 3</re-button>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const buttonRef = ref()
const externalRef = ref()
const setExternal = () => {
externalRef.value = buttonRef.value
}
const buttonRef1 = ref()
const buttonRef2 = ref()
const buttonRef3 = ref()
const hoverRef = ref()
const setRef1 = () => {
hoverRef.value = buttonRef1.value
}
const setRef2 = () => {
hoverRef.value = buttonRef2.value
}
const setRef3 = () => {
hoverRef.value = buttonRef3.value
}
const buttonRef4 = ref()
const buttonRef5 = ref()
const buttonRef6 = ref()
const clickRef = ref()
const setRef4 = () => {
clickRef.value = buttonRef4.value
}
const setRef5 = () => {
clickRef.value = buttonRef5.value
}
const setRef6 = () => {
clickRef.value = buttonRef6.value
}
</script>Virtual Reference
Use is-virtual to activate virtual-ref, it accepts an object with layout properties to build the reference, visible maybe is needed.
<template>
<re-tooltip
content="Tooltip text"
:visible="visible"
is-virtual
:virtual-ref="virtualRef"
></re-tooltip>
<re-button @click="visible = !visible">Click me</re-button>
</template>
<script lang="ts" setup>
import { ref, onMounted, onUnmounted } from 'vue'
const visible = ref<boolean>(false)
const position = ref<Record<string, number>>({
width: 0,
height: 0,
x: 0,
y: 0,
top: 0,
left: 0,
right: 0,
bottom: 0
})
const virtualRef = ref({
getBoundingClientRect: () => position.value
})
const move = ({ clientX, clientY }: MouseEvent) => {
position.value = {
width: 0,
height: 0,
x: clientX,
y: clientY,
top: clientY,
left: clientX,
right: clientX,
bottom: clientY
}
}
onMounted(() => {
document.addEventListener('mousemove', move)
})
onUnmounted(() => {
document.removeEventListener('mousemove', move)
})
</script>Selection Range Build A Virtual Reference
Use is-virtual to activate virtual-ref, it also allows a selection Range to build the reference.
<template>
<re-tooltip
content="Tooltip text"
:visible="visible"
is-virtual
:virtual-ref="rangeRef"
></re-tooltip>
<span ref="textRef">Select the text to visible the Tooltip</span>
</template>
<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
const visible = ref<boolean>(false)
const textRef = ref<HTMLSpanElement | null>(null)
const range = ref<Range | null>()
const rangeRef = {
getBoundingClientRect: () => range.value?.getBoundingClientRect(),
getClientRects: () => range.value?.getClientRects()
}
const mouseup = (e: MouseEvent | TouchEvent) => {
range.value?.selectNode(textRef.value!)
const selection = window.getSelection()
if (!textRef.value || !selection || selection.rangeCount === 0) return
const currentRange = selection.getRangeAt(0)
const container = currentRange.commonAncestorContainer
const text = selection.toString().trim()
// Ensure the selection originates from the target element
if (textRef.value.contains(container!)) {
range.value = currentRange.cloneRange()
visible.value = !!text
}
}
const selectionChange = () => {
const selection = window.getSelection()
const text = selection?.toString()?.trim()
if (!text) {
visible.value = false
}
}
onMounted(() => {
document.addEventListener('mouseup', mouseup)
document.addEventListener('touchend', mouseup)
document.addEventListener('selectionchange', selectionChange)
})
onBeforeUnmount(() => {
document.removeEventListener('mouseup', mouseup)
document.removeEventListener('touchend', mouseup)
document.removeEventListener('selectionchange', selectionChange)
})
</script>Tooltip Attributes
| Name | Description | Type | Default |
|---|---|---|---|
| placement | Tooltip position | enum | top |
| trigger | The trigger event name | enum | hover |
| content | Tooltip content | string | — |
| is-html | Whether content is treated as HTML string | boolean | — |
| disabled | Whether Tooltip is disabled | boolean | — |
| visible / v-model:visible | Whether Tooltip is visible | boolean | — |
| offset | Offset from the reference edge. See Floating UI OffsetOptions for details | number | interface | 10 |
| width | Tooltip width | number | string | — |
| height | Tooltip height | number | string | — |
| max-width | Tooltip max width | number | string | — |
| max-height | Tooltip max height | number | string | — |
| theme | Tooltip theme | 'dark' |'light' | dark |
| reverse-theme | whether to reverse Tooltip theme color | boolean | false |
| append-to | Target element for appending Tooltip | cssSelector | HTMLElement | body |
| teleported | Whether to teleport Tooltip to the appendTo target | boolean | true |
| persistent | Whether to keep the floating open on hover | boolean | true |
| click-to-toggle | Whether to toggle the floating on click, only trigger='click' | boolean | true |
| floating-class | Custom class for the floating | string | object | Array | — |
| floating-style | Custom style for the floating | string | object | Array | — |
| show-delay | Delay(ms) before Tooltip appears , but not effective when visible is present or is-virtual or is-external | number | 0 |
| hide-delay | Delay(ms) before Tooltip disappears , but not effective when visible is present or is-virtual or is-external | number | 200 |
| show-arrow | Whether to show arrow for Tooltip | boolean | true |
| arrow-size | The arrow size | number | 8 |
| arrow-offset | Padding between the arrow and the Tooltip edge | number | 4 |
| arrow-options | Floating UI ArrowOptions Parameters | interface | — |
| transition | Name of Vue3 Transition component | string | tooltip |
| css-transition | Css of Vue3 Transition component | boolean | true |
| transform | Whether to use transform positioning instead of top/left positioning | boolean | true |
| strategy | The type of CSS position property to use | 'absolute' | 'fixed' | absolute |
| css-duration | Duration of Vue3 Transition component for fade in/fade out | number | 300 |
| boundary | Boundary of Floating UI DetectOverflowOptions : interface | union | clippingAncestors |
| alt-boundary | AltBoundary of Floating UI DetectOverflowOptions | boolean | false |
| root-boundary | RootBoundary of Floating UI DetectOverflowOptions | union | viewport |
| element-context | ElementContext of Floating UI DetectOverflowOptions | 'reference' | 'floating' | floating |
| flip-offset | Offset from boundary before flipping, Padding of Floating UI DetectOverflowOptions | union | 8 |
| flip-options | Floating UI FlipOptions Parameters | interface | — |
| inline-options | Floating UI InlineOptions Parameters | interface | — |
| is-external | Whether external reference is enabled | boolean | — |
| external-ref | External reference target | HTMLElement | — |
| is-virtual | Whether virtual reference is enabled | boolean | — |
| virtual-ref | Virtual reference object for Floating UI VirtualElement | interface | — |
Tooltip Events
| Name | Description | Parameters |
|---|---|---|
| before-enter | Vue3 <Transition> event hook | Function |
| enter | Vue3 <Transition> event hook | Function |
| after-enter | Vue3 <Transition> event hook | Function |
| before-leave | Vue3 <Transition> event hook | Function |
| leave | Vue3 <Transition> event hook | Function |
| after-leave | Vue3 <Transition> event hook | Function |
| enter-cancelled | Vue3 <Transition> event hook | Function |
| leave-cancelled | Vue3 <Transition> event hook | Function |
Tooltip Slots
| Name | Description |
|---|---|
| default | Customize default reference |
| content | Customize default content |
Tooltip Exposes
| Name | Description | Type |
|---|---|---|
| update | Manually updates the Tooltip position | Function |
| show | Manually show the Tooltip | Function |
| hide | Manually hide the Tooltip | Function |
| triggerRef | The trigger refernce element | HTMLElement |
| floatingRef | The Tooltip layer element | HTMLElement |
| arrowRef | The Tooltip arrow element | HTMLElement |
