Tuesday, March 14, 2023
HomeReactReact Dropdown for Materials UI (MUI)

React Dropdown for Materials UI (MUI)


Materials UI for React, additionally referred to as MUI, doesn’t include a local Dropdown part. Right here I wish to share the dropdown part that I’ve used for a number of of my freelance initiatives when utilizing Materials UI. Earlier than you need to use it, it’s a must to set up its Materials UI (MUI) dependencies:

npm set up @emotion/styled @mui/materials @mui/icons-material

Subsequent follows the implementation of a Materials UI Dropdown Part:

import * as React from 'react';

import styled from '@emotion/styled';

import Menu from '@mui/materials/Menu';

import MenuItem from '@mui/materials/MenuItem';

export const Dropdown = React.forwardRef(

(

{

set off,

menu,

keepOpen: keepOpenGlobal,

isOpen: controlledIsOpen,

onOpen: onControlledOpen,

minWidth,

},

ref

) => {

const [isInternalOpen, setInternalOpen] = React.useState(null);

const isOpen = controlledIsOpen || isInternalOpen;

let anchorRef = React.useRef(null);

if (ref) {

anchorRef = ref;

}

const handleOpen = (occasion) => {

occasion.stopPropagation();

if (menu.size) {

onControlledOpen

? onControlledOpen(occasion.currentTarget)

: setInternalOpen(occasion.currentTarget);

}

};

const handleClose = (occasion) => {

occasion.stopPropagation();

if (

anchorRef.present &&

anchorRef.present.comprises(occasion.goal)

) {

return;

}

handleForceClose();

};

const handleForceClose = () => {

onControlledOpen

? onControlledOpen(null)

: setInternalOpen(null);

};

const renderMenu = (menuItem, index) => {

const { keepOpen: keepOpenLocal, ...props } = menuItem.props;

let extraProps = {};

if (props.menu) {

extraProps = {

parentMenuOpen: isOpen,

};

}

return React.createElement(menuItem.kind, {

...props,

key: index,

...extraProps,

onClick: (occasion) => {

occasion.stopPropagation();

if (!keepOpenGlobal && !keepOpenLocal) {

handleClose(occasion);

}

if (menuItem.props.onClick) {

menuItem.props.onClick(occasion);

}

},

kids: props.menu

? React.Youngsters.map(props.menu, renderMenu)

: props.kids,

});

};

return (

<>

{React.cloneElement(set off, {

onClick: isOpen ? handleForceClose : handleOpen,

ref: anchorRef,

})}

<Menu

PaperProps={{ sx: { minWidth: minWidth ?? 0 } }}

anchorEl={isOpen}

open={!!isOpen}

onClose={handleClose}

>

{React.Youngsters.map(menu, renderMenu)}

</Menu>

</>

);

}

);

export const DropdownMenuItem = styled(MenuItem)`

show: flex;

justify-content: space-between !necessary;

& > svg {

margin-left: 32px;

}

`;

The utilization of the MUI Dropdown compopnent appears to be like as follows:

import * as React from 'react';

import Button from '@mui/materials/Button';

import AddCircleOutlinedIcon from '@mui/icons-material/AddCircleOutlined';

import EditIcon from '@mui/icons-material/Edit';

import DeleteForeverIcon from '@mui/icons-material/DeleteForever';

import { Dropdown, DropdownMenuItem } from './dropdown';

const App = () => {

const handleCreate = () => {

console.log('create one thing');

};

const handleEdit = () => {

console.log('edit one thing');

};

const handleDelete = () => {

console.log('delete one thing');

};

return (

<Dropdown

keepOpen

open={open}

set off={<Button>Dropdown</Button>}

menu={[

<DropdownMenuItem onClick={handleCreate}>

Create <AddCircleOutlinedIcon />

</DropdownMenuItem>,

<DropdownMenuItem onClick={handleEdit}>

Edit <EditIcon />

</DropdownMenuItem>,

<DropdownMenuItem onClick={handleDelete}>

Delete <DeleteForeverIcon />

</DropdownMenuItem>,

]}

/>

);

};

export default App;

If you wish to get to know a little bit of the underlying implementation particulars:

If you wish to get a nested dropdown menu for this dropdown part:

Optionally you need to use the keepOpen property to not shut the dropdown if one among its menu merchandise’s is clicked and the minWidth property to outline a width for the dropdown’s menu. If you wish to flip the dropdown part right into a , you possibly can cross it isOpen and onOpen props too.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments