Skip to content

Instantly share code, notes, and snippets.

@bennidhamma
Created March 6, 2018 00:50
Show Gist options
  • Save bennidhamma/6c54e851555d01071af73d38b1de7e13 to your computer and use it in GitHub Desktop.
Save bennidhamma/6c54e851555d01071af73d38b1de7e13 to your computer and use it in GitHub Desktop.
import PropTypes from 'prop-types'
import { withStyles } from 'material-ui/styles'
import React, { Component } from 'react'
import Paper from 'material-ui/Paper'
import Collapse from 'material-ui/transitions/Collapse'
import { MenuList } from 'material-ui/Menu'
import { Manager, Target, Popper } from 'react-popper'
import Portal from 'material-ui/Portal';
import ClickAwayListener from 'material-ui/utils/ClickAwayListener'
const styles = {
paper: {
margin: 3,
}
}
class SimpleMenu extends Component {
static propTypes = {
target: PropTypes.func.isRequired,
placement: PropTypes.string,
}
static defaultProps = {
placement: "bottom-start",
target: () => {},
}
constructor(props) {
super(props)
this.state = {
open: false,
}
}
toggleOpen = e => {
this.setState({ open: !this.state.open })
}
close = e => {
if (this.targetEl.contains(e.target)) {
return
}
this.setState({ open: false })
}
render() {
const {
target,
placement,
children,
className,
classes,
} = this.props
const { open } = this.state
return (<Manager className={className}>
<Target>
<div ref={el => this.targetEl = el}>
{target({ toggleOpen: this.toggleOpen, open })}
</div>
</Target>
<Portal>
<Popper
placement={placement}
eventsEnabled={open}
>
<ClickAwayListener onClickAway={this.close}>
<Collapse in={open} id="menu-list" style={{ transformOrigin: '0 0 0' }}>
<Paper className={classes.paper}>
<MenuList>
{children}
</MenuList>
</Paper>
</Collapse>
</ClickAwayListener>
</Popper>
</Portal>
</Manager>)
}
}
export default withStyles(styles)(SimpleMenu)
import SimpleMenu from './SimpleMenu'
import Button from 'material-ui/Button'
import MenuDown from 'theme/svg/menu-down.svg'
import MenuUp from 'theme/svg/menu-up.svg'
export default () => <SimpleMenu
target={({toggleOpen, open}) => <Button onClick={toggleOpen}>{open ? <MenuUp/> : <MenuDown>}</Button>}
>
<MenuItem>Item 1</MenuItem>
<MenuItem>Item 2</MenuItem>
<MenuItem>Item 3</MenuItem>
</SimpleMenu>
@bennidhamma
Copy link
Author

Note: Collapse works better than Grow because the menu is still being fully rendered, invisibly, and interferes with pointer interactions. Collapse has the pleasing effect of not consuming any space in the viewport to hijack pointer events with.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment