# Portal Rendering and Content Display

The `TooltipPortal` and `TooltipContent` components work together to render tooltip content outside the normal DOM hierarchy with sophisticated positioning, collision detection, and accessibility features.

## Capabilities

### TooltipPortal Component

Portal component that renders children in a different part of the DOM, typically at the document body level.

```typescript { .api }
/**
 * Portal component for rendering tooltip content outside normal DOM flow
 * @param children - Content to portal (typically TooltipContent)
 * @param container - Container element to portal into (default: document.body)
 * @param forceMount - Force mounting when controlling animation externally
 */
interface TooltipPortalProps {
  children?: React.ReactNode;
  container?: HTMLElement;
  forceMount?: true;
}

const TooltipPortal: React.FC<TooltipPortalProps>;
```

### TooltipContent Component

Main tooltip content component with positioning, collision detection, and accessibility features.

```typescript { .api }
/**
 * Main tooltip content component with positioning and accessibility
 * @param children - Content to display in tooltip
 * @param side - Preferred side relative to trigger
 * @param sideOffset - Distance in pixels from trigger
 * @param align - Alignment relative to trigger
 * @param alignOffset - Offset in pixels along alignment axis
 * @param avoidCollisions - Whether to avoid viewport collisions
 * @param collisionBoundary - Boundary elements for collision detection
 * @param collisionPadding - Padding around collision boundary
 * @param arrowPadding - Minimum distance between arrow and content edges
 * @param sticky - Sticky behavior when trigger moves
 * @param hideWhenDetached - Hide when trigger is no longer visible
 * @param aria-label - Accessible label for tooltip
 * @param onEscapeKeyDown - Handler for escape key
 * @param onPointerDownOutside - Handler for outside pointer events
 * @param forceMount - Force mounting for animation control
 */
type TooltipContentElement = React.ComponentRef<"div">;
interface TooltipContentProps extends React.ComponentPropsWithoutRef<"div"> {
  side?: "top" | "right" | "bottom" | "left";
  sideOffset?: number;
  align?: "start" | "center" | "end";
  alignOffset?: number;
  avoidCollisions?: boolean;
  collisionBoundary?: Element | Element[];
  collisionPadding?: number | Partial<Record<"top" | "right" | "bottom" | "left", number>>;
  arrowPadding?: number;
  sticky?: "partial" | "always";
  hideWhenDetached?: boolean;
  'aria-label'?: string;
  onEscapeKeyDown?: (event: KeyboardEvent) => void;
  onPointerDownOutside?: (event: CustomEvent) => void;
  forceMount?: true;
}

const TooltipContent: React.forwardRef<TooltipContentElement, TooltipContentProps>;
```

**Usage Examples:**

```typescript
import { 
  TooltipProvider, 
  Tooltip, 
  TooltipTrigger,
  TooltipPortal,
  TooltipContent,
  TooltipArrow
} from "@radix-ui/react-tooltip";

// Basic portal and content
function BasicTooltip() {
  return (
    <TooltipProvider>
      <Tooltip>
        <TooltipTrigger>Hover me</TooltipTrigger>
        <TooltipPortal>
          <TooltipContent>
            Simple tooltip content
          </TooltipContent>
        </TooltipPortal>
      </Tooltip>
    </TooltipProvider>
  );
}

// Custom positioning
function PositionedTooltip() {
  return (
    <TooltipProvider>
      <Tooltip>
        <TooltipTrigger>Hover me</TooltipTrigger>
        <TooltipPortal>
          <TooltipContent
            side="right"
            align="start"
            sideOffset={10}
            alignOffset={5}
          >
            Positioned tooltip
            <TooltipArrow />
          </TooltipContent>
        </TooltipPortal>
      </Tooltip>
    </TooltipProvider>
  );
}

// Collision avoidance
function SmartTooltip() {
  return (
    <TooltipProvider>
      <Tooltip>
        <TooltipTrigger>Near edge</TooltipTrigger>
        <TooltipPortal>
          <TooltipContent
            side="top"
            avoidCollisions={true}
            collisionPadding={10}
          >
            This tooltip avoids viewport edges
          </TooltipContent>
        </TooltipPortal>
      </Tooltip>
    </TooltipProvider>
  );
}

// Custom portal container
function CustomPortalTooltip() {
  const containerRef = useRef<HTMLDivElement>(null);
  
  return (
    <div>
      <div ref={containerRef} className="custom-portal-container" />
      <TooltipProvider>
        <Tooltip>
          <TooltipTrigger>Hover me</TooltipTrigger>
          <TooltipPortal container={containerRef.current}>
            <TooltipContent>
              Rendered in custom container
            </TooltipContent>
          </TooltipPortal>
        </Tooltip>
      </TooltipProvider>
    </div>
  );
}

// Rich content tooltip
function RichContentTooltip() {
  return (
    <TooltipProvider>
      <Tooltip>
        <TooltipTrigger>Product info</TooltipTrigger>
        <TooltipPortal>
          <TooltipContent className="rich-tooltip">
            <div>
              <h3>Product Details</h3>
              <p>Price: $29.99</p>
              <p>In stock: 15 items</p>
            </div>
            <TooltipArrow />
          </TooltipContent>
        </TooltipPortal>
      </Tooltip>
    </TooltipProvider>
  );
}
```

### Portal Props

#### container

Specifies container element for portal rendering.

- **Type**: `HTMLElement`
- **Default**: `document.body`
- **Description**: Element to render portal content into

#### forceMount

Forces mounting regardless of open state for animation control.

- **Type**: `true`
- **Description**: Keeps content mounted for external animation libraries

### Content Props

#### Positioning Props

**side**: Preferred side relative to trigger
- **Type**: `"top" | "right" | "bottom" | "left"`
- **Default**: `"top"`

**sideOffset**: Distance from trigger
- **Type**: `number`
- **Default**: `0`

**align**: Alignment relative to trigger
- **Type**: `"start" | "center" | "end"`
- **Default**: `"center"`

**alignOffset**: Offset along alignment axis
- **Type**: `number`
- **Default**: `0`

#### Collision Detection Props

**avoidCollisions**: Enable collision detection
- **Type**: `boolean`
- **Default**: `true`

**collisionBoundary**: Elements to consider for collisions
- **Type**: `Element | Element[]`
- **Default**: Viewport boundaries

**collisionPadding**: Padding around collision boundary
- **Type**: `number | Partial<Record<"top" | "right" | "bottom" | "left", number>>`
- **Default**: `0`

#### Arrow Props

**arrowPadding**: Minimum distance between arrow and content edges
- **Type**: `number`
- **Default**: `0`

#### Behavior Props

**sticky**: Sticky behavior when trigger moves
- **Type**: `"partial" | "always"`
- **Default**: `"partial"`

**hideWhenDetached**: Hide when trigger is no longer visible
- **Type**: `boolean`
- **Default**: `false`

#### Accessibility Props

**aria-label**: Accessible label
- **Type**: `string`
- **Description**: Descriptive label for screen readers

#### Event Props

**onEscapeKeyDown**: Escape key handler
- **Type**: `(event: KeyboardEvent) => void`

**onPointerDownOutside**: Outside click handler
- **Type**: `(event: CustomEvent) => void`

### Content Features

#### Grace Area Hover

Content supports sophisticated hover behavior with grace areas:
- Pointer can move from trigger to content without closing
- Grace area calculations prevent accidental closing
- Smooth user experience when interacting with rich content

#### CSS Custom Properties

Content exposes positioning data via CSS custom properties:
- `--radix-tooltip-content-transform-origin`
- `--radix-tooltip-content-available-width`
- `--radix-tooltip-content-available-height`
- `--radix-tooltip-trigger-width`
- `--radix-tooltip-trigger-height`

#### Data Attributes

Content element receives data attributes for styling:
- `data-state`: `"closed" | "delayed-open" | "instant-open"`
- `data-side`: Current side placement
- `data-align`: Current alignment

### Portal and Content Aliases

```typescript { .api }
const Portal: React.FC<TooltipPortalProps>;
const Content: React.forwardRef<TooltipContentElement, TooltipContentProps>;
```

The `Portal` and `Content` components are aliases for shorter import names.

## Types

```typescript { .api }
type TooltipPortalProps = {
  children?: React.ReactNode;
  container?: HTMLElement;
  forceMount?: true;
};

type TooltipContentElement = React.ComponentRef<"div">;

type TooltipContentProps = React.ComponentPropsWithoutRef<"div"> & {
  side?: "top" | "right" | "bottom" | "left";
  sideOffset?: number;
  align?: "start" | "center" | "end";
  alignOffset?: number;
  avoidCollisions?: boolean;
  collisionBoundary?: Element | Element[];
  collisionPadding?: number | Partial<Record<"top" | "right" | "bottom" | "left", number>>;
  arrowPadding?: number;
  sticky?: "partial" | "always";
  hideWhenDetached?: boolean;
  'aria-label'?: string;
  onEscapeKeyDown?: (event: KeyboardEvent) => void;
  onPointerDownOutside?: (event: CustomEvent) => void;
  forceMount?: true;
};
```