Gecko UIGecko UI

Tooltip

Contextual information in floating overlays

Tooltip

Tooltip displays contextual information in a floating overlay when users hover over or focus on an element. Built on Radix UI, it provides accessible tooltips with customizable positioning, delays, and styling.

Installation

import { Tooltip } from '@geckoui/geckoui';

Basic Usage

<Tooltip content="This is a tooltip" triggerAsChild>
  <Button>Hover me</Button>
</Tooltip>

Props API

PropTypeDefaultDescription
contentstring | ReactNode | FC-Tooltip content
side'top' | 'right' | 'bottom' | 'left''top'Tooltip position
delayDurationnumber700Delay before showing (ms)
sideOffsetnumber5Distance from trigger (px)
backgroundColorstring'#4b5563'Tooltip background color
classNamestring-CSS class for tooltip
triggerClassNamestring-CSS class for trigger
triggerAsChildbooleanfalseMerge trigger with child
childrenReactNode-Trigger element (required)

Examples

Different Positions

<Tooltip content="Top tooltip" side="top" triggerAsChild>
  <Button>Top</Button>
</Tooltip>

<Tooltip content="Right tooltip" side="right" triggerAsChild>
  <Button>Right</Button>
</Tooltip>

<Tooltip content="Bottom tooltip" side="bottom" triggerAsChild>
  <Button>Bottom</Button>
</Tooltip>

<Tooltip content="Left tooltip" side="left" triggerAsChild>
  <Button>Left</Button>
</Tooltip>

Icon Buttons

<Tooltip content="Add new item" side="right" delayDuration={300} triggerAsChild>
  <Button variant="icon">
    <PlusIcon />
  </Button>
</Tooltip>

<Tooltip content="Edit item" side="right" delayDuration={300} triggerAsChild>
  <Button variant="icon">
    <EditIcon />
  </Button>
</Tooltip>

Complex Content

<Tooltip
  content={
    <div>
      <strong>Premium Feature</strong>
      <p>Upgrade to access this feature</p>
    </div>
  }
  backgroundColor="#1f2937"
  sideOffset={10}
  triggerAsChild
>
  <Button variant="outlined">
    <LockIcon />
    <span>Locked Feature</span>
  </Button>
</Tooltip>

Custom Delay

<Tooltip content="Instant tooltip" delayDuration={0} triggerAsChild>
  <Button>No delay</Button>
</Tooltip>

<Tooltip content="Quick tooltip" delayDuration={200} triggerAsChild>
  <Button>200ms</Button>
</Tooltip>

<Tooltip content="Standard tooltip" delayDuration={700} triggerAsChild>
  <Button>700ms (default)</Button>
</Tooltip>

Custom Colors

<Tooltip content="Blue tooltip" backgroundColor="#3b82f6" triggerAsChild>
  <Button>Blue</Button>
</Tooltip>

<Tooltip content="Red tooltip" backgroundColor="#ef4444" triggerAsChild>
  <Button>Red</Button>
</Tooltip>

Info Hints

<Tooltip
  content="Last updated: 2 hours ago"
  side="bottom"
  delayDuration={500}
>
  <span>Status: Active</span>
</Tooltip>

<Tooltip
  content="This action cannot be undone"
  backgroundColor="#ef4444"
  triggerAsChild
>
  <Button>Delete Account</Button>
</Tooltip>

With Offset

<Tooltip content="Close to trigger" sideOffset={2} triggerAsChild>
  <Button>Offset: 2px</Button>
</Tooltip>

<Tooltip content="Far from trigger" sideOffset={15} triggerAsChild>
  <Button>Offset: 15px</Button>
</Tooltip>

Disabled Buttons

<Tooltip content="This feature is currently disabled" triggerAsChild>
  <Button disabled>Disabled Button</Button>
</Tooltip>

Behavior

No Content

If no content prop is provided, the tooltip returns children unchanged without any wrapper:

<Tooltip>
  <Button>No tooltip</Button>
</Tooltip>
// Renders: <Button>No tooltip</Button>

Trigger as Child

Use triggerAsChild={true} to avoid invalid HTML nesting (like button inside button) and prevent hydration errors in Next.js. This is especially important when using focusable elements like Button:

<Tooltip content="Tooltip text" triggerAsChild>
  <Button>I am a button</Button>
</Tooltip>

This prevents the invalid HTML structure:

<!-- Without triggerAsChild (incorrect - causes hydration error) -->
<button type="button">
  <button>I am a button</button>
</button>

<!-- With triggerAsChild (correct) -->
<button>I am a button</button>

Important: In Next.js, <button> cannot be a descendant of <button>. Always use triggerAsChild when the child is a focusable element like Button.

Arrow Display

The tooltip arrow is displayed only for top and bottom positions. It matches the backgroundColor prop.

Accessibility

  • Built on Radix UI for WCAG compliance
  • Proper ARIA attributes automatically applied
  • Keyboard accessible (focus shows tooltip)
  • Works with screen readers
  • role="tooltip" on trigger and content
  • Hover and focus both trigger display

Styling

The component uses BEM-style class names:

  • GeckoUITooltip - Tooltip content container
  • GeckoUITooltip__trigger - Trigger wrapper (when triggerAsChild={false})
  • GeckoUITooltip__arrow - Arrow element

Override styles using className for content or triggerClassName for trigger.

Dependencies

This component uses @radix-ui/react-tooltip for accessibility and behavior.

  • Label - Labels with built-in tooltips
  • Alert - Page-level messages