14.2.2 • Published 3 days ago

@rmwc/menu v14.2.2

Weekly downloads
8,329
License
MIT
Repository
github
Last release
3 days ago

Menus

Menus display a list of choices on a transient sheet of material.

  • Module @rmwc/menu
  • Import styles:
    • Using CSS Loader
      • import '@rmwc/menu/styles';
    • Or include stylesheets
      • '@material/menu/dist/mdc.menu.css'
      • '@material/menu-surface/dist/mdc.menu-surface.css'
      • '@material/ripple/dist/mdc.ripple.css'
      • '@material/list/dist/mdc.list.css'
      • '@rmwc/icon/icon.css'
  • MDC Docs: https://material.io/develop/web/components/menus/

Basic Usage

You can compose a menu with the given components, and manually manage the open state. Menu expects MenuItems as children while MenuSurface is a generic container which can have anything as a child.

function Example() {
  const [open, setOpen] = React.useState(false);

  return (
    <MenuSurfaceAnchor>
      <Menu
        open={open}
        onSelect={(evt) => console.log(evt.detail.index)}
        onClose={() => setOpen(false)}
      >
        <MenuItem>Cookies</MenuItem>
        <MenuItem>Pizza</MenuItem>
        {/** MenuItem is just a ListItem, so you can intermingle other List components */}
        <ListDivider />
        <MenuItem>Icecream</MenuItem>
      </Menu>

      <Button raised onClick={() => setOpen(!open)}>
        Menu
      </Button>
    </MenuSurfaceAnchor>
  );
}
function Example() {
  const [open, setOpen] = React.useState(false);

  return (
    <MenuSurfaceAnchor>
      <MenuSurface open={open} onClose={(evt) => setOpen(false)}>
        <div style={{ padding: '1rem', width: '8rem' }}>
          Make the content whatever you want.
        </div>
      </MenuSurface>

      <Button raised onClick={(evt) => setOpen(!open)}>
        Menu Surface
      </Button>
    </MenuSurfaceAnchor>
  );
}
function Example() {
  const [open, setOpen] = React.useState(false);

  return (
    <MenuSurfaceAnchor>
      <MenuSurface open={open} onClose={() => setOpen(false)}>
        <div style={{ padding: '1rem', width: '8rem' }}>Menu</div>
      </MenuSurface>
      {/** The handle can be any component you want */}
      <IconButton icon="menu" onClick={() => setOpen(!open)} />
    </MenuSurfaceAnchor>
  );
}
function Example() {
  const [open, setOpen] = React.useState(false);

  return (
    <MenuSurfaceAnchor>
      <Menu
        open={open}
        onSelect={(evt) => console.log(evt.detail.index)}
        onClose={() => setOpen(false)}
      >
        <MenuItem>Item One</MenuItem>
        <MenuItem disabled>Item Two (disabled)</MenuItem>
        <MenuItem>Item Three</MenuItem>
      </Menu>

      <Button raised onClick={() => setOpen(!open)}>
        Menu
      </Button>
    </MenuSurfaceAnchor>
  );
}

Simplified usage

RMWC provides a convenience SimpleMenu component that takes a handle as a prop, and manages the open state for you.

<SimpleMenu handle={<Button>Simple Menu</Button>}>
  <MenuItem>Cookies</MenuItem>
  <MenuItem>Pizza</MenuItem>
  <MenuItem>Icecream</MenuItem>
</SimpleMenu>
<SimpleMenuSurface handle={<Button>Simple Menu Surface</Button>}>
  <div style={{ padding: '1rem', width: '8rem' }}>
    Make the content whatever you want.
  </div>
</SimpleMenuSurface>

Anchoring

By default, Menus will attempt to automatically position themselves, but this behavior can be overridden by setting the anchorCorner prop.

function Example() {
  const [anchorCorner, setAnchorCorner] =
    React.useState('topLeft');

  return (
    <>
      <MenuSurfaceAnchor>
        <MenuSurface anchorCorner={anchorCorner} open={true}>
          <div style={{ padding: '1rem', width: '8rem' }}>
            anchorCorner: {anchorCorner}
          </div>
        </MenuSurface>
        <Button raised label="Anchored Menu" />
      </MenuSurfaceAnchor>

      <Select
        value={anchorCorner}
        label="anchorCorner"
        onChange={(evt) => setAnchorCorner(evt.currentTarget.value)}
        options={[
          'topLeft',
          'topRight',
          'bottomLeft',
          'bottomRight',
          'topStart',
          'topEnd',
          'bottomStart',
          'bottomEnd'
        ]}
      />
    </>
  );
}

Rendering through Portals

Occasionally, you may find your menu being cut off from being inside a container that is styled to be overflow:hidden. RMWC provides a renderToPortal prop that lets you use React's portal functionality to render the menu dropdown in a different container.

You can specify any element or selector you want, but the simplest method is to pass true and use RMWC's built in Portal component.

  `
  // Somewhere at the top level of your app
  // Render the RMWC Portal
  // You only have to do this once
  import React from 'react';
  import { Portal } from '@rmwc/base';

  export default function App() {
    return (
      <div>
        ...
        <Portal />
      </div>
    )
  }
`

Now you can use the renderToPortal prop. Below is a contrived example of a menu being cut off due to overflow: hidden.

function Example() {
  const [renderToPortal, setRenderToPortal] = React.useState(true);
  const [menuIsOpen, setMenuIsOpen] = React.useState(false);
  const options = ['Cookies', 'Pizza', 'Icecream'];
  return (
    <>
      <div
        style={{
          marginBottom: '10rem',
          height: '3.5rem',
          overflow: 'hidden'
        }}
      >
        <MenuSurfaceAnchor>
          <Button raised onClick={() => setMenuIsOpen(!menuIsOpen)}>
            Open Menu
          </Button>
          <Menu
            open={menuIsOpen}
            onClose={() => setMenuIsOpen(false)}
            renderToPortal={renderToPortal}
          >
            {options.map((o) => (
              <MenuItem key={o}>{o}</MenuItem>
            ))}
          </Menu>
        </MenuSurfaceAnchor>
      </div>
      <Checkbox
        checked={renderToPortal}
        onChange={(evt) => setRenderToPortal(evt.currentTarget.checked)}
        label="renderToPortal"
      />
    </>
  );
}

Menu

A menu component for displaying lists items.

Props

NameTypeDescription
anchorCornerAnchorTManually position the menu to one of the corners.
apiRef(api: null \| MenuApi) => voidInternal api reference for cross component communication.
childrenReactNodeChildren to render.
fixedbooleanMake the menu position fixed.
focusOnOpenbooleanWhether or not to focus the first list item on open. Defaults to true.
foundationRefRef<MDCMenuFoundation<>>Advanced: A reference to the MDCFoundation.
onClose(evt: MenuSurfaceOnCloseEventT) => voidCallback for when the menu is closed.
onOpen(evt: MenuSurfaceOnOpenEventT) => voidCallback for when the menu is opened.
onSelect(evt: MenuOnSelectEventT) => voidCallback that fires when a Menu item is selected. evt.detail = { index: number; item: HTMLElement; }
openbooleanOpens the menu.
renderToPortalPortalPropTRenders the menu to a portal. Useful for situations where the content might be cutoff by an overflow: hidden container. You can pass "true" to render to the default RMWC portal.

MenuItem

This is just the ListItem component exported from the Menu module for convenience. You can use ListItem or SimpleListItem components from the List section as long as you add role="menuitem" and tabIndex="0" to the components for accessibility.

Props

NameTypeDescription
activatedbooleanA modifier for an active state.
disabledbooleanA modifier for a disabled state.
rippleRipplePropTAdds a ripple effect to the component
selectedbooleanA modifier for a selected state.

MenuSurface

Props

NameTypeDescription
anchorCornerAnchorTManually position the menu to one of the corners.
apiRef(api: null \| MenuSurfaceApi) => voidAn internal api for cross component communication.
childrenReactNodeChildren to render.
fixedbooleanMake the menu position fixed.
foundationRefRef<MDCMenuSurfaceFoundation<>>Advanced: A reference to the MDCFoundation.
onClose(evt: MenuSurfaceOnCloseEventT) => voidCallback for when the menu is closed.
onOpen(evt: MenuSurfaceOnOpenEventT) => voidCallback for when the menu is opened.
openbooleanOpens the menu.
renderToPortalPortalPropTRenders the menu to a portal. Useful for situations where the content might be cutoff by an overflow: hidden container. You can pass "true" to render to the default RMWC portal.

MenuSurfaceAnchor


MenuSurfaceAnchor


SimpleMenu

A Simplified menu component that allows you to pass a handle element and will automatically control the open state and add a MenuSurfaceAnchor

Props

NameTypeDescription
anchorCornerAnchorTManually position the menu to one of the corners.
apiRef(api: null \| MenuApi) => voidInternal api reference for cross component communication.
childrenReactNodeChildren to render
fixedbooleanMake the menu position fixed.
focusOnOpenbooleanWhether or not to focus the first list item on open. Defaults to true.
foundationRefRef<MDCMenuFoundation<>>Advanced: A reference to the MDCFoundation.
handleReactElement<any, string \| JSXElementConstructor<any>>An element that will open the menu when clicked
onClose(evt: MenuSurfaceOnCloseEventT) => voidCallback for when the menu is closed.
onOpen(evt: MenuSurfaceOnOpenEventT) => voidCallback for when the menu is opened.
onSelect(evt: MenuOnSelectEventT) => voidCallback that fires when a Menu item is selected. evt.detail = { index: number; item: HTMLElement; }
openbooleanOpens the menu.
renderToPortalPortalPropTRenders the menu to a portal. Useful for situations where the content might be cutoff by an overflow: hidden container. You can pass "true" to render to the default RMWC portal.
rootPropsObjectBy default, props spread to the Menu component. These will spread to the MenuSurfaceAnchor which is useful for things like overall positioning of the anchor.

SimpleMenuSurface

The same as SimpleMenu, but a generic surface.

Props

NameTypeDescription
anchorCornerAnchorTManually position the menu to one of the corners.
apiRef(api: null \| MenuSurfaceApi) => voidAn internal api for cross component communication.
childrenReactNodeChildren to render
fixedbooleanMake the menu position fixed.
foundationRefRef<MDCMenuSurfaceFoundation<>>Advanced: A reference to the MDCFoundation.
handleReactElement<any, string \| JSXElementConstructor<any>>An element that will open the menu when clicked
onClose(evt: MenuSurfaceOnCloseEventT) => voidCallback for when the menu is closed.
onOpen(evt: MenuSurfaceOnOpenEventT) => voidCallback for when the menu is opened.
openbooleanOpens the menu.
renderToPortalPortalPropTRenders the menu to a portal. Useful for situations where the content might be cutoff by an overflow: hidden container. You can pass "true" to render to the default RMWC portal.
rootPropsObjectBy default, props spread to the Menu component. These will spread to the MenuSurfaceAnchor which is useful for things like overall positioning of the anchor.
14.2.2

3 days ago

14.2.0

10 days ago

14.2.1

10 days ago

14.1.5

11 days ago

14.1.4

23 days ago

14.1.3

1 month ago

14.1.2

1 month ago

14.1.1

2 months ago

14.1.0

2 months ago

14.0.12

2 months ago

14.0.11

2 months ago

14.0.10

3 months ago

14.0.9

3 months ago

14.0.8

3 months ago

14.0.7

3 months ago

14.0.6

4 months ago

14.0.5

4 months ago

14.0.4

5 months ago

14.0.1-alpha.0

8 months ago

14.0.2-alpha.3

6 months ago

14.0.2-alpha.0

8 months ago

14.0.2-alpha.1

6 months ago

14.0.2-alpha.6

6 months ago

14.0.2-alpha.7

6 months ago

14.0.2-alpha.4

6 months ago

14.0.2-alpha.5

6 months ago

14.0.0

5 months ago

14.0.1

5 months ago

14.0.0-alpha.0

8 months ago

14.0.2

5 months ago

14.0.3

5 months ago

8.0.8

11 months ago

8.0.7

1 year ago

8.0.6

1 year ago

8.0.5

1 year ago

8.0.4

1 year ago

8.0.3

2 years ago

8.0.2

2 years ago

8.0.1

2 years ago

8.0.0

2 years ago

7.0.3

2 years ago

7.0.2

2 years ago

7.0.1

2 years ago

7.0.0

2 years ago

6.1.4

4 years ago

6.1.3

4 years ago

6.1.2

4 years ago

6.1.1

4 years ago

6.0.14

4 years ago

6.0.13

4 years ago

6.0.12

4 years ago

6.0.11

4 years ago

6.0.10

4 years ago

6.0.9

4 years ago

6.0.5

4 years ago

6.0.4

4 years ago

6.0.1

4 years ago

6.0.3

4 years ago

6.0.2

4 years ago

6.0.0

4 years ago

6.0.0-rc.4

4 years ago

6.0.0-rc.3

4 years ago

6.0.0-rc.2

4 years ago

6.0.0-rc.1

4 years ago

6.0.0-rc.0

4 years ago

6.0.0-alpha.16

4 years ago

6.0.0-alpha.14

4 years ago

6.0.0-alpha.15

4 years ago

6.0.0-alpha.13

4 years ago

6.0.0-alpha.12

4 years ago

6.0.0-alpha.11

4 years ago

6.0.0-alpha.7

4 years ago

5.7.2

4 years ago

6.0.0-alpha.6

4 years ago

6.0.0-alpha.5

4 years ago

6.0.0-alpha.3

4 years ago

5.7.1

5 years ago

5.7.0

5 years ago

5.6.0

5 years ago

5.5.2

5 years ago

5.5.1

5 years ago

5.5.0

5 years ago

5.4.3

5 years ago

5.4.2

5 years ago

5.4.1

5 years ago

5.4.0

5 years ago

5.3.1

5 years ago

5.3.0

5 years ago

5.2.2

5 years ago

5.2.1

5 years ago

5.2.0

5 years ago

5.2.0-alpha.1

5 years ago

5.2.0-alpha.0

5 years ago

5.1.8

5 years ago

5.1.7

5 years ago

5.1.6

5 years ago

5.1.5

5 years ago

5.1.4

5 years ago

5.1.3

5 years ago

5.1.2

5 years ago

5.1.1

5 years ago

5.1.0

5 years ago

5.0.30-rc.0

5 years ago

5.0.29-rc.0

5 years ago

5.0.28-rc.0

5 years ago

5.0.27-rc.0

5 years ago

5.0.26-rc.0

5 years ago

5.0.25-rc.0

5 years ago

5.0.24-rc.0

5 years ago

5.0.23-rc.0

5 years ago

5.0.23-alpha.0

5 years ago

5.0.22-alpha.0

5 years ago

5.0.21-alpha.0

5 years ago

5.0.20-alpha.0

5 years ago

5.0.19-alpha.0

5 years ago

5.0.18-alpha.0

5 years ago

5.0.17-alpha.0

5 years ago

5.0.16-alpha.0

5 years ago

5.0.15-alpha.0

5 years ago

5.0.14-alpha.0

5 years ago

5.0.13-alpha.0

5 years ago

5.0.12-alpha.0

5 years ago

5.0.11-alpha.0

5 years ago

5.0.8-alpha.0

5 years ago

5.0.7-alpha.0

5 years ago

5.0.6-alpha.0

5 years ago

5.0.5-alpha.0

5 years ago

5.0.4-alpha.0

5 years ago

5.0.3-alpha.0

5 years ago

5.0.2-alpha.0

5 years ago

5.0.1-alpha.0

5 years ago

5.0.0-alpha.0

5 years ago

4.0.6

5 years ago

4.0.5

5 years ago

4.0.4

5 years ago

4.0.1

5 years ago

4.0.0

5 years ago

3.0.11

5 years ago

3.0.10

5 years ago

3.0.9

5 years ago

3.0.8

5 years ago

3.0.7

6 years ago

3.0.6

6 years ago

3.0.5

6 years ago

3.0.4

6 years ago

3.0.3

6 years ago

3.0.0

6 years ago

2.2.2

6 years ago

2.2.0

6 years ago

2.1.3

6 years ago

2.1.2

6 years ago

2.1.0

6 years ago

2.0.2

6 years ago

2.0.1

6 years ago

2.0.0

6 years ago

2.0.0-alpha.7

6 years ago

2.0.0-alpha.6

6 years ago

2.0.0-alpha.5

6 years ago

2.0.0-alpha.4

6 years ago

2.0.0-alpha.3

6 years ago

2.0.0-alpha.2

6 years ago

2.0.0-alpha.1

6 years ago

2.0.0-alpha.0

6 years ago

1.10.1-alpha.0

6 years ago

1.10.0-alpha.0

6 years ago