Skip to component content

A right-click menu built on Bootstrap's documented dropdown-menu surface, with Moo UI owning only the pointer/keyboard invocation Bootstrap does not provide.

Usage

Use .context-menu for secondary actions that belong to a specific surface, file, row, or card. Attach the trigger area to the object that owns the actions, render the popup as a flat Bootstrap .dropdown-menu, and keep item labels action-oriented so the menu can be scanned quickly.

Support pointer and keyboard access together: right-click should open the menu for mouse users, Shift+F10 should open it for keyboard users, and a visible fallback trigger should remain available for touch and assistive technology users. Do not make context menu access the only path to required work.

Use .dropdown-item rows, headers, and dividers for the menu content, and keep destructive actions after a separator. Because Bootstrap dropdowns support generic menu content, add any more specific ARIA semantics only when the menu is truly acting like an application menu.

Basic

Right-click the card, or focus it and press Shift+F10 (or the ContextMenu key). The corner button is the explicit fallback trigger for touch and keyboard-only use.

Context Menu
<div class="context-menu" id="context-menu-basic">
  <div class="context-menu-trigger" id="context-menu-basic-surface" role="button" tabindex="0" aria-haspopup="menu" aria-expanded="false" aria-controls="context-menu-basic-menu">
    <div class="card">
      <div class="card-header">
        <div class="card-header__text">
          <h3 class="card-title">Quarterly report.pdf</h3>
          <p class="card-subtitle">Right-click, or tab here and press Shift+F10</p>
        </div>
      </div>
      <div class="card-body">
        <p class="text-body-secondary mb-0">The corner button opens the same menu for touch and keyboard-only use.</p>
      </div>
    </div>
  </div>
  <button type="button" class="context-menu-trigger btn btn-ghost btn-icon-sm" id="context-menu-basic-fallback" data-bs-toggle="dropdown" data-context-menu-fallback aria-expanded="false" aria-controls="context-menu-basic-menu" aria-label="Open File actions menu">
    <i class="lucide lucide-ellipsis-vertical" data-icon="inline-start" aria-hidden="true"></i>
  </button>
  <ul class="dropdown-menu context-menu-menu" id="context-menu-basic-menu" tabindex="-1" aria-label="File actions">
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-pencil" data-icon="inline-start" aria-hidden="true"></i>
        <span>Rename</span>
        <span class="ms-auto small text-body-secondary">⌘R</span>
      </button>
    </li>
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-copy" data-icon="inline-start" aria-hidden="true"></i>
        <span>Duplicate</span>
      </button>
    </li>
    <li>
      <hr class="dropdown-divider">
    </li>
    <li>
      <button class="dropdown-item" type="button" data-variant="destructive">
        <i class="lucide lucide-trash-2" data-icon="inline-start" aria-hidden="true"></i>
        <span>Delete</span>
      </button>
    </li>
  </ul>
</div>

Shortcuts

Add compact shortcut text to the end of an item while preserving the Bootstrap dropdown-item structure.

Context Menu
<div class="context-menu" id="context-menu-shortcuts">
  <div class="context-menu-trigger" id="context-menu-shortcuts-surface" role="button" tabindex="0" aria-haspopup="menu" aria-expanded="false" aria-controls="context-menu-shortcuts-menu">
    <div class="card">
      <div class="card-header">
        <div class="card-header__text">
          <h3 class="card-title">Release notes.md</h3>
          <p class="card-subtitle">Right-click to reveal shortcut hints</p>
        </div>
      </div>
      <div class="card-body">
        <p class="text-body-secondary mb-0">Shortcut text uses the same trailing slot as Dropdown Menu items.</p>
      </div>
    </div>
  </div>
  <button type="button" class="context-menu-trigger btn btn-ghost btn-icon-sm" id="context-menu-shortcuts-fallback" data-bs-toggle="dropdown" data-context-menu-fallback aria-expanded="false" aria-controls="context-menu-shortcuts-menu" aria-label="Open Shortcut actions menu">
    <i class="lucide lucide-ellipsis-vertical" data-icon="inline-start" aria-hidden="true"></i>
  </button>
  <ul class="dropdown-menu context-menu-menu" id="context-menu-shortcuts-menu" tabindex="-1" aria-label="Shortcut actions">
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-file-plus" data-icon="inline-start" aria-hidden="true"></i>
        <span>New file</span>
        <span class="ms-auto small text-body-secondary">⌘N</span>
      </button>
    </li>
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-pencil" data-icon="inline-start" aria-hidden="true"></i>
        <span>Rename</span>
        <span class="ms-auto small text-body-secondary">⌘R</span>
      </button>
    </li>
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-copy" data-icon="inline-start" aria-hidden="true"></i>
        <span>Duplicate</span>
        <span class="ms-auto small text-body-secondary">⌘D</span>
      </button>
    </li>
    <li>
      <hr class="dropdown-divider">
    </li>
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-archive" data-icon="inline-start" aria-hidden="true"></i>
        <span>Archive</span>
        <span class="ms-auto small text-body-secondary">⇧⌘A</span>
      </button>
    </li>
  </ul>
</div>

Groups

Group related actions with Bootstrap dropdown headers and dividers inside the same flat menu.

Context Menu
<div class="context-menu" id="context-menu-groups">
  <div class="context-menu-trigger" id="context-menu-groups-surface" role="button" tabindex="0" aria-haspopup="menu" aria-expanded="false" aria-controls="context-menu-groups-menu">
    <div class="card">
      <div class="card-header">
        <div class="card-header__text">
          <h3 class="card-title">Brand guidelines.fig</h3>
          <p class="card-subtitle">Grouped actions use Bootstrap headers and dividers</p>
        </div>
      </div>
      <div class="card-body">
        <p class="text-body-secondary mb-0">Headers are semantic dropdown headers, not custom nested panels.</p>
      </div>
    </div>
  </div>
  <button type="button" class="context-menu-trigger btn btn-ghost btn-icon-sm" id="context-menu-groups-fallback" data-bs-toggle="dropdown" data-context-menu-fallback aria-expanded="false" aria-controls="context-menu-groups-menu" aria-label="Open Grouped file actions menu">
    <i class="lucide lucide-ellipsis-vertical" data-icon="inline-start" aria-hidden="true"></i>
  </button>
  <ul class="dropdown-menu context-menu-menu" id="context-menu-groups-menu" tabindex="-1" aria-label="Grouped file actions">
    <li>
      <h6 class="dropdown-header">File</h6>
    </li>
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-external-link" data-icon="inline-start" aria-hidden="true"></i>
        <span>Open in editor</span>
      </button>
    </li>
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-folder-open" data-icon="inline-start" aria-hidden="true"></i>
        <span>Reveal in project</span>
      </button>
    </li>
    <li>
      <hr class="dropdown-divider">
    </li>
    <li>
      <h6 class="dropdown-header">Share</h6>
    </li>
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-link" data-icon="inline-start" aria-hidden="true"></i>
        <span>Copy public link</span>
      </button>
    </li>
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-send" data-icon="inline-start" aria-hidden="true"></i>
        <span>Send for review</span>
      </button>
    </li>
    <li>
      <hr class="dropdown-divider">
    </li>
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-archive" data-icon="inline-start" aria-hidden="true"></i>
        <span>Move to archive</span>
      </button>
    </li>
  </ul>
</div>

Icons

Use the Dropdown Menu icon slot when actions need quick visual recognition.

Context Menu
<div class="context-menu" id="context-menu-icons">
  <div class="context-menu-trigger" id="context-menu-icons-surface" role="button" tabindex="0" aria-haspopup="menu" aria-expanded="false" aria-controls="context-menu-icons-menu">
    <div class="card">
      <div class="card-header">
        <div class="card-header__text">
          <h3 class="card-title">Media pack.zip</h3>
          <p class="card-subtitle">Icon affordances align with Dropdown Menu</p>
        </div>
      </div>
      <div class="card-body">
        <p class="text-body-secondary mb-0">Icon boxes keep dense menus scannable without changing the item contract.</p>
      </div>
    </div>
  </div>
  <button type="button" class="context-menu-trigger btn btn-ghost btn-icon-sm" id="context-menu-icons-fallback" data-bs-toggle="dropdown" data-context-menu-fallback aria-expanded="false" aria-controls="context-menu-icons-menu" aria-label="Open Icon actions menu">
    <i class="lucide lucide-ellipsis-vertical" data-icon="inline-start" aria-hidden="true"></i>
  </button>
  <ul class="dropdown-menu context-menu-menu" id="context-menu-icons-menu" tabindex="-1" aria-label="Icon actions">
    <li>
      <button class="dropdown-item" type="button">
        <span class="dropdown-item__icon-box">
          <i class="lucide lucide-link" data-icon="inline-start" aria-hidden="true"></i>
        </span>
        <span>Copy link</span>
      </button>
    </li>
    <li>
      <button class="dropdown-item" type="button">
        <span class="dropdown-item__icon-box">
          <i class="lucide lucide-download" data-icon="inline-start" aria-hidden="true"></i>
        </span>
        <span>Download</span>
      </button>
    </li>
    <li>
      <button class="dropdown-item" type="button">
        <span class="dropdown-item__icon-box">
          <i class="lucide lucide-star" data-icon="inline-start" aria-hidden="true"></i>
        </span>
        <span>Star file</span>
      </button>
    </li>
    <li>
      <hr class="dropdown-divider">
    </li>
    <li>
      <button class="dropdown-item" type="button">
        <span class="dropdown-item__icon-box">
          <i class="lucide lucide-info" data-icon="inline-start" aria-hidden="true"></i>
        </span>
        <span>View details</span>
      </button>
    </li>
  </ul>
</div>

Disabled item

A disabled item stays visible for context but cannot receive roving focus or be activated.

Context Menu
<div class="context-menu" id="context-menu-disabled">
  <div class="context-menu-trigger" id="context-menu-disabled-surface" role="button" tabindex="0" aria-haspopup="menu" aria-expanded="false" aria-controls="context-menu-disabled-menu">
    <div class="card">
      <div class="card-header">
        <div class="card-header__text">
          <h3 class="card-title">Draft proposal.docx</h3>
          <p class="card-subtitle">Restore version is disabled: no earlier version exists</p>
        </div>
      </div>
      <div class="card-body">
        <p class="text-body-secondary mb-0">Disabled items are skipped by keyboard roving focus and cannot be activated.</p>
      </div>
    </div>
  </div>
  <button type="button" class="context-menu-trigger btn btn-ghost btn-icon-sm" id="context-menu-disabled-fallback" data-bs-toggle="dropdown" data-context-menu-fallback aria-expanded="false" aria-controls="context-menu-disabled-menu" aria-label="Open Document actions menu">
    <i class="lucide lucide-ellipsis-vertical" data-icon="inline-start" aria-hidden="true"></i>
  </button>
  <ul class="dropdown-menu context-menu-menu" id="context-menu-disabled-menu" tabindex="-1" aria-label="Document actions">
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-share-2" data-icon="inline-start" aria-hidden="true"></i>
        <span>Share</span>
      </button>
    </li>
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-folder-input" data-icon="inline-start" aria-hidden="true"></i>
        <span>Move to…</span>
      </button>
    </li>
    <li>
      <hr class="dropdown-divider">
    </li>
    <li>
      <button class="dropdown-item" type="button" disabled>
        <i class="lucide lucide-history" data-icon="inline-start" aria-hidden="true"></i>
        <span>Restore version</span>
      </button>
    </li>
  </ul>
</div>

Checkboxes

Toggleable options use Bootstrap's button toggle Data API, so selecting one keeps the menu open instead of closing it.

Context Menu
<div class="context-menu" id="context-menu-checkboxes">
  <div class="context-menu-trigger" id="context-menu-checkboxes-surface" role="button" tabindex="0" aria-haspopup="menu" aria-expanded="false" aria-controls="context-menu-checkboxes-menu">
    <div class="card">
      <div class="card-header">
        <div class="card-header__text">
          <h3 class="card-title">Design assets</h3>
          <p class="card-subtitle">Folder · 128 items</p>
        </div>
      </div>
      <div class="card-body">
        <p class="text-body-secondary mb-0">Toggle items keep the menu open, using Bootstrap's own button-toggle Data API.</p>
      </div>
    </div>
  </div>
  <button type="button" class="context-menu-trigger btn btn-ghost btn-icon-sm" id="context-menu-checkboxes-fallback" data-bs-toggle="dropdown" data-context-menu-fallback aria-expanded="false" aria-controls="context-menu-checkboxes-menu" aria-label="Open Folder view options menu">
    <i class="lucide lucide-ellipsis-vertical" data-icon="inline-start" aria-hidden="true"></i>
  </button>
  <ul class="dropdown-menu context-menu-menu" id="context-menu-checkboxes-menu" tabindex="-1" aria-label="Folder view options">
    <li>
      <h6 class="dropdown-header">View</h6>
    </li>
    <li>
      <button class="dropdown-item dropdown-item-check active" type="button" data-bs-toggle="button" aria-pressed="true">
        <span class="dropdown-item-check__indicator" aria-hidden="true">
          <i class="lucide lucide-check" data-icon="inline-start" aria-hidden="true"></i>
        </span>
        <span>Show hidden files</span>
      </button>
    </li>
    <li>
      <button class="dropdown-item dropdown-item-check" type="button" data-bs-toggle="button" aria-pressed="false">
        <span class="dropdown-item-check__indicator" aria-hidden="true">
          <i class="lucide lucide-check" data-icon="inline-start" aria-hidden="true"></i>
        </span>
        <span>Show file extensions</span>
      </button>
    </li>
    <li>
      <hr class="dropdown-divider">
    </li>
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-refresh-cw" data-icon="inline-start" aria-hidden="true"></i>
        <span>Refresh</span>
      </button>
    </li>
  </ul>
</div>

Radio

Single-select options reuse the checkbox item's dropdown-item button so keyboard roving focus and Bootstrap's button-toggle Data API keep working; Moo UI adds only the mutual-exclusivity between grouped options.

Context Menu
<div class="context-menu" id="context-menu-radio">
  <div class="context-menu-trigger" id="context-menu-radio-surface" role="button" tabindex="0" aria-haspopup="menu" aria-expanded="false" aria-controls="context-menu-radio-menu">
    <div class="card">
      <div class="card-header">
        <div class="card-header__text">
          <h3 class="card-title">Screenshots</h3>
          <p class="card-subtitle">Folder · 42 items</p>
        </div>
      </div>
      <div class="card-body">
        <p class="text-body-secondary mb-0">Single-select options stay real dropdown-item buttons, so arrow-key roving focus reaches every option.</p>
      </div>
    </div>
  </div>
  <button type="button" class="context-menu-trigger btn btn-ghost btn-icon-sm" id="context-menu-radio-fallback" data-bs-toggle="dropdown" data-context-menu-fallback aria-expanded="false" aria-controls="context-menu-radio-menu" aria-label="Open Sort options menu">
    <i class="lucide lucide-ellipsis-vertical" data-icon="inline-start" aria-hidden="true"></i>
  </button>
  <ul class="dropdown-menu context-menu-menu" id="context-menu-radio-menu" tabindex="-1" aria-label="Sort options">
    <li>
      <h6 class="dropdown-header">Sort by</h6>
    </li>
    <li>
      <button class="dropdown-item dropdown-item-check active" type="button" data-bs-toggle="button" aria-pressed="true" data-context-menu-radio-group="sort">
        <span class="dropdown-item-check__indicator" aria-hidden="true">
          <i class="lucide lucide-check" data-icon="inline-start" aria-hidden="true"></i>
        </span>
        <span>Name</span>
      </button>
    </li>
    <li>
      <button class="dropdown-item dropdown-item-check" type="button" data-bs-toggle="button" aria-pressed="false" data-context-menu-radio-group="sort">
        <span class="dropdown-item-check__indicator" aria-hidden="true">
          <i class="lucide lucide-check" data-icon="inline-start" aria-hidden="true"></i>
        </span>
        <span>Date modified</span>
      </button>
    </li>
    <li>
      <button class="dropdown-item dropdown-item-check" type="button" data-bs-toggle="button" aria-pressed="false" data-context-menu-radio-group="sort">
        <span class="dropdown-item-check__indicator" aria-hidden="true">
          <i class="lucide lucide-check" data-icon="inline-start" aria-hidden="true"></i>
        </span>
        <span>Size</span>
      </button>
    </li>
    <li>
      <hr class="dropdown-divider">
    </li>
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-refresh-cw" data-icon="inline-start" aria-hidden="true"></i>
        <span>Refresh</span>
      </button>
    </li>
  </ul>
</div>

Destructive

Mark destructive actions with the shared danger text utility while keeping the menu item anatomy unchanged.

Context Menu
<div class="context-menu" id="context-menu-destructive">
  <div class="context-menu-trigger" id="context-menu-destructive-surface" role="button" tabindex="0" aria-haspopup="menu" aria-expanded="false" aria-controls="context-menu-destructive-menu">
    <div class="card">
      <div class="card-header">
        <div class="card-header__text">
          <h3 class="card-title">Old backup.sql</h3>
          <p class="card-subtitle">Destructive actions stay visually distinct</p>
        </div>
      </div>
      <div class="card-body">
        <p class="text-body-secondary mb-0">The danger item still uses a normal dropdown-item so focus, hover, and click behavior remain consistent.</p>
      </div>
    </div>
  </div>
  <button type="button" class="context-menu-trigger btn btn-ghost btn-icon-sm" id="context-menu-destructive-fallback" data-bs-toggle="dropdown" data-context-menu-fallback aria-expanded="false" aria-controls="context-menu-destructive-menu" aria-label="Open Dangerous file actions menu">
    <i class="lucide lucide-ellipsis-vertical" data-icon="inline-start" aria-hidden="true"></i>
  </button>
  <ul class="dropdown-menu context-menu-menu" id="context-menu-destructive-menu" tabindex="-1" aria-label="Dangerous file actions">
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-pencil" data-icon="inline-start" aria-hidden="true"></i>
        <span>Rename</span>
      </button>
    </li>
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-copy" data-icon="inline-start" aria-hidden="true"></i>
        <span>Duplicate</span>
      </button>
    </li>
    <li>
      <hr class="dropdown-divider">
    </li>
    <li>
      <button class="dropdown-item" type="button" data-variant="destructive">
        <i class="lucide lucide-trash-2" data-icon="inline-start" aria-hidden="true"></i>
        <span>Delete forever</span>
        <span class="ms-auto small text-body-secondary">⌘⌫</span>
      </button>
    </li>
  </ul>
</div>

Sides

Use Bootstrap's end alignment for the fallback trigger while pointer invocation continues to position from the right-click location.

Context Menu
<div class="context-menu" id="context-menu-sides">
  <div class="context-menu-trigger" id="context-menu-sides-surface" role="button" tabindex="0" aria-haspopup="menu" aria-expanded="false" aria-controls="context-menu-sides-menu">
    <div class="card">
      <div class="card-header">
        <div class="card-header__text">
          <h3 class="card-title">logs/production.log</h3>
          <p class="card-subtitle">Fallback trigger aligns the menu to the end edge</p>
        </div>
      </div>
      <div class="card-body">
        <p class="text-body-secondary mb-0">Pointer-open menus anchor to the click point; the explicit fallback trigger can use Bootstrap's end alignment.</p>
      </div>
    </div>
  </div>
  <button type="button" class="context-menu-trigger btn btn-ghost btn-icon-sm" id="context-menu-sides-fallback" data-bs-toggle="dropdown" data-context-menu-fallback aria-expanded="false" aria-controls="context-menu-sides-menu" aria-label="Open End-aligned fallback actions menu">
    <i class="lucide lucide-ellipsis-vertical" data-icon="inline-start" aria-hidden="true"></i>
  </button>
  <ul class="dropdown-menu context-menu-menu dropdown-menu-end" id="context-menu-sides-menu" tabindex="-1" aria-label="End-aligned fallback actions">
    <li>
      <button class="dropdown-item" type="button">
        <span>Open</span>
      </button>
    </li>
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-copy" data-icon="inline-start" aria-hidden="true"></i>
        <span>Copy path</span>
      </button>
    </li>
    <li>
      <hr class="dropdown-divider">
    </li>
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-search" data-icon="inline-start" aria-hidden="true"></i>
        <span>Inspect</span>
      </button>
    </li>
  </ul>
</div>

RTL

Switch between Arabic, Hebrew, and English to validate pointer/keyboard placement and item alignment in RTL mode.

<div class="context-menu" id="context-menu-rtl-arabic">
  <div class="context-menu-trigger" id="context-menu-rtl-arabic-surface" role="button" tabindex="0" aria-haspopup="menu" aria-expanded="false" aria-controls="context-menu-rtl-arabic-menu">
    <div class="card">
      <div class="card-header">
        <div class="card-header__text">
          <h3 class="card-title">تقرير ربع سنوي.pdf</h3>
          <p class="card-subtitle">انقر بزر الماوس الأيمن أو اضغط على Shift+F10</p>
        </div>
      </div>
      <div class="card-body">
        <p class="text-body-secondary mb-0">زر الزاوية يفتح نفس القائمة للمس ولوحة المفاتيح.</p>
      </div>
    </div>
  </div>
  <button type="button" class="context-menu-trigger btn btn-ghost btn-icon-sm" id="context-menu-rtl-arabic-fallback" data-bs-toggle="dropdown" data-context-menu-fallback aria-expanded="false" aria-controls="context-menu-rtl-arabic-menu" aria-label="Open إجراءات الملف menu">
    <i class="lucide lucide-ellipsis-vertical" data-icon="inline-start" aria-hidden="true"></i>
  </button>
  <ul class="dropdown-menu context-menu-menu" id="context-menu-rtl-arabic-menu" tabindex="-1" aria-label="إجراءات الملف">
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-pencil" data-icon="inline-start" aria-hidden="true"></i>
        <span>إعادة تسمية</span>
      </button>
    </li>
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-copy" data-icon="inline-start" aria-hidden="true"></i>
        <span>تكرار</span>
      </button>
    </li>
    <li>
      <hr class="dropdown-divider">
    </li>
    <li>
      <button class="dropdown-item" type="button" data-variant="destructive">
        <i class="lucide lucide-trash-2" data-icon="inline-start" aria-hidden="true"></i>
        <span>حذف</span>
      </button>
    </li>
  </ul>
</div>
<div class="context-menu" id="context-menu-rtl-hebrew">
  <div class="context-menu-trigger" id="context-menu-rtl-hebrew-surface" role="button" tabindex="0" aria-haspopup="menu" aria-expanded="false" aria-controls="context-menu-rtl-hebrew-menu">
    <div class="card">
      <div class="card-header">
        <div class="card-header__text">
          <h3 class="card-title">דוח רבעוני.pdf</h3>
          <p class="card-subtitle">לחץ לחיצה ימנית או הקש Shift+F10</p>
        </div>
      </div>
      <div class="card-body">
        <p class="text-body-secondary mb-0">כפתור הפינה פותח את אותה תפריט למגע ולמקלדת.</p>
      </div>
    </div>
  </div>
  <button type="button" class="context-menu-trigger btn btn-ghost btn-icon-sm" id="context-menu-rtl-hebrew-fallback" data-bs-toggle="dropdown" data-context-menu-fallback aria-expanded="false" aria-controls="context-menu-rtl-hebrew-menu" aria-label="Open פעולות קובץ menu">
    <i class="lucide lucide-ellipsis-vertical" data-icon="inline-start" aria-hidden="true"></i>
  </button>
  <ul class="dropdown-menu context-menu-menu" id="context-menu-rtl-hebrew-menu" tabindex="-1" aria-label="פעולות קובץ">
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-pencil" data-icon="inline-start" aria-hidden="true"></i>
        <span>שנה שם</span>
      </button>
    </li>
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-copy" data-icon="inline-start" aria-hidden="true"></i>
        <span>שכפל</span>
      </button>
    </li>
    <li>
      <hr class="dropdown-divider">
    </li>
    <li>
      <button class="dropdown-item" type="button" data-variant="destructive">
        <i class="lucide lucide-trash-2" data-icon="inline-start" aria-hidden="true"></i>
        <span>מחק</span>
      </button>
    </li>
  </ul>
</div>
<div class="context-menu" id="context-menu-rtl-english">
  <div class="context-menu-trigger" id="context-menu-rtl-english-surface" role="button" tabindex="0" aria-haspopup="menu" aria-expanded="false" aria-controls="context-menu-rtl-english-menu">
    <div class="card">
      <div class="card-header">
        <div class="card-header__text">
          <h3 class="card-title">Quarterly report.pdf</h3>
          <p class="card-subtitle">Right-click or press Shift+F10</p>
        </div>
      </div>
      <div class="card-body">
        <p class="text-body-secondary mb-0">The corner button opens the same menu for touch and keyboard.</p>
      </div>
    </div>
  </div>
  <button type="button" class="context-menu-trigger btn btn-ghost btn-icon-sm" id="context-menu-rtl-english-fallback" data-bs-toggle="dropdown" data-context-menu-fallback aria-expanded="false" aria-controls="context-menu-rtl-english-menu" aria-label="Open File actions menu">
    <i class="lucide lucide-ellipsis-vertical" data-icon="inline-start" aria-hidden="true"></i>
  </button>
  <ul class="dropdown-menu context-menu-menu" id="context-menu-rtl-english-menu" tabindex="-1" aria-label="File actions">
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-pencil" data-icon="inline-start" aria-hidden="true"></i>
        <span>Rename</span>
      </button>
    </li>
    <li>
      <button class="dropdown-item" type="button">
        <i class="lucide lucide-copy" data-icon="inline-start" aria-hidden="true"></i>
        <span>Duplicate</span>
      </button>
    </li>
    <li>
      <hr class="dropdown-divider">
    </li>
    <li>
      <button class="dropdown-item" type="button" data-variant="destructive">
        <i class="lucide lucide-trash-2" data-icon="inline-start" aria-hidden="true"></i>
        <span>Delete</span>
      </button>
    </li>
  </ul>
</div>

Component reference

Status
Accepted
Runtime
optional Moo UI ESM
Markup
Moo UI documented extension
Reference

Context Menu inherits Bootstrap's dropdown-menu surface, item states, and Popper positioning. Nested submenus are not supported because Bootstrap does not provide a native nested-menu contract; for the underlying options and keyboard behavior see the Bootstrap Dropdowns documentation.

Settings

Theme
Choose how Moo UI looks on this device.
Sidebar
Choose how the sidebar sits on the page.
Theme Builder
Tune catalog tokens and chart colors for this browser.
Base color
Theme color
Chart color
Heading font
Body font
Radius
Direction
Choose the reading direction. RTL flips the layout live.
Reset

Restore the default appearance.