How to get items out and inside of menu item in React?

Asked
Active3 hr before
Viewed126 times

10 Answers

itemsreactinside
90%

How to insert an item into an array at a specific index (JavaScript) , How do you get a timestamp in JavaScript? , How do I get the current date in JavaScript?

 Pretag team - issue, fix, solve, resolve
88%

load more v
72%

The API documentation of the MenuItem React component. Learn more about the props and the CSS customization points.,You can override the style of the component thanks to one of these customization points:,If that's not sufficient, you can check the implementation of the component for more detail.

Import

import MenuItem from '@material-ui/core/MenuItem';
// or
import {
   MenuItem
} from '@material-ui/core';
65%

Simple menus open over the anchor element by default (this option can be changed via props). When close to a screen edge, simple menus vertically realign to make sure that all menu items are completely visible.,Choosing an option should immediately ideally commit the option and close the menu.,If the height of a menu prevents all menu items from being displayed, the menu can scroll internally.

<Button aria-controls="simple-menu" aria-haspopup="true" onClick={handleClick}>
  Open Menu
</Button>
<Menu
  id="simple-menu"
  anchorEl={anchorEl}
  keepMounted
  open={Boolean(anchorEl)}
  onClose={handleClose}
>
  <MenuItem onClick={handleClose}>Profile</MenuItem>
  <MenuItem onClick={handleClose}>My account</MenuItem>
  <MenuItem onClick={handleClose}>Logout</MenuItem>
</Menu>
load more v
75%

Specially for Menu, we added MenuItem and MenuSeparator child components, which allows you to define menu items and separators declaratively in JSX.,For all major list-like controls (ListBox, ComboBox, MultiSelect, Menu), we added special wjItemTemplate render prop, which allows you to specify a render function that draws items content.,But when it comes to React, it sounds tempting to potentially define an item's content declaratively, in JSX markup, using React components with their property bindings.

Now it's possible by means of the new MenuItem component from the @grapecity/wijmo.react.input module. Instead of defining items in an array, you can now use MenuItem components nested to their Menu component right in the render function's JSX, where every MenuItem defines a separate menu item, with a content of an arbitrary complexity in it. In addition, a MenuSeparator component can be used to insert separators between menu items. For example, the following piece of JSX code from this sample defines File menu items with rich content and a separator before the Exit item:

<wjInput.Menu
    header="File"
    itemClicked={this.menuItemClicked}>
    <wjInput.MenuItem>
        <span className="glyphicon glyphicon-asterisk"></span>&nbsp;&nbsp;
        <b>New</b>
        <br />
        <small><i>create a new file</i></small>
    </wjInput.MenuItem>
    <wjInput.MenuItem>
        <span className="glyphicon glyphicon-folder-open"></span>&nbsp;&nbsp;
        <b>Open</b>
        <br />
        <small><i>open an existing file or folder</i></small>
    </wjInput.MenuItem>
    <wjInput.MenuItem>
        <span className="glyphicon glyphicon-floppy-disk"></span>&nbsp;&nbsp;
        <b>Save</b>
        <br />
        <small><i>save the current file</i></small>
    </wjInput.MenuItem>
    <wjInput.MenuSeparator></wjInput.MenuSeparator>
    <wjInput.MenuItem>
        <span className="glyphicon glyphicon-remove"></span>&nbsp;&nbsp;
        <b>Exit</b>
        <br />
        <small><i>exit the application</i></small>
    </wjInput.MenuItem>
</wjInput.Menu>
load more v
40%

Step 3: After creating the ReactJS application, Install the material-ui modules using the following command:,Step 1: Create a React application using the following command:,Creating React Application And Installing Module:

Step 1: Create a React application using the following command:

npx create - react - app foldername

Step 2: After creating your project folder i.e. foldername, move to it using the following command:

cd foldername

npm install @material - ui / core

Step to Run Application: Run the application using the following command from the root directory of the project:

npm start
load more v
22%

Wraps a DOM element that renders the menu items. Must be rendered inside of a <Menu>.,Must be a direct child of a <MenuList>.,Wraps a DOM button that toggles the opening and closing of the dropdown menu. Must be rendered inside of a <Menu>.

function Example() {  return (    <Menu>      <MenuButton>        Actions <span aria-hidden></span>      </MenuButton>      <MenuList>        <MenuItem onSelect={() => alert("Download")}>Download</MenuItem>        <MenuItem onSelect={() => alert("Copy")}>Create a Copy</MenuItem>        <MenuItem onSelect={() => alert("Mark as Draft")}>          Mark as Draft        </MenuItem>        <MenuItem onSelect={() => alert("Delete")}>Delete</MenuItem>        <MenuLink as="a" href="https://reacttraining.com/workshops/">          Attend a Workshop        </MenuLink>      </MenuList>    </Menu>  );}
load more v
60%

The Menu enables you to override the default rendering of its items.,Override the rendering of the item link,Set the ids of the content items to the customCloseItemIds property of the Menu.

Pretag
render
load more v
48%

A menu item may contain another menu nested inside that acts as a grouped sub-menu.,A vertical menu displays elements vertically.,A menu can stack at mobile resolutions.

src / collections / Menu / Menu.js
23%

I decided to build my own simple hamburger with sidebar. No pickles, onions or ketchup. Just meat, bun, and a side of menu items.,Create a components folder inside the src directory and add two folders in there: Menu and Burger, plus an index.js file.,We set the initial state to false, because our menu should be hidden when the application is rendered.

Let’s spin up a new project using create-react-app, change to that folder directory and add styled-components to style the UI:

npx create - react - app your - project - name
cd your - project - name
yarn add styled - components

Open the newly created project in your favorite code editor and start adding basic styles using styled-components. In your src directory, create a file called global.js. It will contain styles for the whole app. You can write your own or just copy what I ended up doing:

// global.js
import {
   createGlobalStyle
} from 'styled-components';

export const GlobalStyles = createGlobalStyle`
  html, body {
    margin: 0;
    padding: 0;
  }
  *, *::after, *::before {
    box-sizing: border-box;
  }
  body {
    align-items: center;
    background: #0D0C1D;
    color: #EFFFFA;
    display: flex;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
    height: 100vh;
    justify-content: center;
    text-rendering: optimizeLegibility;
  }
  `

The next step is to add a theme file that holds all our variables. Create a theme.js file in the src directory and add following:

// theme.js
export const theme = {
   primaryDark: '#0D0C1D',
   primaryLight: '#EFFFFA',
   primaryHover: '#343078',
   mobile: '576px',
}

Go to your App.js file. We’re going to wipe everything out of there and create the main template for our app. Here’s what I did. You can certainly create your own.

// App.js
import React from 'react';
import { ThemeProvider } from 'styled-components';
import { GlobalStyles } from './global';
import { theme } from './theme';

function App() {
  return (
    <ThemeProvider theme={theme}>
      <>
        <GlobalStyles />
        <div>
          <h1>Hello. This is burger menu tutorial</h1>
          <img src="https://image.flaticon.com/icons/svg/2016/2016012.svg" alt="burger icon" />
          <small>Icon made by Freepik from www.flaticon.com</small>
        </div>
      </>
    </ThemeProvider>
  );
}
export default App;

Go to global.js and change the background and color properties to use our defined variables. This helps us implement a theme rather than using fixed values that are difficult to change.

// global.js
background: $ {
   ({
      theme
   }) => theme.primaryDark
};
color: $ {
   ({
      theme
   }) => theme.primaryLight
};

Go to the Burger folder and create Burger.js for our layout. Then add Burger.styled.js, which will contain styles, and index.js, which will be exporting the file.

// index.js
export {
   default
}
from './Burger';

Feel free to style burger toggle in a way you want, or just paste these styles:

// Burger.styled.js
import styled from 'styled-components';

export const StyledBurger = styled.button`
  position: absolute;
  top: 5%;
  left: 2rem;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  width: 2rem;
  height: 2rem;
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 0;
  z-index: 10;
  
  &:focus {
    outline: none;
  }
  
  div {
    width: 2rem;
    height: 0.25rem;
    background: ${({ theme }) => theme.primaryLight};
    border-radius: 10px;
    transition: all 0.3s linear;
    position: relative;
    transform-origin: 1px;
  }
`;

After adding the styles, go to Burger.js and add the layout:

// Burger.js
import React from 'react';
import { StyledBurger } from './Burger.styled';

const Burger = () => {
  return (
    <StyledBurger>
      <div />
      <div />
      <div />
    </StyledBurger>
  )
}

export default Burger;

Time to do the same with the Menu folder:

// Menu -> index.js
export {
   default
}
from './Menu';

// Menu.styled.js
import styled from 'styled-components';

export const StyledMenu = styled.nav`
  display: flex;
  flex-direction: column;
  justify-content: center;
  background: ${({ theme }) => theme.primaryLight};
  height: 100vh;
  text-align: left;
  padding: 2rem;
  position: absolute;
  top: 0;
  left: 0;
  transition: transform 0.3s ease-in-out;
  
  @media (max-width: ${({ theme }) => theme.mobile}) {
    width: 100%;
  }

  a {
    font-size: 2rem;
    text-transform: uppercase;
    padding: 2rem 0;
    font-weight: bold;
    letter-spacing: 0.5rem;
    color: ${({ theme }) => theme.primaryDark};
    text-decoration: none;
    transition: color 0.3s linear;
    
    @media (max-width: ${({ theme }) => theme.mobile}) {
      font-size: 1.5rem;
      text-align: center;
    }

    &:hover {
      color: ${({ theme }) => theme.primaryHover};
    }
  }
`;

Next, let’s add the layout for the menu items that are revealed when clicking on our burger:

// Menu.js
import React from 'react';
import { StyledMenu } from './Menu.styled';

const Menu = () => {
  return (
    <StyledMenu>
      <a href="/">
        <span role="img" aria-label="about us">&#x1f481;&#x1f3fb;&#x200d;&#x2642;&#xfe0f;</span>
        About us
      </a>
      <a href="/">
        <span role="img" aria-label="price">&#x1f4b8;</span>
        Pricing
        </a>
      <a href="/">
        <span role="img" aria-label="contact">&#x1f4e9;</span>
        Contact
        </a>
    </StyledMenu>
  )
}
export default Menu;

Time to import our new components into our App.js file:

// App.js
import React from 'react';
import {
   ThemeProvider
} from 'styled-components';
import {
   GlobalStyles
} from './global';
import {
   theme
} from './theme';
import {
   Burger,
   Menu
} from './components';

// ...

Take a look at this nice navigation bar! But we’ve got one issue here: it’s opened, and we want it initially to be closed. We only need to add one line to Menu.styled.js fix it:

// Menu.styled.js
transform: translateX(-100 % );

We want to open the sidebar when clicking the hamburger icon, so let’s get to it. Open App.js and add some state to it. We will use the useState hook for it.

// App.js
import React, {
   useState
} from 'react';

After you import it, let’s use it inside the App component.

// App.js
const [open, setOpen] = useState(false);

We need both our toggle and sidebar menu to know about the state, so pass it down as a prop to each component. Now your App.js should look something like this:

// App.js
import React, { useState } from 'react';
import { ThemeProvider } from 'styled-components';
import { GlobalStyles } from './global';
import { theme } from './theme';
import { Burger, Menu } from './components';

function App() {
  const [open, setOpen] = useState(false);
  return (
    <ThemeProvider theme={theme}>
      <>
        <GlobalStyles />
        <div>
          <h1>Hello. This is burger menu tutorial</h1>
          <img src="https://media.giphy.com/media/xTiTnwj1LUAw0RAfiU/giphy.gif" alt="animated burger" />
        </div>
        <div>
          <Burger open={open} setOpen={setOpen} />
          <Menu open={open} setOpen={setOpen} />
        </div>
      </>
    </ThemeProvider>
  );
}
export default App;

Our Burger and Menu know about the state, so all we need to do is to handle it inside and add styles accordingly. Go to Burger.js and handle the props that were passed down:

// Burger.js
import React from 'react';
import { bool, func } from 'prop-types';
import { StyledBurger } from './Burger.styled';
const Burger = ({ open, setOpen }) => {
  return (
    <StyledBurger open={open} onClick={() => setOpen(!open)}>
      <div />
      <div />
      <div />
    </StyledBurger>
  )
}
Burger.propTypes = {
  open: bool.isRequired,
  setOpen: func.isRequired,
};
export default Burger;

Go to Menu.js and do almost the same, although, here we pass only the open prop:

// Menu.js
import React from 'react';
import { bool } from 'prop-types';
import { StyledMenu } from './Menu.styled';
const Menu = ({ open }) => {
  return (
    <StyledMenu open={open}>
      <a href="/">
        <span role="img" aria-label="about us">&#x1f481;&#x1f3fb;&#x200d;&#x2642;&#xfe0f;</span>
        About us
      </a>
      <a href="/">
        <span role="img" aria-label="price">&#x1f4b8;</span>
        Pricing
        </a>
      <a href="/">
        <span role="img" aria-label="contact">&#x1f4e9;</span>
        Contact
        </a>
    </StyledMenu>
  )
}
Menu.propTypes = {
  open: bool.isRequired,
}
export default Menu;

Next step is to pass open prop down to our styled component so we could apply the transition. Open Menu.styled.js and add the following to our transform property:

transform: $ {
   ({
      open
   }) => open ? 'translateX(0)' : 'translateX(-100%)'
};

Open Burger.styled.js and write the following:

// Burger.styled.js
import styled from 'styled-components';
export const StyledBurger = styled.button`
  position: absolute;
  top: 5%;
  left: 2rem;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  width: 2rem;
  height: 2rem;
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 0;
  z-index: 10;

  &:focus {
    outline: none;
  }

  div {
    width: 2rem;
    height: 0.25rem;
    background: ${({ theme, open }) => open ? theme.primaryDark : theme.primaryLight};
    border-radius: 10px;
    transition: all 0.3s linear;
    position: relative;
    transform-origin: 1px;

    :first-child {
      transform: ${({ open }) => open ? 'rotate(45deg)' : 'rotate(0)'};
    }

    :nth-child(2) {
      opacity: ${({ open }) => open ? '0' : '1'};
      transform: ${({ open }) => open ? 'translateX(20px)' : 'translateX(0)'};
    }

    :nth-child(3) {
      transform: ${({ open }) => open ? 'rotate(-45deg)' : 'rotate(0)'};
    }
  }
`;

We’re going to put more React hooks to use to make this happen! Create a file in the src directory, called hooks.js and open it. For this one, we’re gonna turn to the useEffect hook, which was introduced in React 18.

// hooks.js
import {
   useEffect
} from 'react';

We are going to use ref to check the clicked element, and we will do so every time someone clicks on the page.

// hooks.js
import {
   useEffect
} from 'react';

export const useOnClickOutside = (ref, handler) => {
   useEffect(() => {
         const listener = event => {
            if (!ref.current || ref.current.contains(event.target)) {
               return;
            }
            handler(event);
         };
         document.addEventListener('mousedown', listener);
         return () => {
            document.removeEventListener('mousedown', listener);
         };
      },
      [ref, handler],
   );
};

We’ve got our hook ready, so it’s time to add it to the app. Go to the App.js file, and import two hooks: the newly created useOnClickOutside and also useRef. We’ll need the latter to get a reference to the element.

// App.js
import React, {
   useState,
   useRef
} from 'react';
import {
   useOnClickOutside
} from './hooks';

From there, we pass the node as a first argument. We’ll pass the function that closes our menu as a second argument.

// App.js
const node = useRef();
useOnClickOutside(node, () => setOpen(false));

Lastly, we need to pass our ref to the DOM element. In our case, it will be div, that holds the Burger and Menu components:

// App.js
<div ref={node}>
  <Burger open={open} setOpen={setOpen} />
  <Menu open={open} setOpen={setOpen} />
</div>

Your App.js should look similar to this:

// App.js
import React, { useState, useRef } from 'react';
import { ThemeProvider } from 'styled-components';
import { useOnClickOutside } from './hooks';
import { GlobalStyles } from './global';
import { theme } from './theme';
import { Burger, Menu } from './components';
function App() {
  const [open, setOpen] = useState(false);
  const node = useRef();
  useOnClickOutside(node, () => setOpen(false));
  return (
    <ThemeProvider theme={theme}>
      <>
        <GlobalStyles />
        <div>
          <h1>Hello. This is burger menu tutorial</h1>
          <img src="https://media.giphy.com/media/xTiTnwj1LUAw0RAfiU/giphy.gif" alt="animated burger" />
        </div>
        <div ref={node}>
          <Burger open={open} setOpen={setOpen} />
          <Menu open={open} setOpen={setOpen} />
        </div>
      </>
    </ThemeProvider>
  );
}
export default App;
load more v

Other "items-react" queries related to "How to get items out and inside of menu item in React?"