Skip to content

Tooltip

Names a control the moment someone hovers it or tabs onto it.

View source View as Markdown

Tooltip puts a short label beside a control once the pointer has rested on it, or straight away when someone tabs onto it. Use it for the name of an icon button or a keyboard shortcut, never for anything a reader has to act on: the popup is not focusable and disappears again the moment the pointer moves on.

The example switches the teleport off, so the popup renders in place and scrolls with the frame around it rather than with the page.

App.vue
<template>
  <Tooltip.Group :options="{ timeout: 400 }">
    <div class="flex flex-wrap items-center gap-2">
      <Tooltip.Root
        v-for="action in actions"
        :key="action.label"
        :options="options"
      >
        <Tooltip.Trigger
          :aria-label="action.label"
          class="border-surface rounded-component-lg text-primary-solid hover:bg-primary-subtle active:bg-primary-subtle-active focus-visible:focus-ring inline-flex size-12 items-center justify-center border-2 outline-4 outline-transparent transition-all duration-100 ease-linear select-none"
        >
          <svg class="size-5" viewBox="0 0 20 20" aria-hidden="true">
            <path
              :d="action.path"
              fill="none"
              stroke="currentColor"
              stroke-width="1.5"
              stroke-linecap="round"
              stroke-linejoin="round"
            />
          </svg>
        </Tooltip.Trigger>

        <Tooltip.Content
          class="bg-primary-solid text-primary-on-solid type-component-sm rounded-component-md px-2.5 py-1.5 whitespace-nowrap select-none"
          :side-offset="8"
        >
          {{ action.label }}
          <Tooltip.Arrow
            class="bg-primary-solid size-2 rotate-45 data-[side=bottom]:bottom-full data-[side=bottom]:-mb-1 data-[side=left]:left-full data-[side=left]:-ml-1 data-[side=right]:right-full data-[side=right]:-mr-1 data-[side=top]:top-full data-[side=top]:-mt-1"
          />
        </Tooltip.Content>
      </Tooltip.Root>
    </div>
  </Tooltip.Group>
</template>

<script setup lang="ts">
import { Tooltip } from '@maas/mirror/vue/Tooltip'

const options = {
  delay: { mouseenter: 500 },
  teleport: { disabled: true },
}

const actions = [
  { label: 'Undo', path: 'M7 5 3 9l4 4M3 9h8a6 6 0 0 1 0 12H8' },
  { label: 'Redo', path: 'M13 5l4 4-4 4M17 9H9a6 6 0 0 0 0 12h3' },
  { label: 'Duplicate', path: 'M7 7V4h9v9h-3M4 7h9v9H4z' },
]
</script>

Usage guidelines

  • A tooltip is a hint rather than a name, so give the trigger an aria-label or visible text of its own; a reader who never hovers still has to know what the control does.must
  • Nothing in the popup can be reached by keyboard or by touch, so links, buttons and anything else a reader has to act on belong somewhere else.must not
  • Tooltip.Content teleports to the end of <body> unless you turn that off with options.teleport.disabled. Leave it on where the trigger sits inside anything with overflow: hidden.should
  • Wrap a row of triggers in one Tooltip.Group and the second tooltip opens the moment the pointer arrives, so scanning a row of icon buttons does not wait out the delay again at every one.may