Action Menu
A kebab button opening an actions menu with icons and two hover-opening submenus. The submenus sit beside their trigger through the nested flyout's position-order="horizontal", with --sv-flyout-offset: 0 removing the gap so the pointer never crosses a dead zone on its way in. Every leaf action closes the whole tree through the root menu's close().
Code
The following example assumes that you have imported the components and set up the theme.
<div class="action-menu-example">132 collapsed lines
<sv-menu class="action-menu"> <sv-flyout aria-label="More actions menu"> <button type="button" class="trigger" aria-label="More actions" slot="trigger" title="More actions"> <!-- More vertical --> <svg class="trigger-icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg"> <path d="M480-160q-33 0-56.5-23.5T400-240q0-33 23.5-56.5T480-320q33 0 56.5 23.5T560-240q0 33-23.5 56.5T480-160Zm0-240q-33 0-56.5-23.5T400-480q0-33 23.5-56.5T480-560q33 0 56.5 23.5T560-480q0 33-23.5 56.5T480-400Zm0-240q-33 0-56.5-23.5T400-720q0-33 23.5-56.5T480-800q33 0 56.5 23.5T560-720q0 33-23.5 56.5T480-640Z" ></path> </svg> </button>
<button type="button" class="option" role="menuitem"> <!-- Edit --> <svg class="action-icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg"> <path d="M200-200h57l391-391-57-57-391 391v57Zm-80 80v-170l528-527q12-11 26.5-17t30.5-6q16 0 31 6t26 18l55 56q12 11 17.5 26t5.5 30q0 16-5.5 30.5T817-647L290-120H120Zm640-584-56-56 56 56Zm-141 85-28-29 57 57-29-28Z" ></path> </svg> <span>Edit</span> </button>
<button type="button" class="option" role="menuitem"> <!-- Content copy --> <svg class="action-icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg"> <path d="M360-240q-33 0-56.5-23.5T280-320v-480q0-33 23.5-56.5T360-880h360q33 0 56.5 23.5T800-800v480q0 33-23.5 56.5T720-240H360Zm0-80h360v-480H360v480ZM200-80q-33 0-56.5-23.5T120-160v-560h80v560h440v80H200Zm160-240v-480 480Z" ></path> </svg> <span>Copy</span> </button>
<button type="button" class="option" role="menuitem"> <!-- Delete --> <svg class="action-icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg"> <path d="M280-120q-33 0-56.5-23.5T200-200v-520h-40v-80h200v-40h240v40h200v80h-40v520q0 33-23.5 56.5T680-120H280Zm400-600H280v520h400v-520ZM360-280h80v-360h-80v360Zm160 0h80v-360h-80v360ZM280-720v520-520Z" ></path> </svg> <span>Delete</span> </button>
<div class="divider" role="separator"></div>
<sv-menu class="action-submenu" mode="submenu"> <sv-flyout aria-label="Share submenu" open-on-hover position-order="horizontal"> <button type="button" class="option" slot="trigger"> <!-- Share --> <svg class="action-icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg"> <path d="M680-80q-50 0-85-35t-35-85q0-6 3-28L282-392q-16 15-37 23.5t-45 8.5q-50 0-85-35t-35-85q0-50 35-85t85-35q24 0 45 8.5t37 23.5l281-164q-2-7-2.5-13.5T560-760q0-50 35-85t85-35q50 0 85 35t35 85q0 50-35 85t-85 35q-24 0-45-8.5T598-672L317-508q2 7 2.5 13.5t.5 14.5q0 8-.5 14.5T317-452l281 164q16-15 37-23.5t45-8.5q50 0 85 35t35 85q0 50-35 85t-85 35Zm0-80q17 0 28.5-11.5T720-200q0-17-11.5-28.5T680-240q-17 0-28.5 11.5T640-200q0 17 11.5 28.5T680-160ZM200-440q17 0 28.5-11.5T240-480q0-17-11.5-28.5T200-520q-17 0-28.5 11.5T160-480q0 17 11.5 28.5T200-440Zm480-280q17 0 28.5-11.5T720-760q0-17-11.5-28.5T680-800q-17 0-28.5 11.5T640-760q0 17 11.5 28.5T680-720Zm0 520ZM200-480Zm480-280Z" ></path> </svg> <span>Share</span>
<!-- Arrow right --> <svg class="submenu-icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg"> <path d="M400-280v-400l200 200-200 200Z"></path> </svg> </button>
<button type="button" class="option" role="menuitem"> <!-- Mail --> <svg class="action-icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg"> <path d="M160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h640q33 0 56.5 23.5T880-720v480q0 33-23.5 56.5T800-160H160Zm320-280L160-640v400h640v-400L480-440Zm0-80 320-200H160l320 200ZM160-640v-80 480-400Z" ></path> </svg> <span>Mail</span> </button>
<button type="button" class="option" role="menuitem"> <!-- Print --> <svg class="action-icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg"> <path d="M640-640v-120H320v120h-80v-200h480v200h-80Zm-480 80h640-640Zm560 100q17 0 28.5-11.5T760-500q0-17-11.5-28.5T720-540q-17 0-28.5 11.5T680-500q0 17 11.5 28.5T720-460Zm-80 260v-160H320v160h320Zm80 80H240v-160H80v-240q0-51 35-85.5t85-34.5h560q51 0 85.5 34.5T880-520v240H720v160Zm80-240v-160q0-17-11.5-28.5T760-560H200q-17 0-28.5 11.5T160-520v160h80v-80h480v80h80Z" ></path> </svg> <span>Print</span> </button>
<button type="button" class="option" role="menuitem"> <!-- Download --> <svg class="action-icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg"> <path d="M480-320 280-520l56-58 104 104v-326h80v326l104-104 56 58-200 200ZM240-160q-33 0-56.5-23.5T160-240v-120h80v120h480v-120h80v120q0 33-23.5 56.5T720-160H240Z" ></path> </svg> <span>Download</span> </button> </sv-flyout> </sv-menu>
<sv-menu class="action-submenu" mode="submenu"> <sv-flyout aria-label="Help submenu" open-on-hover position-order="horizontal"> <button type="button" class="option" slot="trigger"> <!-- Help --> <svg class="action-icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg"> <path d="M513.5-254.5Q528-269 528-290t-14.5-35.5Q499-340 478-340t-35.5 14.5Q428-311 428-290t14.5 35.5Q457-240 478-240t35.5-14.5ZM442-394h74q0-33 7.5-52t42.5-52q26-26 41-49.5t15-56.5q0-56-41-86t-97-30q-57 0-92.5 30T342-618l66 26q5-18 22.5-39t53.5-21q32 0 48 17.5t16 38.5q0 20-12 37.5T506-526q-44 39-54 59t-10 73Zm38 314q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z" ></path> </svg> <span>Help</span>
<!-- Arrow right --> <svg class="submenu-icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg"> <path d="M400-280v-400l200 200-200 200Z"></path> </svg> </button>
<button type="button" class="option" role="menuitem"> <!-- Info --> <svg class="action-icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg"> <path d="M440-280h80v-240h-80v240Zm68.5-331.5Q520-623 520-640t-11.5-28.5Q497-680 480-680t-28.5 11.5Q440-657 440-640t11.5 28.5Q463-600 480-600t28.5-11.5ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z" ></path> </svg> <span>About</span> </button>
<button type="button" class="option" role="menuitem"> <!-- Report --> <svg class="action-icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg"> <path d="M480-280q17 0 28.5-11.5T520-320q0-17-11.5-28.5T480-360q-17 0-28.5 11.5T440-320q0 17 11.5 28.5T480-280Zm-40-160h80v-240h-80v240ZM330-120 120-330v-300l210-210h300l210 210v300L630-120H330Zm34-80h232l164-164v-232L596-760H364L200-596v232l164 164Zm116-280Z" ></path> </svg> <span>Report</span> </button> </sv-flyout> </sv-menu> </sv-flyout> </sv-menu></div>
<script type="application/x-typescript" module>8 collapsed lines
const menu = document.querySelector<Menu>(".action-menu")!; const actions = menu.querySelectorAll<HTMLButtonElement>(".option:not([slot])");
for (const action of actions) { action.addEventListener("click", () => { menu.close(); }); }</script>
<style>69 collapsed lines
.action-menu-example { display: grid; justify-items: center; padding-block: 1em;
sv-flyout::part(content) { inline-size: clamp(150px, 38vw, 200px); }
.action-submenu sv-flyout { --sv-flyout-offset: 0; }
.trigger { display: grid; place-items: center; padding: 0.4em; color: var(--sv-gray-2); cursor: pointer; background-color: var(--sv-gray-6); border: solid var(--sv-bdr-sz-sm) var(--sv-gray-5); border-radius: var(--sv-bdr-rad-md);
.trigger-icon { inline-size: 1.5em; block-size: 1.5em; fill: currentcolor; } }
.option { display: flex; gap: 0.5em; align-items: center; padding: 0.5em; font: inherit; color: var(--sv-gray-2); text-align: start; cursor: pointer; background-color: transparent; border: none; border-radius: var(--sv-bdr-rad-md);
.action-icon { flex-shrink: 0; inline-size: 1em; block-size: 1em; fill: var(--sv-accent); }
.submenu-icon { inline-size: 1.2em; block-size: 1.2em; margin-inline-start: auto; fill: currentcolor; }
@media (hover: hover) and (pointer: fine) { &:hover { background-color: var(--sv-gray-5); } } }
.divider { block-size: 1px; background-color: var(--sv-gray-5); } }</style>