Tooltip

Manual until a YAML contract lands in monochrome/spec/components/.

Hover/focus tooltip. Ids: mct:tooltip:<id> on the trigger, mcc:tooltip:<id> on the content. Linked with aria-describedby (not aria-controls). Content has role="tooltip" and popover="manual".

Tooltips do not use aria-expanded. Screen readers associate the description via aria-describedby regardless of visual visibility.

Composition

Root
  Trigger
  Content (role="tooltip" popover="manual")

Usage

HTML

html
<button type="button" id="mct:tooltip:save" aria-describedby="mcc:tooltip:save">
  Save
</button>
<div id="mcc:tooltip:save" role="tooltip" popover="manual">
  Saves to cloud (⌘S)
</div>

Author CSS may wrap or style these elements; monochrome ships no classes.

React

jsx
import { Tooltip } from "@monochrome-ui/react"

<Tooltip.Root>
  <Tooltip.Trigger>Save</Tooltip.Trigger>
  <Tooltip.Content>Saves to cloud (⌘S)</Tooltip.Content>
</Tooltip.Root>

Vue

vue
<script setup lang="ts">
import { Tooltip } from "@monochrome-ui/vue"
</script>

<template>
  <Tooltip.Root>
    <Tooltip.Trigger>Save</Tooltip.Trigger>
    <Tooltip.Content>Saves to cloud (⌘S)</Tooltip.Content>
  </Tooltip.Root>
</template>

Parts

Root

Required for wrappers. Element: div. Mints shared <id>.

Trigger

Required. Element: button (wrappers). Any focusable control works in HTML if ids and aria-describedby match.

Kind Name Type / value Description
attr type "button" When rendered as button.
attr id mct:tooltip:<id>
attr aria-describedby mcc:tooltip:<id> Points at Content.

Wrappers have no disabled prop. Putting aria-disabled="true" on the trigger does not stop the tooltip: core still shows it on hover/focus (covered by tests). Prefer a native disabled button (or remove the tooltip) if the control should not be interactive.

Content

Required. Element: div.

Kind Name Type / value Description
attr id mcc:tooltip:<id>
attr role "tooltip"
attr popover "manual" Core calls showPopover / hidePopover.

No aria-hidden toggle; visibility is popover show/hide only.

Notes

  • Show: Pointer enter or focus on Trigger (hover beats focus when both apply). Core publishes position CSS vars on show.
  • Hide: Pointer leave, blur, Escape, scroll that moves the anchor, or click on the trigger (suppresses until pointer/focus moves to a different trigger).
  • Escape: Suppresses the visible tooltip first (before menu / popover / dialog layers).
  • One at a time: Only one tooltip shown; switching triggers updates which content is open.
  • Structure independence: Trigger and Content need not be siblings; linkage is aria-describedby / ids.
  • Positioning: Author CSS with --top, --right, --bottom, --left, --pw, --ph. Delays (if wanted) belong in CSS (transition-delay), not JS timers.
  • Vs Popover: Tooltip is non-interactive description chrome. Prefer Popover when the panel contains actions or needs aria-expanded.

Keyboard

Key Behavior
Focus on Trigger Show tooltip
Blur Hide (unless hover keeps it)
Escape Suppress visible tooltip

No arrow-key navigation inside the tooltip.

See also