Skip to content
lab components / Actions and controls

Action menu

Action Menu is used to present a list of actions when space is limited.

This is a Lab component!

That means it doesn't satisfy our definition of done and may be changed or even deleted. For an exact status, please reach out to the Fancy team through the dev_fancy or ux_fancy channels.

import { ActionMenu } from "@siteimprove/fancylab";

#Examples

An ActionMenu allows the user to choose a specific action from a list of actions. When the ActionMenu button is pressed, a list of items for the current task or view appears. The user can only select one item at a time. When an item is pressed, the action is performed immediately and the menu is closed.

The ActionMenu consists of four main elements:

  • Button: communicates what actions are available and enable users to trigger a menu. The label never changes. A button is paired with the menu and is part of the component architecture.
  • Chevron icon: indicates that more actions are available.
  • Menu: a list of actions the user can take. The menu can appear above or below a button, depending on where a menu appears in the layout, so that it always remains visible.
  • Menu item: describes the action that the user can take from the menu. Place the most frequently used or high priority items at the top.
<ActionMenu items={[ { text: "Action Button", onClick: () => console.log("clicked") }, { text: "Action Link", href: "https://www.google.com", openNew: true }, ActionMenu.divider, { text: "Disabled Action Button", onClick: () => console.log("clicked"), disabled: true, }, { text: "Disabled Action Link", href: "https://www.google.com", openNew: true, disabled: true, }, ]} buttonContent="Action Menu" />

#Item variants

Each item in a menu can be either a button or a link.

  • Button items: a menu item wrapped in a button tag <button>. It is useful when the user's main task is to change the state of some data set by issuing commands.
  • Link items: a menu item wrapped in an anchor tag <a>. It is useful when the user's main task is to obtain information by navigating to another site, page or section of a page.

The menu item always has a label and can optionally include descriptions, icons, and tooltips to give the user additional information about an action. Keep items concise and consistent.

  • Label: describes the action the user may select. The label should be direct and clear so the user can quickly decide on an action.
  • Description: use descriptions when the information will help the user to choose an action from the menu. Do not overload the user with repetitive information.
  • Icon: use an icon only when necessary and when it has a strong association with the item's label.
  • Tooltip: use tooltips sparingly, as they only work when hovering. Excessive use of tooltips can clutter UI and obscure the label of the item.

State variations

Each item has the following states:

  • Default: when a user has not interacted with an item, it is displayed in its default state.
  • Hover: when a user hovers over an item, a highlight (light gray background) appears indicating that the item is selectable.
  • Focus: a blue outline appears around the text area when the user uses keyboard to navigate through the items.
  • Active/Pressed: a light blue background appears while the item is clicked.
  • Disabled: the disabled option should be used infrequently. It indicates that the item is present, but is not currently available to the user.


<ActionMenu buttonContent="Button items" items={[ { text: "Action Button", onClick: () => console.log("clicked") }, { text: "Action Button Disabled", onClick: () => console.log("clicked"), disabled: true, }, ActionMenu.divider, { text: "Action Button With Icon", onClick: () => console.log("clicked"), icon: <IconSettings />, }, { text: "Action Button With Description", description: "This button has a description", onClick: () => console.log("clicked"), }, { text: "Action Button With Tooltip", description: "This button has a description", icon: <IconSettings />, tooltip: "This button has a tooltip", onClick: () => console.log("clicked"), }, ]} /> <br /> <br /> <ActionMenu buttonContent="Link items" items={[ { text: "Action Link", href: "https://www.google.com", openNew: true }, { text: "Action Link Disabled", href: "https://www.google.com", openNew: true, disabled: true, }, ActionMenu.divider, { text: "Action Link With Icon", href: "https://www.google.com", openNew: true, icon: <IconSettings />, }, { text: "Action Link With Description", href: "https://www.google.com", openNew: true, icon: <IconSettings />, description: "This link has a description and an icon", }, { text: "Action Link With Tooltip", href: "https://www.google.com", openNew: true, icon: <IconSettings />, description: "This link has a description and an icon", tooltip: "This link has a tooltip", }, ]} />

#Usage with Sections

It is useful to use sections to differentiate between the functions and relationships of menu items. For example, add, edit, and copy can be considered as one section. Avoid having only one section in a menu.

A menu section consists of a subheading, an icon and a divider.

  • Subheading: describes the group of actions listed below.
  • Icon (optional): provides a visual representation of the subheading, such as a gear that indicates settings.
  • Divider (optional): visually groups related actions within the same menu.
<ActionMenu buttonContent="Action Menu" items={[ // without icons ActionMenu.sectionHeader("File"), { text: "New File", onClick: () => console.log("clicked") }, { text: "Open File", onClick: () => console.log("clicked") }, // with icons ActionMenu.sectionHeader("Settings", <IconSettings />), { text: "Increase Contrast", icon: <IconContrast />, onClick: () => console.log("clicked"), }, { text: "Toggle Fullscreen", description: "this is a description", icon: <IconFullscreen />, onClick: () => console.log("clicked"), }, ]} />

#Button variants

Choose an appropriate Button that can help streamline the user's choices. In certain cases, you may use different Button variants in your layout. Be cautious when mixing different variants in the same layout to avoid inconsistency. See Button to find more details about the button variants.

const items = [ { text: "Action Button", onClick: () => console.log("clicked") }, { text: "Action Link", href: "https://www.google.com", openNew: true }, ]; return ( <div style={{ display: "flex", gap: SpaceSmall }}> <ActionMenu items={items} buttonContent="Action Menu" buttonProps={{ size: "small", variant: "primary", }} /> <ActionMenu items={items} buttonContent="Action Menu" buttonProps={{ size: "medium", variant: "secondary", }} /> <ActionMenu items={items} buttonContent="Action Menu" buttonProps={{ size: "large", variant: "ctaDefault", }} /> </div> );

#Chevron and icons are optional

The icon-only Button, especially when using IconOptions (three horizontal dots), is often used as a trigger for hidden items that do not fit in views. Avoid icons that could be confused with navigation, such as IconMenu in the icon-only Button.

<ActionMenu aria-label="Action menu" hideChevron buttonContent={ <Icon> <IconOptions /> </Icon> } items={[ { text: "Actionbutton", icon: <IconEdit />, onClick: () => console.log("clicked") }, { text: "ActionLink", icon: <IconOpenNew />, href: "https://www.google.com", openNew: true }, { text: "Disabled actionbutton", icon: <IconDelete />, onClick: () => console.log("clicked"), disabled: true, }, ActionMenu.divider, { text: "Actionbutton", onClick: () => console.log("clicked") }, { text: "ActionLink", href: "https://www.google.com", openNew: true }, { text: "Disabled actionbutton", onClick: () => console.log("clicked"), disabled: true, }, ]} />

#Searchable

The search field allows the user to type in a keyword to search for an item, and it should only be used if the user is very familiar with the menu item. This way the user can access it quickly.

You should keep in mind that since menu items should have fewer than seven items, it might be unusual to include a search function in the ActionMenu. Alternatively, if you use sections properly, the menu should be easy to scan.

<ActionMenu searchable buttonContent="Action Menu" items={[ // without icons ActionMenu.sectionHeader("File"), { text: "New File", onClick: () => console.log("clicked") }, { text: "Open File", onClick: () => console.log("clicked") }, // with icons ActionMenu.sectionHeader("Settings", <IconSettings />), { text: "Increase Contrast", icon: <IconContrast />, onClick: () => console.log("clicked"), }, { text: "Toggle Fullscreen", description: "this is a description", icon: <IconFullscreen />, onClick: () => console.log("clicked"), }, ]} />

#Properties

PropertyDescriptionDefinedValue
itemsRequired
object[]List of strings or objects to display in the menu
aria-labelOptional
stringLabel to describe the list
buttonContentOptional
elementText and other content for menu menu
buttonPropsOptional
objectProps to affect the styling of the menu button
hideChevronOptional
booleanIf set to true, chevron icon will be hidden
containerClassNameOptional
stringClassname for container of both menu and popover
searchableOptional
booleanEnables item search functionality
tooltipOptional
| string | number | elementTooltip text
tooltipPlacementOptional
"bottom" | "bottom-end" | "bottom-start" | "left" | "left-end" | "left-start" | "right" | "right-end" | "right-start" | "top" | "top-end" | "top-start"Tooltip placement
data-observe-keyOptional
stringUnique string, used by external script e.g. for event tracking
classNameOptional
stringCustom className that's applied to the outermost element (only intended for special cases)
styleOptional
objectStyle object to apply custom inline styles (only intended for special cases)

#Guidelines

#Best practices

#General

Use ActionMenu when

  • the user can perform actions with a single selection.
  • less important actions need to be provided and space is limited.
  • there is more than one action or link, preferably 2 to 7.

#Placement

ActionMenu is typically used in the following places:

  • Card

    An ActionMenu is often used in a Card to provide additional actions, such as exporting files or adding widgets to the dashboard. An example can be found in Main Menu > Accessibility > Accessibility Overview > Add widget to dashboard.
  • Table

    An ActionMenu is commonly used in a Table to provide the user with a set of contextual actions related to their current view or task. These actions often provide relevant tools for completing tasks without cluttering the UI. If the menu contains items such as delete, warn the user that the action would destroy data. An example can be found in Main Menu > Policy > My Policies .
  • Include only a set of actions or frequent actions that relate to the task at hand.
  • List menu items in the order in which they are most frequently used so that the user can focus on the most important action.
  • Limit the number of items within a menu. Keep the length of the menu manageable and ensure that all items are visible without having to scroll.
  • Disable items that are not relevant to the user's context to prevent them from being triggered.

#Icons

  • Use action icons for button items, such as IconEdit, and IconCopy.
  • Be careful not to use the same icon for similar actions in the menu, which does not make it easier for the user to select an item. For example, the menu could contain related actions that allow the user to download data in different formats, such as in PDF and HTML formats. In this case, use the IconDownload icon for the icon-only Button to the related actions, and not in each of the menu items.
  • If you cannot find an appropriate icon that represents the action, it is recommended to not have an icon for the menu item.
  • Icons should always be placed to the left of the menu item.

#Style

  • A button is usually located at the right edge of a card, a table or a page.
  • A the destructive item, that would destroy the user's data, should always be visually separated and located at the bottom of the menu. It is recommended to use $color--red--dark (#D04257) to indicate a destructive item.
  • To maintain a consistent single-column format, the default popover has a minimum width of 15 rem and a maximum width of 30 rem.

#Do not use when

  • The user cannot perform an action.
  • There is space for displaying the actions. Especially if the menu contains only one item, consider displaying it as a single action if possible.
  • The user can select more than one item from a list where an item is an option in a filter, form or modal. Use Select instead.

#Accessibility

#For designers

  • Ensure that all labels are clear, concise and consistent. If the same item is available in an additional place, make sure the label is consistent.
  • Ensure that icon-only Button has a name that is accessible to readers.
  • Ensure that the user can open and close the menu with the keyboard by pressing the button and navigate the items within the menu.

#For developers

This component comes with built-in accessibility, no extra work required.

Explore detailed guidelines for this component: Accessibility Specifications

#Writing

#Button label

The button is used as a trigger paired with an ActionMenu. Avoid verbs that imply that pressing a button will perform an action. The button does not perform an action; the items in the ActionMenu perform the actions. For example, write "More" instead of "Edit" for the button label.

  • Use verb + object for item labels: “Add widget,” or “Edit policy”.
  • Use clear and concise labels, preferably 1-3 words.
  • Use sentence case for a label.
  • Do not add punctuation after a label.
  • Avoid unnecessary words and articles such as "the", "an", or "a".