CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-radix-ui--react-dropdown-menu

A React dropdown menu component library providing accessible dropdown menu functionality with keyboard navigation and focus management.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

portal-context.mddocs/

Portal and Context

Portal component for rendering menu content and context utilities for advanced customization. These components provide lower-level control over rendering behavior and component scope.

Capabilities

DropdownMenuPortal (Portal)

Portal component that renders dropdown content outside the normal DOM hierarchy for proper layering and positioning.

/**
 * Portal for rendering dropdown content outside normal DOM flow
 * @param forceMount - Force mounting regardless of open state
 * @param container - Container element to portal into (defaults to document.body)
 * @param children - Content to be portaled (typically DropdownMenuContent)
 */
interface DropdownMenuPortalProps {
  forceMount?: boolean;
  container?: HTMLElement;
  children?: React.ReactNode;
}

const DropdownMenuPortal: React.FC<DropdownMenuPortalProps>;

Usage Examples:

// Basic portal usage
<DropdownMenu.Root>
  <DropdownMenu.Trigger>Menu</DropdownMenu.Trigger>
  <DropdownMenu.Portal>
    <DropdownMenu.Content>
      <DropdownMenu.Item>Item 1</DropdownMenu.Item>
    </DropdownMenu.Content>
  </DropdownMenu.Portal>
</DropdownMenu.Root>

// Portal to specific container
const portalContainer = document.getElementById('modal-root');
<DropdownMenu.Portal container={portalContainer}>
  <DropdownMenu.Content>
    <DropdownMenu.Item>Portaled Item</DropdownMenu.Item>
  </DropdownMenu.Content>
</DropdownMenu.Portal>

// Force-mounted portal (always rendered)
<DropdownMenu.Portal forceMount>
  <DropdownMenu.Content>
    <DropdownMenu.Item>Always Present</DropdownMenu.Item>
  </DropdownMenu.Content>
</DropdownMenu.Portal>

// Without portal (content renders in place)
<DropdownMenu.Root>
  <DropdownMenu.Trigger>Menu</DropdownMenu.Trigger>
  <DropdownMenu.Content>
    <DropdownMenu.Item>Inline Item</DropdownMenu.Item>
  </DropdownMenu.Content>
</DropdownMenu.Root>

createDropdownMenuScope

Context scope creation utility for advanced component composition and avoiding context conflicts.

/**
 * Creates a scoped context for dropdown menu components
 * Used for advanced composition patterns and avoiding context conflicts
 * @returns Scoped context creation functions
 */
function createDropdownMenuScope(): any;

Usage Examples:

// Advanced usage with custom scope
const useCustomScope = createDropdownMenuScope();

function CustomDropdownMenu() {
  const customScope = useCustomScope();
  
  return (
    <DropdownMenu.Root {...customScope}>
      <DropdownMenu.Trigger {...customScope}>
        Custom Scoped Menu
      </DropdownMenu.Trigger>
      <DropdownMenu.Portal {...customScope}>
        <DropdownMenu.Content {...customScope}>
          <DropdownMenu.Item {...customScope}>
            Scoped Item
          </DropdownMenu.Item>
        </DropdownMenu.Content>
      </DropdownMenu.Portal>
    </DropdownMenu.Root>
  );
}

Advanced Portal Patterns

Multiple Portals

function MultiPortalExample() {
  return (
    <div>
      {/* First dropdown with default portal */}
      <DropdownMenu.Root>
        <DropdownMenu.Trigger>Menu 1</DropdownMenu.Trigger>
        <DropdownMenu.Portal>
          <DropdownMenu.Content>
            <DropdownMenu.Item>Item 1</DropdownMenu.Item>
          </DropdownMenu.Content>
        </DropdownMenu.Portal>
      </DropdownMenu.Root>
      
      {/* Second dropdown with custom portal container */}
      <DropdownMenu.Root>
        <DropdownMenu.Trigger>Menu 2</DropdownMenu.Trigger>
        <DropdownMenu.Portal container={document.getElementById('custom-layer')}>
          <DropdownMenu.Content>
            <DropdownMenu.Item>Item 2</DropdownMenu.Item>
          </DropdownMenu.Content>
        </DropdownMenu.Portal>
      </DropdownMenu.Root>
    </div>
  );
}

Conditional Portal

function ConditionalPortalExample() {
  const [usePortal, setUsePortal] = React.useState(true);
  
  const content = (
    <DropdownMenu.Content>
      <DropdownMenu.Item>Item</DropdownMenu.Item>
    </DropdownMenu.Content>
  );
  
  return (
    <DropdownMenu.Root>
      <DropdownMenu.Trigger>Menu</DropdownMenu.Trigger>
      {usePortal ? (
        <DropdownMenu.Portal>{content}</DropdownMenu.Portal>
      ) : (
        content
      )}
    </DropdownMenu.Root>
  );
}

Context Scoping Benefits

  • Isolation: Prevents context bleeding between multiple dropdown instances
  • Composition: Enables building custom dropdown variations
  • Testing: Allows isolated testing of dropdown components
  • Performance: Reduces unnecessary re-renders in complex component trees

When to Use Portal

Use Portal when:

  • Content needs to appear above other page elements (z-index issues)
  • Working with modals, overlays, or fixed positioning
  • Need to escape parent container's overflow: hidden
  • Building complex layered interfaces

Skip Portal when:

  • Simple in-page menus without layering concerns
  • Content should scroll with parent container
  • Working within already-portaled contexts
  • Performance optimization for simple cases

Component Aliases

// Short aliases for composition patterns
const Portal = DropdownMenuPortal;

These portal and context utilities provide advanced control over dropdown rendering behavior and enable sophisticated composition patterns while maintaining proper accessibility and functionality.

Install with Tessl CLI

npx tessl i tessl/npm-radix-ui--react-dropdown-menu

docs

core-components.md

index.md

layout-components.md

menu-items.md

portal-context.md

submenus.md

tile.json