HomeGetting StartedColor SystemTypographySpacingIconographyLayoutInstallationUsageAngularBlazorReactSvelteVueThemingTypographyCustomizationCSS-Only ComponentsFormsIconsIllustrationsAccessibilityGlobal ConfigurationTailwind CSSSass LibraryForge MCP ServerDropdown OptionsFocus Indicator ClippingAll componentsButtonButton AreaChipFloating Action ButtonIcon ButtonSplit ButtonAutocompleteButton ToggleCalendarCheckboxChip FieldColor PickerDate PickerDate Range PickerFile PickerLabelRadioSelectSliderSwitchText FieldTime PickerApp BarApp LauncherDrawerMenuPaginatorSkip LinkStepperTabsView SwitcherAccordionApp LayoutCardDividerExpansion PanelScaffoldSplit ViewStackStructured CardToolbarBadgeBannerBusy IndicatorCircular ProgressDialogInline MessageLinear ProgressPage StateSkeletonToastTooltipAvatarIconKeyLabel ValueListMeterSecretTableTimelineTimestampTreeKeyboard ShortcutPopoverIntroductionColorTypographySpacingShapeBorderElevationLayeringAnimationUsageIcon LibraryBlocksRoadmapChangelogBlog

Menu

Menus display a list of contextual actions or options in a popup, triggered from a button, icon, or list item.

Menu

Overview

Menus are used to provide a list of options/actions to a user, and are typically anchored dynamically to a button or other similar trigger element and appear upon selection of that trigger element.

Menus can be used in a variety of ways, such as a simple list of options, a list of actions, or a hierarchical/cascading list of options. They appear in front of all other permanent UI elements. If they are in a position to be cut off by the browser or screen’s edge, they can appear to the left, right, or above the element that generates it. Menus do not hold a selection state.

Usage

forge-menu wraps a trigger element and opens a dropdown of options — icon-and-label entries, optionally grouped, set as a JS property rather than an attribute — through mode (click or cascade), placement, and dense. Reserve it for a short list of contextual actions or unrelated options; for a field where a user picks one value from a fixed set, use a select instead — the menu’s own selectedIndex/selectedValue are deprecated for exactly that reason.

Rules

Do
Use icons consistently across a menu's options — either every option has one, or none does.Group related options with a divider or a labeled section instead of one flat, mixed list.Keep cascading submenus to one level deep so users don't lose track of where they are.
Don't
Don't use a menu to represent a form field's selection state — use a select instead.Don't mix clearly unrelated actions into the same menu without a visual separator between them.Don't rely on selectedIndex or selectedValue for persisted selection — both are deprecated in favor of forge-select-dropdown.Don't use when options need to be immediately visible for comparison or quick access.

Basic usage

Wrap a trigger element — typically a button — in forge-menu and set its options property to populate the dropdown.

A menu opened from a button trigger.

Add an icon to an option with icon (or leadingIcon/trailingIcon to be explicit about placement), plus a matching leadingIconType/trailingIconType set to "component" to render it as a real forge-icon element:

const options = [
  { label: "Edit", value: "edit", leadingIcon: "edit", leadingIconType: "component" },
  { label: "Delete", value: "delete", leadingIcon: "delete", leadingIconType: "component" },
];

Grouped options

Pass grouped entries in options to divide a longer list into labeled sections instead of one flat list.

A menu with its options divided into labeled sections.

Cascading

Set mode="cascade" and nest a sub-options array on an option to open a submenu instead of selecting it immediately.

A cascading menu opens a submenu instead of selecting immediately.

Menus display a list of options or actions that users can select from a dropdown. Menus wrap button or list item elements to provide the trigger for displaying the menu options.

import "@tylertech/forge/menu";
Properties
PropertyAttributeTypeDefaultDescription
openopenbooleanfalseGets/sets the open state.
options—Array<IMenuOption | IMenuOptionGroup> | MenuOptionFactory[]Gets/sets the array of options to display in the menu.
selectedIndexselected-indexnumber—Gets/sets the selected option to the index. Does not support cascading menus.
selectedValueselected-valueany—Gets/sets the value of the option to select.
placementplacement`${PositionPlacement}`"bottom-start"Gets/sets the menu placement (default is bottom-left).
fallbackPlacementsfallback-placements`${PositionPlacement}`[]—Gets/sets the fallback menu placement for overriding the default of any side.
densedensebooleanfalseGets/sets dense state of the list options used in the menu popup.
iconClassicon-classstring—Gets/sets the class name to use for option icons.
persistSelection—boolean—Gets/sets whether selection of menu items is persisted.
modemodeMenuMode"click"Gets/sets the mode that this menu is using.
popupOffset—IOverlayOffset—Sets the position adjustment on the internal popup element.
optionBuilder—MenuOptionBuilder—Sets the callback that will be executed for each option in the dropdown for producing custom option templates.
popupElement—HTMLElement | undefined—Gets the currently active popup element when the dropdown is open.
popupTargetpopup-targetstring | nullnullGets/sets the ID of the element to use as the popup anchor for positioning. When null or empty, the target element (button) is used for both interaction and positioning. This is useful for cases like forge-list-item > button where the menu should be attached to the button for listeners but positioned relative to the list item.
popupClassespopup-classesstring | string[]—Gets/sets the list of classes to apply to the popup element.
popupHeaderBuilder—ListDropdownHeaderBuilder—Gets/sets the callback function for generating header content within the popup.
popupFooterBuilder—ListDropdownFooterBuilder—Gets/sets the callback function for generating header content within the popup.
syncPopupWidthsync-popup-widthbooleanfalseGets/sets whether the popup width is synchronized with the popup target width.
optionLimitoption-limitnumber0Gets/sets the maximum number of options to display in the dropdown.
observeScrollobserve-scrollbooleanfalseControls the observation of scroll events on the dropdown.
observeScrollThresholdobserve-scroll-thresholdnumber0The number of pixels from the bottom to trigger the scroll bottom event. Only applicable if `observeScroll` is true.
constrainPopupWidthconstrain-popup-widthbooleantrueGets/sets whether the popup width will be constrained to a max width of the viewport width (default: `100vw`).
wrapOptionTextwrap-option-textbooleanfalseGets/sets whether the options will wrap their text or not. This only applies if `constrainPopupWidth` is `true`, if there is an explicit width set via CSS.
popoverPlacementpopover-placementOverlayPlacement'bottom'Gets/sets the placement of the popover.
popoverOffsetpopover-offsetIOverlayOffset—Gets/sets the offset of the popover.
popoverFlippopover-flipOverlayFlipState'auto'Gets/sets the flip state of the popover.
popoverShiftpopover-shiftOverlayShiftState'auto'Gets/sets whether the popover should shift to fit within the viewport.
popoverFallbackPlacementspopover-fallback-placementsPositionPlacement[] | null—Gets/sets the fallback placements of the popover.
Events
NameTypeDescription
forge-menu-selectCustomEvent<IMenuSelectEventData>Dispatches when a menu option is selected.
forge-menu-openCustomEvent<void>Dispatches when the menu is opened.
forge-menu-closeCustomEvent<void>Dispatches when the menu is closed.
forge-menu-active-changeCustomEvent<IMenuActiveChangeEventData>Dispatches when the active menu option changes.
Methods
NameReturnsDescription
propagateKeyEvent(evt)voidForce propagates the key event from another element to this component.
activateFirstOption()voidActivates the first option in the menu when open.

Trigger and item selection

  • The trigger element that opens and closes the menu should be reachable and activatable by keyboard, with a visible focus cue.
  • Pressing Space or Enter while the trigger is focused should open the menu the same way a click would.
  • Once open, each menu item should be selectable using the up and down arrow keys.

Keyboard shortcuts

Menu open Action
Space / Escape Closes the menu.
Enter / Right arrow Opens or closes the focused item’s child menu.
Left arrow Closes the menu (cascade mode only).
Menu closed Action
Space Opens the menu.
Enter Opens the menu and its focused item’s child menu.
Down arrow Opens the menu and focuses the first item.

Interactive elements in a menu option

Placing an interactive element inside a menu option needs the same forge-ignore handling described in nested interactive elements.

Loading Forge chat…