shadcn.io is not affiliated with official shadcn/ui
Components
Free
Toggle Tooltip for React
Give an info icon a note that works on touch screens, not only on hover. For React with Base UI, when people need the text without hovering.
Framework
UI library
Base UI does not include this primitive, so this page uses the Ark UI component. The visuals match the Ark UI version.
Click or tap opens a short note, and a mouse hover can open it too.
Use it when the note has to work on a touch screen. A Tooltip is enough for a hint that only shows on hover or focus. In React, Base UI keeps the note open until it's dismissed.
Installation
Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
<ToggleTooltip>
<ToggleTooltipTrigger asChild>
<Buttonaria-label="More information"size="icon-md"variant="outline">
<InfoIcon />
</Button>
</ToggleTooltipTrigger>
<ToggleTooltipContentclassName="max-w-52">
Hover or click to see this content. Works on touch devices too.
</ToggleTooltipContent>
</ToggleTooltip>
Accessibility
KeyAction
Enter
Activate the focused control.
Space
Activate the focused control.
Demos
Info Icon
Each row of a data list gets its own info button: New Users, Sales, and Revenue, with one sentence in the note. The button is named for that metric, because the icon alone does not say which number it describes. Put it beside a label when a definition would clutter the row, and keep the note short. A long explanation belongs on the page, not in the bubble.
Side
Four triggers open the note on a different side: left, top, bottom, and right, via positioning and placement. Pin a side when the trigger sits in a corner or against a toolbar and the default would cover the thing it explains. The note can still flip if that side has no room. The content here is only the side name, so you can see the placement without reading a paragraph.
With Link
The note holds a real link, which is the reason to prefer this over a hover tooltip. A tooltip closes when the pointer moves toward the link, so the click never lands. Here the note stays open until a second click, a click outside, or Escape. Keep the interactive bit small, and put a form in a Popover instead.
FAQ
What is a Toggle Tooltip and when should I use it?
It is a tooltip that opens on click or tap instead of hover, so it also works on touch screens. Use it for an info icon next to a label or a setting; for hover hints on desktop, use a Tooltip.
What is the difference between a Toggle Tooltip, a Tooltip and a Popover?
A Tooltip shows on hover or focus and cannot hold interactive content. A Toggle Tooltip opens on click, stays until dismissed, and can hold a link, as in the With Link demo. A Popover is for larger content like a form.
How do I change where the Toggle Tooltip opens in React?
Pass positioning with a placement such as top, bottom, left or right, as the Side demo does. It flips to the other side when there is not enough room.
How do I open the Toggle Tooltip from code?
Keep the open state in state and pass it as open; use defaultOpen to start open.
onOpenChange receives details.open.
How do I close the Toggle Tooltip?
It closes on a second click of its trigger, a click outside, or Escape. It does not trap focus or block the page, so people can keep working while it is open.
How do I make the Toggle Tooltip trigger accessible?
Use a Button as the trigger, with asChild, and give an icon-only Button an aria-label that says what it explains, like the Info Icon demo's "Info about" labels. The trigger is announced as a button that opens its content.
How do I install the Toggle Tooltip in React?
Run the command in the Installation section above: it adds the Toggle Tooltip to your ui folder. It is built on Ark UI's popover on every base and framework.
The command uses the shadcn CLI.
API Reference
ToggleTooltip
data-slot="toggle-tooltip"
PropType
open?boolean
The controlled open state of the popover.
defaultOpen?boolean
The initial open state of the popover when rendered.
Use when you don't need to control the open state of the popover.
onOpenChange?(details: OpenChangeDetails) → void
Function invoked when the popover opens or closes.
Type
(details: OpenChangeDetails) → void
Parameters
details – { open: boolean }
Returns
void
triggerValue?string | null
The controlled trigger value.
Type
string | null
defaultTriggerValue?string | null
The initial trigger value when rendered.
Use when you don't need to control the trigger value.
Whether to automatically set focus on the first focusable
content within the popover when opened.
Default
true
closeOnEscape?boolean
Whether to close the popover when the escape key is pressed.
Default
true
closeOnInteractOutside?boolean
Whether to close the popover when the user clicks outside of the popover.
Default
true
dir?"ltr" | "rtl"
The document's text/writing direction.
Type
"ltr" | "rtl"
Default
"ltr"
finalFocusEl?() → MaybeElement
Element to receive focus when the popover is closed.
Returns
MaybeElement
hideMode?"display-none" | "activity"
How to hide content when mounted but not present.
- display-none: HTML hidden attribute. Effects stay alive.
- activity: React 19 <Activity mode="hidden">. Effects pause. Requires React 19+.
Type
"display-none" | "activity"
Default
"display-none"
id?string
The unique identifier of the machine.
ids?object
The ids of the elements in the popover. Useful for composition.
The element to focus on when the popover is opened.
Return false to skip moving focus, or null to use the default.
Type
() → HTMLElement | null | false
Returns
HTMLElement | null | false
lazyMount?boolean
Whether to enable lazy mounting. Ark default: false.
Default
true
modal?boolean
Whether the popover should be modal. When set to true:
- interaction with outside elements will be disabled
- only popover content will be visible to screen readers
- scrolling is blocked
- focus is trapped within the popover