JSPM

@rmwc/menu

14.0.3
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 15266
  • Score
    100M100P100Q196192F
  • License MIT

RMWC Menu component

Package Exports

  • @rmwc/menu
  • @rmwc/menu/styles

Readme

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"

      />

    </\>

  );

}

SimpleMenu

SimpleMenuSurface