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

submenus.mddocs/

Submenus

Components for creating nested dropdown menus with submenu triggers and content areas. These components enable complex menu hierarchies with multiple levels of navigation.

Capabilities

DropdownMenuSub (Sub)

Container component that manages the state and behavior of a submenu.

/**
 * Container for submenu functionality
 * @param children - Child components (typically SubTrigger and SubContent)
 * @param open - Controlled open state of the submenu
 * @param defaultOpen - Default open state (uncontrolled)
 * @param onOpenChange - Callback when submenu open state changes
 */
interface DropdownMenuSubProps {
  children?: React.ReactNode;
  open?: boolean;
  defaultOpen?: boolean;
  onOpenChange?(open: boolean): void;
}

const DropdownMenuSub: React.FC<DropdownMenuSubProps>;

Usage Examples:

// Uncontrolled submenu
<DropdownMenu.Sub>
  <DropdownMenu.SubTrigger>More Options</DropdownMenu.SubTrigger>
  <DropdownMenu.SubContent>
    <DropdownMenu.Item>Nested Option 1</DropdownMenu.Item>
    <DropdownMenu.Item>Nested Option 2</DropdownMenu.Item>
  </DropdownMenu.SubContent>
</DropdownMenu.Sub>

// Controlled submenu
const [subOpen, setSubOpen] = React.useState(false);
<DropdownMenu.Sub open={subOpen} onOpenChange={setSubOpen}>
  <DropdownMenu.SubTrigger>Controlled Submenu</DropdownMenu.SubTrigger>
  <DropdownMenu.SubContent>
    <DropdownMenu.Item>Nested Item</DropdownMenu.Item>
  </DropdownMenu.SubContent>
</DropdownMenu.Sub>

DropdownMenuSubTrigger (SubTrigger)

Trigger component that opens a submenu when hovered or activated with keyboard.

/**
 * Trigger for opening submenu
 * @param disabled - Whether the trigger is disabled
 * @param textValue - Text value for typeahead functionality
 * @param asChild - Compose with child element
 */
interface DropdownMenuSubTriggerProps {
  disabled?: boolean;
  textValue?: string;
  asChild?: boolean;
  children?: React.ReactNode;
}

const DropdownMenuSubTrigger: React.ForwardRefExoticComponent<DropdownMenuSubTriggerProps>;

Usage Examples:

// Basic submenu trigger
<DropdownMenu.SubTrigger>
  Share
  <ChevronRightIcon />
</DropdownMenu.SubTrigger>

// Disabled submenu trigger
<DropdownMenu.SubTrigger disabled>
  Unavailable Options
</DropdownMenu.SubTrigger>

// Custom submenu trigger using asChild
<DropdownMenu.SubTrigger asChild>
  <button className="custom-submenu-trigger">
    <ShareIcon />
    Share Options
    <ArrowIcon />
  </button>
</DropdownMenu.SubTrigger>

DropdownMenuSubContent (SubContent)

Content container for submenu items that appears when the submenu is triggered.

/**
 * Content container for submenu items
 * Similar to DropdownMenuContent but for nested menus
 * @param loop - Whether focus should loop when navigating
 * @param onEscapeKeyDown - Callback when Escape key is pressed
 * @param onKeyDown - Callback for key events
 * @param forceMount - Force mounting regardless of open state
 * @param container - Container element for portaling
 */
interface DropdownMenuSubContentProps {
  loop?: boolean;
  onEscapeKeyDown?: (event: KeyboardEvent) => void;
  onKeyDown?: (event: KeyboardEvent) => void;
  forceMount?: boolean;
  container?: HTMLElement;
  children?: React.ReactNode;
}

const DropdownMenuSubContent: React.ForwardRefExoticComponent<DropdownMenuSubContentProps>;

Usage Examples:

// Basic submenu content
<DropdownMenu.SubContent>
  <DropdownMenu.Item>Copy Link</DropdownMenu.Item>
  <DropdownMenu.Item>Email</DropdownMenu.Item>
  <DropdownMenu.Item>Print</DropdownMenu.Item>
</DropdownMenu.SubContent>

// Submenu content with custom behavior
<DropdownMenu.SubContent 
  loop={false}
  onEscapeKeyDown={(e) => console.log('Escaping submenu')}
>
  <DropdownMenu.Item>Option A</DropdownMenu.Item>
  <DropdownMenu.Item>Option B</DropdownMenu.Item>
</DropdownMenu.SubContent>

Complete Submenu Example

function MultiLevelDropdownMenu() {
  return (
    <DropdownMenu.Root>
      <DropdownMenu.Trigger>File</DropdownMenu.Trigger>
      
      <DropdownMenu.Portal>
        <DropdownMenu.Content>
          <DropdownMenu.Item>New File</DropdownMenu.Item>
          <DropdownMenu.Item>Open</DropdownMenu.Item>
          
          <DropdownMenu.Separator />
          
          {/* First level submenu */}
          <DropdownMenu.Sub>
            <DropdownMenu.SubTrigger>
              Recent Files
              <ChevronRightIcon />
            </DropdownMenu.SubTrigger>
            <DropdownMenu.SubContent>
              <DropdownMenu.Item>document1.txt</DropdownMenu.Item>
              <DropdownMenu.Item>document2.txt</DropdownMenu.Item>
              
              {/* Second level submenu */}
              <DropdownMenu.Sub>
                <DropdownMenu.SubTrigger>
                  More Recent
                  <ChevronRightIcon />
                </DropdownMenu.SubTrigger>
                <DropdownMenu.SubContent>
                  <DropdownMenu.Item>old-file1.txt</DropdownMenu.Item>
                  <DropdownMenu.Item>old-file2.txt</DropdownMenu.Item>
                </DropdownMenu.SubContent>
              </DropdownMenu.Sub>
            </DropdownMenu.SubContent>
          </DropdownMenu.Sub>
          
          <DropdownMenu.Sub>
            <DropdownMenu.SubTrigger>
              Export
              <ChevronRightIcon />
            </DropdownMenu.SubTrigger>
            <DropdownMenu.SubContent>
              <DropdownMenu.Item>Export as PDF</DropdownMenu.Item>
              <DropdownMenu.Item>Export as HTML</DropdownMenu.Item>
              <DropdownMenu.Item>Export as Markdown</DropdownMenu.Item>
            </DropdownMenu.SubContent>
          </DropdownMenu.Sub>
          
          <DropdownMenu.Separator />
          
          <DropdownMenu.Item>Close</DropdownMenu.Item>
        </DropdownMenu.Content>
      </DropdownMenu.Portal>
    </DropdownMenu.Root>
  );
}

Keyboard Navigation

Submenus support full keyboard navigation:

  • Arrow Keys: Navigate between items and into/out of submenus
  • Enter/Space: Activate items or open submenus
  • Escape: Close current submenu level
  • Home/End: Jump to first/last item in current level
  • Letter keys: Type-ahead search within current level

Accessibility Features

  • Proper ARIA attributes for nested menu structure
  • Screen reader announcements for submenu state changes
  • Focus management across menu levels
  • Keyboard navigation between parent and child menus
  • Automatic focus return when closing submenus

Component Aliases

// Short aliases for composition patterns
const Sub = DropdownMenuSub;
const SubTrigger = DropdownMenuSubTrigger;
const SubContent = DropdownMenuSubContent;

These submenu components enable the creation of complex, multi-level dropdown menus while maintaining full accessibility and keyboard navigation support.

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