dowelunreleased

Components

Tooltip

A hover and focus label on the popover elevation tier. Open timing, hover intent and focus-visible handling come from Base UI.

Anatomy

Compose Root, Trigger, Portal, Positioner and Popup. The positioner defaults to a 6px sideOffset.

tsx
import { IconButton, Tooltip } from "dowel";

<Tooltip.Root>
  <Tooltip.Trigger
    render={<IconButton label="Copy link"><CopyIcon /></IconButton>}
  />
  <Tooltip.Portal>
    <Tooltip.Positioner>
      <Tooltip.Popup>Copy link</Tooltip.Popup>
    </Tooltip.Positioner>
  </Tooltip.Portal>
</Tooltip.Root>

The shared delay

A single Tooltip.Provider at the app root is what lets adjacent tooltips share one delay: the first waits, and the next one the pointer reaches opens instantly instead of waiting again. Hover across this row to feel it.

tsx
// once, at the root of the app
<Tooltip.Provider>
  <App />
</Tooltip.Provider>

A tooltip is a visual label only

Base UI, which dowel builds on, deliberately does not associate the popup with its trigger — there is no aria-describedby and no touch affordance. So the tooltip text does not reach a screen reader, and the trigger has to carry its own accessible name. IconButton enforces exactly that with its required label prop, which is why every example above wraps one. If the hover content is information a user cannot do without, it does not belong in a Tooltip — reach for a Popover, which is announced.