Skip to main content
On this page

An overflow menu tucks secondary or contextual actions behind an icon-only "more" button.

Overview​

When to use​

  • To offer secondary or contextual actions that don't fit the primary UI. The most common place is a row in a Data Table, but it also suits a Card.
  • When there are several actions for the same item and showing each as its own button would crowd the layout.

When not to use​

  • For a single action - show it directly as a standalone icon-only CTA Button instead of hiding it behind a menu.
  • For the primary action on a page or in a form. Keep it visible.
  • To choose a value. This is a menu of actions, not a replacement for Select Field or Combobox Field.

Anatomy​

  1. Trigger: an icon-only CTA Button showing the vertical ellipsis (kebab) icon. Hovering or focusing it shows a tooltip reading "More actions".
  2. Menu: the list of actions, attached directly below the trigger. It is 300px wide, and grows up to 350px to fit longer labels. Each item has a label that describes the action that will be performed.
  3. Icon: an optional icon before the label.

Basic usage​

Loading...
Edit live code
<OverflowMenu
  items={[
    { label: 'Edit', icon: 'edit', onClick: () => alert('Edit') },
    { label: 'Download statement', icon: 'download', onClick: () => alert('Download statement') },
    { label: 'View in new window', icon: 'new-window', onClick: () => alert('View in new window') },
    { label: 'Archive', onClick: () => alert('Archive') },
  ]}
/>

Each item has a label, and optionally an icon, destructive, and one of three kinds: a button with an onClick handler, a link with an href, or a router link with as and to. See the Properties tab for the full list.

Use onClick for something that happens on the page, such as archiving or deleting. Use href for an item that goes somewhere else. The two look the same, but a link is a real anchor, so it can be opened in a new tab, and assistive technology announces it as a link rather than an action.

Loading...
Edit live code
<OverflowMenu
  items={[
    { label: 'Download statement', icon: 'download', onClick: () => alert('Downloading') },
    { label: 'View account', icon: 'link', href: '/account' },
  ]}
/>

Variants​

Tertiary and secondary​

The trigger is built on the icon-only CTA Button, so it is only available as tertiary (the default) or secondary. Tertiary suits dense layouts such as table rows. Use secondary when the trigger needs more visual grounding and has to be clearly separated from surrounding text.

Loading...
Edit live code
<OverflowMenu
  variant="secondary"
  items={[
    { label: 'Edit', icon: 'edit', onClick: () => alert('Edit') },
    { label: 'Delete', icon: 'delete', destructive: true, onClick: () => alert('Delete') },
  ]}
/>

Small size​

Set size="small" for a more compact trigger. The same guidance as the small CTA Button applies. The menu is the same size either way.

Loading...
Edit live code
<OverflowMenu
  size="small"
  items={[
    { label: 'Edit', icon: 'edit', onClick: () => alert('Edit') },
    { label: 'Delete', icon: 'delete', destructive: true, onClick: () => alert('Delete') },
  ]}
/>

Without icons​

Icons are optional. When no item has one, labels sit at the left edge of the menu with no indent. When only some items have one, the others are indented so every label lines up.

Loading...
Edit live code
<OverflowMenu
  items={[
    { label: 'Mark as paid', onClick: () => alert('Mark as paid') },
    { label: 'Archive', onClick: () => alert('Archive') },
    { label: 'Add to group', onClick: () => alert('Add to group') },
    { label: 'Report a problem', onClick: () => alert('Report a problem') },
  ]}
/>

Destructive item​

Set destructive on an item that deletes or removes something. Its label and icon use the error colour. Place it last.

Loading...
Edit live code
<OverflowMenu
  items={[
    { label: 'Edit', icon: 'edit', onClick: () => alert('Edit') },
    { label: 'Archive', onClick: () => alert('Archive') },
    { label: 'Delete', icon: 'delete', destructive: true, onClick: () => alert('Delete') },
  ]}
/>

Give an item an href to make it a link instead of a button, for example to take the user to another page. It sits in the menu and is operated like every other item, and assistive technology announces it as a link. Set opensInNewWindow for a link that opens a new tab or window. A link can also have an onClick, which runs before the link is followed, for example to send an analytics event. It receives the click event, so it can call preventDefault() to stop the link being followed.

To use a client-side router, pass the router's link component as as and the destination as to, as you would for a Text Link. For example, with React Router: { label: 'View account', as: Link, to: '/account' }.

Loading...
Edit live code
<OverflowMenu
  items={[
    { label: 'View account', icon: 'link', href: '/account' },
    {
      label: 'Help centre',
      icon: 'new-window',
      href: 'https://example.com/help',
      opensInNewWindow: true,
    },
    { label: 'Archive', onClick: () => alert('Archive') },
  ]}
/>

Placement​

The menu lines up with the left edge of the trigger. If that would run it off the right of the screen, for example for a trigger in the last column of a wide table, it lines up with the right edge of the trigger instead. There is nothing to configure.

In context​

In a table​

Put the trigger in the last column of each row. Give the column a visually hidden heading, and give each menu a label that names its row.

Loading...
Edit live code
<DataTable
  caption={<Strong>Accounts</Strong>}
  columnHeadings={[
    'Account',
    'Balance',
    <VisuallyHidden key="actions">Actions</VisuallyHidden>,
  ]}
  items={[
    [
      'Electricity',
      '£42.10',
      <OverflowMenu
        key="electricity"
        label="More actions for Electricity"
        items={[
          { label: 'View statements', onClick: () => alert('View statements') },
          { label: 'Download statement', icon: 'download', onClick: () => alert('Download statement') },
          { label: 'Close account', icon: 'delete', destructive: true, onClick: () => alert('Close account') },
        ]}
      />,
    ],
    [
      'Gas',
      '£18.75',
      <OverflowMenu
        key="gas"
        label="More actions for Gas"
        items={[
          { label: 'View statements', onClick: () => alert('View statements') },
          { label: 'Download statement', icon: 'download', onClick: () => alert('Download statement') },
          { label: 'Close account', icon: 'delete', destructive: true, onClick: () => alert('Close account') },
        ]}
      />,
    ],
  ]}
/>

In a card​

Loading...
Edit live code
<Card>
  <Cluster justify="space-between">
    <ClusterItem>
      <Heading3>Direct debit</Heading3>
    </ClusterItem>
    <ClusterItem>
      <OverflowMenu
        label="More actions for direct debit"
        items={[
          { label: 'Change amount', onClick: () => alert('Change amount') },
          { label: 'Change date', onClick: () => alert('Change date') },
          { label: 'Cancel direct debit', icon: 'delete', destructive: true, onClick: () => alert('Cancel direct debit') },
        ]}
      />
    </ClusterItem>
  </Cluster>
  <P>£50.00 on the 1st of every month.</P>
</Card>