Overlays

Tooltip

A short label that appears beside its trigger on hover and keyboard focus, for an icon button's purpose or a control's shortcut. It never opens on touch, and screen readers don't read it, so it only repeats or adds to what the page already says. Inside OuroProvider, tooltips share one delay: once one shows, its neighbours open instantly.

Hover or focus the button. It never opens on touch.

Install

Once per app, with Tailwind CSS v4 and an @/* path alias (Ouro HX is built on Base UI, so --base base; skip -t in an existing app):

npx shadcn@latest init --base base --preset nova --yes --no-monorepo
npx shadcn@latest add ourostack/ouro-ui/ouro-base#v1.2.13

Then the component. From v0.8.0 it installs only the helpers it imports and never touches your stylesheet (Installing):

npx shadcn@latest add ourostack/ouro-ui/tooltip#v1.2.13

Or, with the @ouro namespace set up:

npx shadcn@latest add @ouro/ouro-base @ouro/tooltip

Its tests, stories and Playwright spec are optional. They need Vitest 4.1.11 or later, and from v0.8.0 never change a version your app has (Testing):

npx shadcn@latest add ourostack/ouro-ui/tooltip#v1.2.13 ourostack/ouro-ui/tooltip-tests#v1.2.13
import { Tooltip } from "@/components/ouro/tooltip/tooltip";

Paths use shadcn's default @/ alias; the CLI rewrites them to yours.

Example

<Tooltip content="Add to cookbook">
  <Button aria-label="Save" variant="plain"><BookmarkIcon /></Button>
</Tooltip>
<Popover
  title="Share recipe"
  trigger={<Tooltip content="Share recipe"><Button aria-label="Share"><ShareIcon /></Button></Tooltip>}
>
  <TextField label="Link" defaultValue={url} readOnly />
</Popover>

Usage

It stacks above the page at --ouro-layer, a z-index of 50 by default (from ouro-base.css), like Dialog and Sheet.

Use instead when

  • Use Popover instead for anything the user needs or can act on (it opens on tap and holds controls), HoverCard for a preview of a link, and plain text on the page for essential information.

Props

Type: TooltipProps.

align
Type: "start" | "center" | "end"
Default: "center"
How the tooltip lines up with the trigger along that side.
children (required)
Type: ReactElement
The trigger: one element that can take focus, usually a Button. It needs a name of its own; give an icon-only button aria-label.
content (required)
Type: ReactNode
A short label for the trigger, a few words: "Add to cookbook". It shows on hover and keyboard focus, never on touch, and screen readers don't read it, so it must never hold anything the user needs.
side
Type: "top" | "bottom" | "left" | "right"
Default: "top"
The side of the trigger the tooltip sits on; it flips when there is no room.

Don't use

These are not props. Passing one fails the type check with the fix in the error, and in development a console message names the fix.

  • asChild: Not a prop. The child is the trigger: <Tooltip content="…"><Button>…</Button></Tooltip>.
  • delay: Not a prop. Ouro UI sets the delay, and OuroProvider groups tooltips so neighbours open instantly.
  • delayDuration: Not a prop. Ouro UI sets the delay, and OuroProvider groups tooltips so neighbours open instantly.
  • placement: Not a prop. Ouro UI splits placement into side and align: <Tooltip side="bottom" align="start">.
  • title: Not a prop. The text is content: <Tooltip content="Add to cookbook">.