Skip to content

Menu Actions

Use mode="menu" for action buttons and mode="submenu" for nested actions.

Warning

menu mode is not a form control.

Code

The following example assumes that you have imported the component and set up the theme.

Menu Actions
<div class="menu-container">
<label for="action-menu">More Actions:</label>
<button id="action-menu" type="button" class="trigger" slot="trigger">
<svg class="trigger-icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg">
5 collapsed lines
<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>
<sv-menu class="action-menu" mode="menu">
<sv-flyout aria-label="More actions menu" trigger-element="#action-menu">
5 collapsed lines
<button type="button" class="option" role="menuitem">
<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>
5 collapsed lines
<button type="button" class="option" role="menuitem">
<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>
5 collapsed lines
<button type="button" class="option" role="menuitem">
<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 offset="0" open-on-hover position-order="horizontal">
<button type="button" class="option" slot="trigger">
10 collapsed lines
<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>
<svg class="submenu-icon" aria-hidden="false" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg">
<path d="M400-280v-400l200 200-200 200Z"></path>
</svg>
</button>
5 collapsed lines
<button type="button" class="option" role="menuitem">
<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>
5 collapsed lines
<button type="button" class="option" role="menuitem">
<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>
5 collapsed lines
<button type="button" class="option" role="menuitem">
<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 offset="0" open-on-hover position-order="horizontal">
<button type="button" class="option" slot="trigger">
10 collapsed lines
<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"
/>
</svg>
<span>Help</span>
<svg class="submenu-icon" aria-hidden="false" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg">
<path d="M400-280v-400l200 200-200 200Z"></path>
</svg>
</button>
5 collapsed lines
<button type="button" class="option" role="menuitem">
<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"
/>
</svg>
<span>About</span>
</button>
5 collapsed lines
<button type="button" class="option" role="menuitem">
<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"
/>
</svg>
<span>Report</span>
</button>
</sv-flyout>
</sv-menu>
</sv-flyout>
</sv-menu>
</div>
13 collapsed lines
<script type="module">
/** @type {Menu} */
const actionMenu = document.querySelector(".action-menu");
/** @type {NodeListOf<HTMLButtonElement>} */
const actionButtons = actionMenu.querySelectorAll(".option:not([slot])");
actionButtons.forEach(button => {
button.addEventListener("click", () => {
actionMenu.close();
});
});
</script>
8 collapsed lines
<style>
.menu-container {
display: flex;
flex-direction: column;
gap: 0.5em;
max-inline-size: 350px;
margin: auto;
.action-menu sv-flyout::part(content),
.action-submenu sv-flyout::part(content) {
inline-size: clamp(150px, 200px, 38vw);
min-block-size: 100px;
}
70 collapsed lines
.trigger {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 0.5em;
margin: auto;
font-family: inherit;
font-size: 1rem;
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);
transition: border-color 200ms ease;
.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-family: inherit;
font-size: 1rem;
color: var(--sv-gray-2);
cursor: pointer;
background-color: transparent;
border: none;
border-radius: var(--sv-bdr-rad-md);
transition: background-color 200ms;
.action-icon {
flex-shrink: 0;
inline-size: 1em;
block-size: 1em;
fill: var(--sv-accent);
}
.submenu-icon {
inline-size: 1.5em;
block-size: 1.5em;
margin-inline-start: auto;
fill: currentcolor;
}
&[disabled] {
cursor: not-allowed;
filter: saturate(40%) brightness(50%);
}
@media (hover: hover) and (pointer: fine) {
&:not([disabled], [aria-selected="true"]):hover {
background-color: var(--sv-gray-5);
}
}
}
.divider {
inline-size: 100%;
block-size: 1px;
background-color: var(--sv-gray-5);
}
}
</style>