Skip to content

Instantly share code, notes, and snippets.

@maruware
Created February 7, 2018 03:54
Show Gist options
  • Save maruware/ab228f76d26f111957eab25f59eb5198 to your computer and use it in GitHub Desktop.
Save maruware/ab228f76d26f111957eab25f59eb5198 to your computer and use it in GitHub Desktop.
Material-UI SpeedDial Example
import AddIcon from 'material-ui-icons/Add'
import PersonAddIcon from 'material-ui-icons/PersonAdd'
import GroupAddIcon from 'material-ui-icons/GroupAdd'
import StarsIcon from 'material-ui-icons/Stars'
import SpeedDial, {SpeedDialItem} from './SpeedDial'
export default (props) => {
return (
<div>
<h1>Sample</h1>
<SpeedDial
color="accent"
label="New person"
defaultIcon={<AddIcon/>}
openedIcon={<PersonAddIcon/>}
onClick={e => console.log('clicked')}
>
<SpeedDialItem
color="accent"
label="Something"
icon={<StarsIcon/>}
onClick={e => console.log('clicked')}
/>
<SpeedDialItem
color="accent"
label="New group"
icon={<GroupAddIcon/>}
onClick={e => console.log('clicked')}
/>
</SpeedDial>
</div>
)
}
import React, {Component} from 'react'
import classNames from 'classnames'
import Button from 'material-ui/Button'
import Tooltip from 'material-ui/Tooltip'
import { withStyles } from 'material-ui/styles'
const actionMargin = 20
const actionSize = 40
const styles = theme => ({
action: {
marginBottom: actionMargin,
left: (56 - 40) / 2,
position: 'relative'
},
actionButton: {
width: actionSize,
height: actionSize,
transition: 'transform 0.2s ease-in-out'
},
actionButtonClosed: {
transform: 'scale(0, 0)'
},
container: {
flip: false,
position: 'fixed',
bottom: 32,
right: 32,
textAlign: 'center'
},
mainButtonIcon: {
position: 'absolute',
transition: 'transform 0.2s ease-in-out, visibility 0.2s ease-in-out'
},
mainButtonNormalIconOpened: {
visibility: 'hidden',
transform: 'rotate(90deg)'
},
mainButtonOpenedIconClosed: {
visibility: 'hidden',
transform: 'rotate(-90deg)'
},
actions: {
position: 'absolute'
},
actionsClosed: {
transition: 'top 0s linear 0.2s'
},
tooltip: {
width: 100
}
})
class SpeedDial extends Component {
constructor (props) {
super(props)
this.state = {
open: false
}
}
openItems () {
this.setState({open: true})
}
closeItems () {
this.setState({open: false})
}
render () {
const {classes, children, color, label, defaultIcon, openedIcon} = this.props
const {onClick} = this.props
const {open} = this.state
const actionButtons = React.Children.map(children, (child, index) => {
const delay = (30 * (open ? (children.length - index) : index))
return (
<div className={classes.action}>
{React.cloneElement(child, {
classes,
open,
placement: 'left',
style: {transitionDelay: delay + 'ms'}
})}
</div>
)
})
return (
<div
className={classes.container}
onMouseLeave={this.closeItems.bind(this)}
>
<div
className={classNames(classes.actions, !open ? classes.actionsClosed : null) }
style={{top: open ? `${actionButtons.length * -(actionSize + actionMargin)}px` : '100px'}}
>
{actionButtons}
</div>
<Tooltip
title={label}
placement="left"
classes={{
tooltip: classes.tooltip
}}
>
<Button
fab color={color || 'accent'}
onMouseEnter={this.openItems.bind(this)}
onClick={onClick}
>
{React.cloneElement(defaultIcon, {className: classNames(classes.mainButtonIcon, open ? classes.mainButtonNormalIconOpened : null)})}
{React.cloneElement(openedIcon, {className: classNames(classes.mainButtonIcon, (!open) ? classes.mainButtonOpenedIconClosed : null)})}
</Button>
</Tooltip>
</div>
)
}
}
export default withStyles(styles)(SpeedDial)
import React from 'react'
import classNames from 'classnames'
import Button from 'material-ui/Button'
import Tooltip from 'material-ui/Tooltip'
const SpeedDialItem = ({classes, color, label, icon, onClick, open, ...rest}) => {
return (
<Tooltip
title={label}
classes={{tooltip: classes.tooltip}}
{...rest}
>
<Button
fab color={color}
className={classNames(classes.actionButton, (!open) && classes.actionButtonClosed)}
onClick={onClick}
>
{icon}
</Button>
</Tooltip>
)
}
export default SpeedDialItem
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment