Amplify UI

Menu

Menu provides a way for users to navigate and select actions within an application.

Demo

Usage

Import the Menu and MenuItem components. Note that the Menu component is rendered in a React Portal, so you can set the Menu button's width from its outer container.

import { Menu, MenuItem, View } from '@aws-amplify/ui-react';

export const BasicExample = () => {
  return (
    <View width="4rem">
      <Menu>
        <MenuItem>Option 1</MenuItem>
        <MenuItem>Option 2</MenuItem>
        <MenuItem>Option 3</MenuItem>
      </Menu>
    </View>
  );
};

Use the MenuItem component to configure Menu options. The example below demonstrates how to add interactivity to the MenuItem's via the onClick handler, as well as how to use the Divider component and isDisabled prop.

import { Menu, MenuItem, View, Divider } from '@aws-amplify/ui-react';

export const MenuItemsExample = () => {
  return (
    <View width="4rem">
      <Menu>
        <MenuItem onClick={() => alert('Download')}>Download</MenuItem>
        <MenuItem onClick={() => alert('Create a Copy')}>
          Create a Copy
        </MenuItem>
        <Divider />
        <MenuItem isDisabled onClick={() => alert('Delete')}>
          Delete
        </MenuItem>
      </Menu>
    </View>
  );
};

Customize Menu button

The default Menu button can be customized by importing the MenuButton component and passing it to the Menu's trigger prop. MenuButton can take all the same props as Button.

import { Menu, MenuItem, MenuButton } from '@aws-amplify/ui-react';

export const MenuExample = () => (
  <Menu
    trigger={
      <MenuButton variation="primary" size="large" width="40%">
        Custom trigger button 🚀
      </MenuButton>
    }
  >
    <MenuItem>Download</MenuItem>
    <MenuItem>Create a Copy</MenuItem>
    <MenuItem>Mark as Draft</MenuItem>
  </Menu>
);

To control the alignment of the Menu with the Menu button, use the menuAlign prop. Available options are start (default), center, and end.

import { Flex, Menu, MenuItem } from '@aws-amplify/ui-react';

export const MenuAlignExample = () => {
  return (
    <Flex direction="column" width="4rem">
      <Menu>
        <MenuItem>Align start (default)</MenuItem>
      </Menu>
      <Menu menuAlign="center">
        <MenuItem>Align center</MenuItem>
      </Menu>
      <Menu menuAlign="end">
        <MenuItem>Align end</MenuItem>
      </Menu>
    </Flex>
  );
};

Size

Control the size of the Menu button and items using the size prop. Available options are small, none (default), and large.

import { Menu, MenuItem, Flex } from '@aws-amplify/ui-react';

export const SizeExample = () => {
  return (
    <Flex direction="column" width="4rem">
      <Menu size="small">
        <MenuItem>Download</MenuItem>
        <MenuItem>Create a Copy</MenuItem>
      </Menu>
      <Menu>
        <MenuItem>Download</MenuItem>
        <MenuItem>Create a Copy</MenuItem>
      </Menu>
      <Menu size="large">
        <MenuItem>Download</MenuItem>
        <MenuItem>Create a Copy</MenuItem>
      </Menu>
    </Flex>
  );
};

Controlled Menu

Create a controlled Menu using the isOpen and onOpenChange props.

import * as React from 'react';
import { Menu, MenuItem, View } from '@aws-amplify/ui-react';

export const ControlledExample = () => {
  const [isOpen, setIsOpen] = React.useState(false);

  const handleOpenChange = (open) => {
    setIsOpen(open);
    // Do something else
  };

  const closeMenu = () => setIsOpen(false);

  return (
    <View width="4rem">
      <Menu
        isOpen={isOpen}
        onOpenChange={handleOpenChange}
        width="3rem"
        maxWidth="4rem"
      >
        <MenuItem
          onClick={() => {
            closeMenu();
            alert('Download');
          }}
        >
          Download
        </MenuItem>
        <MenuItem
          onClick={() => {
            closeMenu();
            alert('Create a Copy');
          }}
        >
          Create a Copy
        </MenuItem>
        <MenuItem
          onClick={() => {
            closeMenu();
            alert('Mark as Draft');
          }}
        >
          Mark as Draft
        </MenuItem>
      </Menu>
    </View>
  );
};

Styling

Theme

You can customize the appearance of all Menu components in your application with a Theme.

Menu Theme Source

import { Menu, MenuItem, ThemeProvider, Theme } from '@aws-amplify/ui-react';

const theme: Theme = {
  name: 'menu-theme',
  tokens: {
    components: {
      menu: {
        backgroundColor: { value: '{colors.blue.20}' },
        borderRadius: { value: '0' },
        item: {
          minHeight: { value: '5rem' },
        },
      },
    },
  },
};

export const MenuThemeExample = () => {
  return (
    <ThemeProvider theme={theme} colorMode="light">
      <Menu>
        <MenuItem>Download</MenuItem>
        <MenuItem>Create a Copy</MenuItem>
        <MenuItem>Mark as Draft</MenuItem>
      </Menu>
    </ThemeProvider>
  );
};

Icons

import { Menu, MenuItem, IconsProvider } from '@aws-amplify/ui-react';
import { FiMoreHorizontal } from 'react-icons/fi';

export const MenuIconExample = () => (
  <IconsProvider
    icons={{
      menu: {
        menu: <FiMoreHorizontal />,
      },
    }}
  >
    <Menu>
      <MenuItem>Download</MenuItem>
      <MenuItem>Create a Copy</MenuItem>
      <MenuItem>Mark as Draft</MenuItem>
    </Menu>
  </IconsProvider>
);

Target classes

ClassDescription
amplify-menu__contentMenu content container (Flex)
amplify-menu__wrapperMenu content wrapper
amplify-menu__content__itemMenu item button (MenuButton, wrapped in amplify-menu-content class)
amplify-menu__triggerMenu trigger button (MenuButton, not wrapped in amplify-menu-content class)
  • --amplify-components-menu-background-color
  • --amplify-components-menu-border-color
  • --amplify-components-menu-border-radius
  • --amplify-components-menu-border-style
  • --amplify-components-menu-border-width
  • --amplify-components-menu-box-shadow
  • --amplify-components-menu-flex-direction
  • --amplify-components-menu-gap
  • --amplify-components-menu-item-min-height
  • --amplify-components-menu-item-padding-inline-end
  • --amplify-components-menu-item-padding-inline-start
  • --amplify-components-menu-large-height
  • --amplify-components-menu-large-width
  • --amplify-components-menu-max-width
  • --amplify-components-menu-min-width
  • --amplify-components-menu-small-height
  • --amplify-components-menu-small-width

Global styling

To override styling on all Menus, you can set the Amplify CSS variables with the built-in classes.

/* styles.css */
.amplify-menu-content {
  --amplify-components-button-color: var(--amplify-colors-secondary-90);
}
.amplify-menu-trigger {
  --amplify-components-button-border-color: var(
    --amplify-colors-secondary-90
  );
  --amplify-components-button-color: var(--amplify-colors-secondary-90);
}
import { Menu, MenuItem } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';

import './styles.css';

export const GlobalStylingExample = () => (
  <Menu>
    <MenuItem>Download</MenuItem>
    <MenuItem>Create a Copy</MenuItem>
    <MenuItem>Mark as Draft</MenuItem>
  </Menu>
);

Local styling

To override styling on a specific Menu, you can use (in order of increasing specificity): a class selector, data attributes, or style props.

Using a class selector:

Note: The classname prop is applied to the Menu dropdown content. Use the triggerClassName prop to apply a class to the menu trigger button.

/* styles.css */
.my-menu-trigger.amplify-menu-trigger {
  border-color: var(--amplify-colors-secondary-90);
  color: var(--amplify-colors-secondary-90);
}
.my-menu-content .amplify-menu-content__item {
  color: var(--amplify-colors-secondary-90);
}
.my-menu-content .amplify-menu-content__item:hover {
  background-color: var(--amplify-colors-secondary-90);
}
import { Menu, MenuItem } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';

import './styles.css';

export const ClassNameExample = () => (
  <Menu className="my-menu-content" triggerClassName="my-menu-trigger">
    <MenuItem>Download</MenuItem>
    <MenuItem>Create a Copy</MenuItem>
    <MenuItem>Mark as Draft</MenuItem>
  </Menu>
);

Using data attributes:

/* styles.css */
.amplify-menu-content__item[data-size='large'] {
  font-size: var(--amplify-font-sizes-xxxxl);
}
import { Menu, MenuItem } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';

import './styles.css';

export const DataAttributesExample = () => (
  <Menu size="large">
    <MenuItem>Download</MenuItem>
    <MenuItem>Create a Copy</MenuItem>
    <MenuItem>Mark as Draft</MenuItem>
  </Menu>
);

Using style props:

import { Menu, MenuItem, View, useTheme } from '@aws-amplify/ui-react';

export const StylePropsExample = () => {
  const { tokens } = useTheme();

  return (
    <View width="4rem">
      <Menu direction="row">
        <MenuItem>Download</MenuItem>
        <MenuItem fontStyle="italic">Create a Copy</MenuItem>
        <MenuItem backgroundColor={tokens.colors.red[40]}>Delete</MenuItem>
      </Menu>
    </View>
  );
};

Amplify open source software, documentation and community are supported by Amazon Web Services.

© 2024 Amazon Web Services, Inc. and its affiliates. All rights reserved. View the site terms and privacy policy.

Flutter and the related logo are trademarks of Google LLC. We are not endorsed by or affiliated with Google LLC.