# Content Management

Content and viewport components for displaying menu content with animation support and focus management.

## Capabilities

### NavigationMenuContent

Dismissable content panel that displays when a navigation menu item is triggered, with built-in focus management and animation support.

```typescript { .api }
/**
 * Content panel for navigation menu items with dismissable layer integration
 * @param forceMount - Force mounting for animation control (useful with animation libraries)
 */
const NavigationMenuContent: React.ForwardRefExoticComponent<
  NavigationMenuContentProps & React.RefAttributes<HTMLDivElement>
>;

interface NavigationMenuContentProps 
  extends React.ComponentPropsWithoutRef<"div"> {
  forceMount?: true;
}
```

**Key Features:**
- Dismissable layer integration (clicks outside, Escape key)
- Focus management and tab order handling
- Animation support via `forceMount` prop
- Portal rendering (when used with viewport)
- Keyboard navigation within content
- Pointer interaction handling

**Usage Examples:**

```typescript
import { 
  NavigationMenu,
  NavigationMenuList,
  NavigationMenuItem,
  NavigationMenuTrigger,
  NavigationMenuContent,
  NavigationMenuLink
} from "@radix-ui/react-navigation-menu";

// Basic content usage
function BasicContentExample() {
  return (
    <NavigationMenu>
      <NavigationMenuList>
        <NavigationMenuItem>
          <NavigationMenuTrigger>Products</NavigationMenuTrigger>
          <NavigationMenuContent className="nav-content">
            <div className="content-grid">
              <NavigationMenuLink href="/web">Web Development</NavigationMenuLink>
              <NavigationMenuLink href="/mobile">Mobile Apps</NavigationMenuLink>
              <NavigationMenuLink href="/desktop">Desktop Software</NavigationMenuLink>
            </div>
          </NavigationMenuContent>
        </NavigationMenuItem>
      </NavigationMenuList>
    </NavigationMenu>
  );
}

// Content with force mount for animations
function AnimatedContentExample() {
  return (
    <NavigationMenuItem>
      <NavigationMenuTrigger>Services</NavigationMenuTrigger>
      <NavigationMenuContent 
        forceMount
        className="animated-content"
        onPointerEnter={() => console.log("Content entered")}
        onPointerLeave={() => console.log("Content left")}
      >
        <div className="service-list">
          <h3>Our Services</h3>
          <NavigationMenuLink href="/consulting">Consulting</NavigationMenuLink>
          <NavigationMenuLink href="/support">Support</NavigationMenuLink>
          <NavigationMenuLink href="/training">Training</NavigationMenuLink>
        </div>
      </NavigationMenuContent>
    </NavigationMenuItem>
  );
}

// Rich content with complex layout
function RichContentExample() {
  return (
    <NavigationMenuItem>
      <NavigationMenuTrigger>Resources</NavigationMenuTrigger>
      <NavigationMenuContent>
        <div className="resource-content">
          <div className="resource-section">
            <h4>Documentation</h4>
            <NavigationMenuLink href="/docs/getting-started">Getting Started</NavigationMenuLink>
            <NavigationMenuLink href="/docs/api">API Reference</NavigationMenuLink>
            <NavigationMenuLink href="/docs/examples">Examples</NavigationMenuLink>
          </div>
          
          <div className="resource-section">
            <h4>Community</h4>
            <NavigationMenuLink href="/forum">Forum</NavigationMenuLink>
            <NavigationMenuLink href="/discord">Discord</NavigationMenuLink>
            <NavigationMenuLink href="/github">GitHub</NavigationMenuLink>
          </div>
          
          <div className="resource-section">
            <h4>Latest</h4>
            <p>Check out our latest blog post about navigation patterns.</p>
            <NavigationMenuLink href="/blog/latest">Read More</NavigationMenuLink>
          </div>
        </div>
      </NavigationMenuContent>
    </NavigationMenuItem>
  );
}
```

### NavigationMenuViewport

Centralized viewport container that manages and displays menu content with dynamic sizing and positioning.

```typescript { .api }
/**
 * Centralized viewport for menu content with dynamic sizing
 * Provides a container that automatically sizes to match active content
 * @param forceMount - Force mounting for animation control
 */
const NavigationMenuViewport: React.ForwardRefExoticComponent<
  NavigationMenuViewportProps & React.RefAttributes<HTMLDivElement>
>;

interface NavigationMenuViewportProps 
  extends React.ComponentPropsWithoutRef<"div"> {
  forceMount?: true;
}
```

**Key Features:**
- Dynamic sizing based on active content
- CSS custom properties for dimensions
- Portal rendering for content
- Animation support with presence detection
- Pointer event handling
- Content lifecycle management

**Usage Examples:**

```typescript
import { 
  NavigationMenu,
  NavigationMenuList,
  NavigationMenuItem,
  NavigationMenuTrigger,
  NavigationMenuContent,
  NavigationMenuViewport
} from "@radix-ui/react-navigation-menu";

// Basic viewport setup
function ViewportExample() {
  return (
    <div className="nav-container">
      <NavigationMenu>
        <NavigationMenuList>
          <NavigationMenuItem>
            <NavigationMenuTrigger>Products</NavigationMenuTrigger>
            <NavigationMenuContent>
              <div className="products-content">
                {/* Content will be rendered in viewport */}
                Product information here
              </div>
            </NavigationMenuContent>
          </NavigationMenuItem>
          
          <NavigationMenuItem>
            <NavigationMenuTrigger>Services</NavigationMenuTrigger>
            <NavigationMenuContent>
              <div className="services-content">
                {/* Different sized content */}
                Much larger service information content here
                with multiple sections and detailed descriptions
              </div>
            </NavigationMenuContent>
          </NavigationMenuItem>
        </NavigationMenuList>
        
        {/* Viewport renders all content and manages transitions */}
        <NavigationMenuViewport className="nav-viewport" />
      </NavigationMenu>
    </div>
  );
}

// Viewport with custom styling using CSS custom properties
function StyledViewportExample() {
  return (
    <NavigationMenu>
      <NavigationMenuList>
        <NavigationMenuItem>
          <NavigationMenuTrigger>Large Content</NavigationMenuTrigger>
          <NavigationMenuContent>
            <div style={{ width: "400px", height: "300px" }}>
              Large content area
            </div>
          </NavigationMenuContent>
        </NavigationMenuItem>
      </NavigationMenuList>
      
      <NavigationMenuViewport 
        className="custom-viewport"
        style={{
          // CSS custom properties are automatically set:
          // --radix-navigation-menu-viewport-width
          // --radix-navigation-menu-viewport-height
          width: "var(--radix-navigation-menu-viewport-width)",
          height: "var(--radix-navigation-menu-viewport-height)",
          transition: "width 200ms, height 200ms",
        }}
      />
    </NavigationMenu>
  );
}

// Viewport with animation control
function AnimatedViewportExample() {
  return (
    <NavigationMenu>
      <NavigationMenuList>
        <NavigationMenuItem>
          <NavigationMenuTrigger>Animated Content</NavigationMenuTrigger>
          <NavigationMenuContent forceMount>
            Animated content here
          </NavigationMenuContent>
        </NavigationMenuItem>
      </NavigationMenuList>
      
      <NavigationMenuViewport 
        forceMount
        onPointerEnter={() => console.log("Viewport entered")}
        onPointerLeave={() => console.log("Viewport left")}
      />
    </NavigationMenu>
  );
}
```

## Content vs Viewport Mode

The navigation menu can operate in two content display modes:

### Direct Content Mode (Default)

Content is rendered directly adjacent to triggers:

```typescript
<NavigationMenuItem>
  <NavigationMenuTrigger>Trigger</NavigationMenuTrigger>
  <NavigationMenuContent>
    {/* Rendered directly in DOM tree */}
  </NavigationMenuContent>
</NavigationMenuItem>
```

### Viewport Mode

Content is rendered centrally in a viewport:

```typescript
<NavigationMenu>
  <NavigationMenuList>
    <NavigationMenuItem>
      <NavigationMenuTrigger>Trigger</NavigationMenuTrigger>
      <NavigationMenuContent>
        {/* Rendered via portal into viewport */}
      </NavigationMenuContent>
    </NavigationMenuItem>
  </NavigationMenuList>
  
  <NavigationMenuViewport />
</NavigationMenu>
```

**Benefits of Viewport Mode:**
- Consistent content positioning
- Smooth size transitions between different content
- Better animation control
- Simplified layout management

## Event Handling

### Content Events

```typescript
// Pointer events for hover behavior
onPointerEnter?: (event: React.PointerEvent) => void;
onPointerLeave?: (event: React.PointerEvent) => void;

// Focus events for accessibility
onFocusOutside?: (event: Event) => void;
onPointerDownOutside?: (event: Event) => void;

// Keyboard events
onKeyDown?: (event: React.KeyboardEvent) => void;
onEscapeKeyDown?: (event: KeyboardEvent) => void;
```

### Viewport Events

```typescript
// Pointer events
onPointerEnter?: (event: React.PointerEvent) => void;
onPointerLeave?: (event: React.PointerEvent) => void;
```

## CSS Custom Properties

When using viewport mode, these CSS custom properties are automatically available:

```css
.nav-viewport {
  width: var(--radix-navigation-menu-viewport-width);
  height: var(--radix-navigation-menu-viewport-height);
  transition: width 200ms, height 200ms;
}
```

## Data Attributes

Content components expose data attributes for styling and animation:

### NavigationMenuContent Data Attributes

```css
[data-state="open"] { /* Content is visible */ }
[data-state="closed"] { /* Content is hidden */ }
[data-motion="from-start"] { /* Animating in from start */ }
[data-motion="from-end"] { /* Animating in from end */ }
[data-motion="to-start"] { /* Animating out to start */ }
[data-motion="to-end"] { /* Animating out to end */ }
[data-orientation="horizontal"|"vertical"] { /* Content orientation */ }
```

**Animation Examples:**

```css
.nav-content[data-state="open"] {
  animation: slideIn 200ms ease-out;
}

.nav-content[data-state="closed"] {
  animation: slideOut 200ms ease-in;
}

.nav-content[data-motion="from-start"] {
  animation: slideFromStart 200ms ease-out;
}

.nav-content[data-motion="from-end"] {
  animation: slideFromEnd 200ms ease-out;
}

@keyframes slideIn {
  from { opacity: 0; transform: translateY(-10px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes slideFromStart {
  from { transform: translateX(-20px); opacity: 0; }
  to { transform: translateX(0); opacity: 1; }
}
```

### NavigationMenuViewport Data Attributes

```css
[data-state="open"] { /* Viewport contains content */ }
[data-state="closed"] { /* Viewport is empty */ }
[data-orientation="horizontal"|"vertical"] { /* Viewport orientation */ }
```

**Viewport Styling:**

```css
.nav-viewport[data-state="open"] {
  pointer-events: auto;
  opacity: 1;
}

.nav-viewport[data-state="closed"] {
  pointer-events: none;
  opacity: 0;
}

.nav-viewport[data-orientation="horizontal"] {
  /* Styles for horizontal viewport */
}

.nav-viewport[data-orientation="vertical"] {
  /* Styles for vertical viewport */
}
```