Tooltip
A React source recipe with Base UI behavior and the public TIS Tooltip tokens.
Design
Functional preview
Running with the React source recipe distributed through shadcn and based on Base UI.
Loading functional preview…
Open the React · shadcn/Base UI playground
Anatomy
Edit document
2
3
4
1 Trigger — the element that activates the tooltip on hover/focus.
2 Tooltip container (
3 Arrow — CSS pseudo-element pointing toward the trigger.
4 Content — text only, no interactive elements.
2 Tooltip container (
.ds-tooltip) — dark background, positioned relative to trigger.3 Arrow — CSS pseudo-element pointing toward the trigger.
4 Content — text only, no interactive elements.
Positions
The tooltip content appears on the specified side of the trigger. The arrow (via ::before) points toward the trigger element.
Tooltip on top
Tooltip on bottom
Tooltip on left
Tooltip on right
With icon buttons
Tooltips are especially useful on icon-only buttons to clarify their purpose.
Edit
Delete
Token mapping
| Property | Token | CSS variable |
|---|---|---|
| background | semantic.background.inverse | --ds-background-inverse |
| text | semantic.brand.content.default | --ds-brand-content-default |
| padding-x | component.tooltip.content.padding-x.default | --ds-tooltip-content-padding-x-default |
| padding-y | component.tooltip.content.padding-y.default | --ds-tooltip-content-padding-y-default |
| border-radius | component.tooltip.content.radius.default | --ds-tooltip-content-radius-default |
| label font-size | component.tooltip.label.font-size.default | --ds-tooltip-label-font-size-default |
| label line-height | component.tooltip.label.line-height.default | --ds-tooltip-label-line-height-default |
| label font-weight | component.tooltip.label.font-weight.default | --ds-tooltip-label-font-weight-default |
| arrow base | component.tooltip.arrow.base.default | --ds-tooltip-arrow-base-default |
| arrow depth | component.tooltip.arrow.depth.default | --ds-tooltip-arrow-depth-default |
| z-index | semantic.z.tooltip | --ds-z-tooltip |
Usage
When to use
Use tooltips when
Providing supplementary, non-essential info on hover or focus: icon button labels, abbreviation explanations, brief clarifications.
Don't use tooltips when
The information is essential (make it visible by default), the content is interactive — links, buttons, or forms (use Popover), or the content is long (use Modal).
Best practices
Settings
Faça
Use tooltips on icon-only buttons to clarify their purpose. Keep under 80 characters.
Click here to open settings where you can change your theme, language, and notification preferences
Não faça
Put long content, links, buttons, or forms inside tooltips.
Edit document
Faça
Provide supplementary, non-essential information via tooltips.
Critical information only visible on hover
Não faça
Make tooltips the only way to convey critical info. Essential content should be always visible.
Content guidelines
| Rule | Example |
|---|---|
| Under 80 characters | "Edit document" — not a full paragraph |
| Sentence case | "Copy to clipboard" — not "Copy To Clipboard" |
| No period for fragments | "Delete item" — not "Delete item." |
| Text only — no interactive content | No links, buttons, or form elements inside tooltips |
React composition
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip"
import { Button } from "@/components/ui/button"
<TooltipProvider>
<Tooltip>
<TooltipTrigger render={<Button aria-label="Editar projeto" variant="outline" />}>
Editar
</TooltipTrigger>
<TooltipContent>Editar projeto</TooltipContent>
</Tooltip>
</TooltipProvider>Implementation
- Status
- Beta
- Distribution
- Source via shadcn
Installation
Configure the namespace once in the React integration guide.
npx shadcn@latest add @tis/tooltip @tis/button @tis/popoverpnpm dlx shadcn@latest add @tis/tooltip @tis/button @tis/popoveryarn dlx shadcn@latest add @tis/tooltip @tis/button @tis/popoverbunx --bun shadcn@latest add @tis/tooltip @tis/button @tis/popoverPublic contract
- Registry item
@tis/tooltip- Provider
- Base UI
- Distribution
- Source copied into the application
- Status
- Beta
Accessibility
Keyboard interaction
| Key | Action |
|---|---|
Tab (to trigger) | Shows tooltip when trigger receives focus |
Escape | Hides tooltip |
Tab (away) | Hides tooltip when focus leaves the trigger |
Accessibility
| WCAG criterion | Requirement | Status |
|---|---|---|
| 1.4.13 Content on Hover/Focus (AA) | Tooltip must be dismissable (Escape), hoverable (mouse can enter tooltip), and persistent (stays while hovered/focused) | ✓ |
| 4.1.2 Name, Role, Value (A) | Tooltip element has role="tooltip", trigger linked via aria-describedby | ✓ |
ARIA attributes summary
role="tooltip" — on the tooltip content element.aria-describedby — on the trigger, pointing to the tooltip's id.Tooltips must appear on both
hover and focus, and be dismissible with Escape.
Output responsibility
Preserve Base UI semantics and test real content, focus visibility, and accessible names in the consuming application.
Validation evidence
Covered by its independent Storybook output plus browser, responsive, keyboard, Axe, and bundle checks.