Skip to main content

Tooltip Component - Radix UI v1.2.7

This document outlines the Tooltip component built on top of Radix UI Tooltip v1.2.7 using CSS Modules with Class Variance Authority (CVA).

Features

Built on Radix UI v1.2.7 - Latest stable release with all modern features ✅ Provider support - Global configuration for delay timing ✅ Portal support - Better z-index and layering control ✅ Animation variants - Smooth enter/exit animations ✅ Flexible positioning - 4 sides with 3 alignment options each ✅ Collision detection - Automatic repositioning to stay in viewport ✅ Arrow customization - Optional arrow with proper styling ✅ CSS Custom Properties - Leverages Radix's CSS variables for better animations ✅ TypeScript support - Full type safety with proper prop interfaces

Basic Usage

Simple Tooltip

import * as Tooltip from '~/modules/design-system@v2/components/Tooltip'

;<Tooltip.Provider>
<Tooltip.Root>
<Tooltip.Trigger asChild>
<Button variant="primary">Hover me</Button>
</Tooltip.Trigger>
<Tooltip.Tooltip>This is a tooltip</Tooltip.Tooltip>
</Tooltip.Root>
</Tooltip.Provider>

With Animation

<Tooltip.Tooltip type="animation" side="bottom" sideOffset={8}>
Animated tooltip with custom positioning
</Tooltip.Tooltip>

With Portal (for z-index control)

<Tooltip.Root>
<Tooltip.Trigger asChild>
<Button>Trigger</Button>
</Tooltip.Trigger>
<Tooltip.Portal>
<Tooltip.Tooltip>Content in portal</Tooltip.Tooltip>
</Tooltip.Portal>
</Tooltip.Root>

API Reference

Tooltip.Provider

Global configuration for all tooltips in the tree.

<Tooltip.Provider
delayDuration={300} // Delay before showing tooltip
skipDelayDuration={100} // Delay when moving between tooltips
>
{children}
</Tooltip.Provider>

Tooltip.Root

Container for the tooltip logic.

<Tooltip.Root
defaultOpen={false} // Initial open state
open={open} // Controlled open state
onOpenChange={setOpen} // Open state change handler
delayDuration={700} // Override global delay
>
{children}
</Tooltip.Root>

Tooltip.Trigger

The element that triggers the tooltip.

<Tooltip.Trigger asChild>
<Button>Trigger element</Button>
</Tooltip.Trigger>

Tooltip.Tooltip (Content)

The tooltip content with styling variants.

Props

PropTypeDefaultDescription
type'default' \| 'animation''default'Styling variant
withArrowbooleantrueShow/hide arrow
side'top' \| 'right' \| 'bottom' \| 'left''top'Preferred side
align'start' \| 'center' \| 'end''center'Alignment on the side
sideOffsetnumber4Distance from trigger
alignOffsetnumber0Offset from alignment
avoidCollisionsbooleantrueAuto-reposition on collision

Examples

{
/* Basic */
}
;<Tooltip.Tooltip>Simple tooltip</Tooltip.Tooltip>

{
/* Animated with custom positioning */
}
;<Tooltip.Tooltip type="animation" side="bottom" align="start" sideOffset={12} alignOffset={8}>
Advanced tooltip
</Tooltip.Tooltip>

{
/* Without arrow */
}
;<Tooltip.Tooltip withArrow={false}>No arrow tooltip</Tooltip.Tooltip>

Tooltip.Portal

Portal component for better layering control.

<Tooltip.Portal container={customContainer}>
<Tooltip.Tooltip>Portaled content</Tooltip.Tooltip>
</Tooltip.Portal>

Radix UI v1.2.7 Enhancements

CSS Custom Properties

The component leverages Radix UI's CSS custom properties for better animations:

.content {
// Transform origin based on positioning
transform-origin: var(--radix-tooltip-content-transform-origin);

// Available space constraints
max-width: var(--radix-tooltip-content-available-width);
max-height: var(--radix-tooltip-content-available-height);

// Trigger dimensions (useful for sizing)
width: var(--radix-tooltip-trigger-width); // if needed
height: var(--radix-tooltip-trigger-height); // if needed
}

Data Attributes for Animations

Radix UI provides data attributes for collision-aware animations:

.content {
// Side-aware animations
&[data-side='top'] {
animation-name: slideUp;
}
&[data-side='bottom'] {
animation-name: slideDown;
}
&[data-side='left'] {
animation-name: slideLeft;
}
&[data-side='right'] {
animation-name: slideRight;
}

// Alignment-aware styling
&[data-align='start'] {
/* start-aligned styles */
}
&[data-align='center'] {
/* center-aligned styles */
}
&[data-align='end'] {
/* end-aligned styles */
}
}

Migration from v1.1.x

New Features in v1.2.7

  1. Provider component - Global configuration
  2. Portal component - Better layering control
  3. Enhanced CSS variables - More animation possibilities
  4. Improved collision detection - Better boundary handling
  5. Better TypeScript support - More accurate prop types

Breaking Changes

  • Provider is now recommended for global configuration
  • Some internal implementation details may have changed
  • CSS custom property names updated
// Before (any version)
<Tooltip.Root>
<Tooltip.Trigger asChild>
<Button>Trigger</Button>
</Tooltip.Trigger>
<Tooltip.Tooltip>Content</Tooltip.Tooltip>
</Tooltip.Root>

// After (v1.2.7 - recommended pattern)
<Tooltip.Provider delayDuration={300}>
<Tooltip.Root>
<Tooltip.Trigger asChild>
<Button>Trigger</Button>
</Tooltip.Trigger>
<Tooltip.Portal>
<Tooltip.Tooltip type="animation">Content</Tooltip.Tooltip>
</Tooltip.Portal>
</Tooltip.Root>
</Tooltip.Provider>

Performance Notes

  • Use Provider at the app level to avoid multiple providers
  • Portal is optional but recommended for complex layouts
  • Animations use CSS transforms for better performance
  • CSS custom properties provide hardware-accelerated animations