Usage
Use a Button or any other component in the default slot of the Tooltip.
<template>
<PTooltip text="Open on GitHub">
<PButton label="Open" color="neutral" variant="subtle" />
</PTooltip>
</template>App component which uses the TooltipProvider component from Akar.Text
Use the text prop to set the content of the Tooltip.
<template>
<PTooltip text="Open on GitHub">
<PButton label="Open" color="neutral" variant="subtle" />
</PTooltip>
</template>Kbds
Use the kbds prop to render Kbd components in the Tooltip.
<template>
<PTooltip text="Open on GitHub" :kbds="['meta', 'G']">
<PButton label="Open" color="neutral" variant="subtle" />
</PTooltip>
</template>meta that displays as ⌘ on macOS and Ctrl on other platforms.Delay
Use the delay-duration prop to change the delay before the Tooltip appears. For example, you can make it appear instantly by setting it to 0.
<template>
<PTooltip :delay-duration="0" text="Open on GitHub">
<PButton label="Open" color="neutral" variant="subtle" />
</PTooltip>
</template>tooltip.delayDuration option in the App component.Content
Use the content prop to control how the Tooltip content is rendered, like its align or side for example.
tooltip.content option in the App component.<template>
<PTooltip
:content="{
align: 'center',
side: 'bottom',
sideOffset: 8
}"
text="Open on GitHub"
>
<PButton label="Open" color="neutral" variant="subtle" />
</PTooltip>
</template>Arrow
Use the arrow prop to display an arrow on the Tooltip.
<template>
<PTooltip arrow text="Open on GitHub">
<PButton label="Open" color="neutral" variant="subtle" />
</PTooltip>
</template>Disabled
Use the disabled prop to disable the Tooltip.
<template>
<PTooltip disabled text="Open on GitHub">
<PButton label="Open" color="neutral" variant="subtle" />
</PTooltip>
</template>Examples
Control open state
You can control the open state by using the default-open prop or the v-model:open directive.
<script setup lang="ts">
const open = ref(false);
defineShortcuts({
o: () => open.value = !open.value,
});
</script>
<template>
<PTooltip
v-model:open="open"
text="Open on GitHub"
>
<PButton
label="Open"
color="neutral"
variant="subtle"
/>
</PTooltip>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const open = ref(false);
defineShortcuts({
o: () => open.value = !open.value,
});
</script>
<template>
<PTooltip
v-model:open="open"
text="Open on GitHub"
>
<PButton
label="Open"
color="neutral"
variant="subtle"
/>
</PTooltip>
</template>
defineShortcuts, you can toggle the Tooltip by pressing O.With following cursor
You can make the Tooltip follow the cursor when hovering over an element using the reference prop:
<script setup lang="ts">
const open = ref(false);
const anchor = ref({ x: 0, y: 0 });
const reference = computed(() => ({
getBoundingClientRect: () =>
({
width: 0,
height: 0,
left: anchor.value.x,
right: anchor.value.x,
top: anchor.value.y,
bottom: anchor.value.y,
...anchor.value,
} as DOMRect),
}));
</script>
<template>
<PTooltip
:open="open"
:reference="reference"
:content="{ side: 'top', sideOffset: 16, updatePositionStrategy: 'always' }"
>
<div
class="text-sm border border-border-accented rounded-md border-dashed flex w-72 aspect-video items-center justify-center"
@pointerenter="open = true"
@pointerleave="open = false"
@pointermove="(ev: PointerEvent) => {
anchor.x = ev.clientX
anchor.y = ev.clientY
}"
>
Hover me
</div>
<template #content>
{{ anchor.x.toFixed(0) }} - {{ anchor.y.toFixed(0) }}
</template>
</PTooltip>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
const open = ref(false);
const anchor = ref({ x: 0, y: 0 });
const reference = computed(() => ({
getBoundingClientRect: () =>
({
width: 0,
height: 0,
left: anchor.value.x,
right: anchor.value.x,
top: anchor.value.y,
bottom: anchor.value.y,
...anchor.value,
} as DOMRect),
}));
</script>
<template>
<PTooltip
:open="open"
:reference="reference"
:content="{ side: 'top', sideOffset: 16, updatePositionStrategy: 'always' }"
>
<div
class="text-sm border border-border-accented rounded-md border-dashed flex w-72 aspect-video items-center justify-center"
@pointerenter="open = true"
@pointerleave="open = false"
@pointermove="(ev: PointerEvent) => {
anchor.x = ev.clientX
anchor.y = ev.clientY
}"
>
Hover me
</div>
<template #content>
{{ anchor.x.toFixed(0) }} - {{ anchor.y.toFixed(0) }}
</template>
</PTooltip>
</template>
API
Props
| Prop | Default | Type |
|---|---|---|
text | stringThe text content of the tooltip. | |
kbds | (string | undefined)[] | KbdProps[]The keyboard keys to display in the tooltip. | |
content | { side: 'bottom', sideOffset: 8, collisionPadding: 8 } | TooltipContentProps & Partial<EmitsToProps<TooltipContentImplEmits>>The content of the tooltip. Inherits from the |
arrow | false | boolean | TooltipArrowProps Display an arrow alongside the tooltip.
|
portal | true | string | false | true | HTMLElementRender the tooltip in a portal. |
reference | Element | VirtualElementThe reference (or anchor) element that is being referred to for positioning. If not provided will use the current component as anchor. | |
defaultOpen | boolean The open state of the tooltip when it is initially rendered. Use when you do not need to control its open state. | |
open | boolean The controlled open state of the tooltip. | |
delayDuration | 700 | numberOverride the duration given to the |
disableHoverableContent | boolean Prevents Tooltip.Content from remaining open when hovering. Disabling this has accessibility consequences. Inherits from Tooltip.Provider. | |
disableClosingTrigger | false | boolean When |
disabled | false | boolean When |
ignoreNonKeyboardFocus | false | boolean Prevent the tooltip from opening if the focus did not come from
the keyboard by matching against the |
ui | { content?: SlotClass; arrow?: SlotClass; text?: SlotClass; kbds?: SlotClass; kbdsSize?: SlotClass; } |
Slots
| Slot | Type |
|---|---|
default | { open: boolean; } |
content | { ui: object; } |
Emits
| Event | Type |
|---|---|
update:open | [value: boolean] |
Theme
export default defineAppConfig({
ui: {
tooltip: {
slots: {
content: 'text-xs color-text-highlighted px-2.5 py-1 rounded-sm bg-background flex gap-1 h-6 max-w-[400px] pointer-events-auto select-none ring ring-border shadow-sm origin-$akar-tooltip-content-transform-origin items-center data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
arrow: 'fill-background stroke-border',
text: 'truncate',
kbds: "shrink-0 gap-0.5 hidden items-center lg:inline-flex not-first-of-type:before:me-0.5 not-first-of-type:before:content-['·']",
kbdsSize: 'sm'
}
}
}
})import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from 'pohon-ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
tooltip: {
slots: {
content: 'text-xs color-text-highlighted px-2.5 py-1 rounded-sm bg-background flex gap-1 h-6 max-w-[400px] pointer-events-auto select-none ring ring-border shadow-sm origin-$akar-tooltip-content-transform-origin items-center data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
arrow: 'fill-background stroke-border',
text: 'truncate',
kbds: "shrink-0 gap-0.5 hidden items-center lg:inline-flex not-first-of-type:before:me-0.5 not-first-of-type:before:content-['·']",
kbdsSize: 'sm'
}
}
}
})
]
})