Skip to content

Instantly share code, notes, and snippets.

@HriBB
Last active April 26, 2018 22:13
Show Gist options
  • Save HriBB/65fabece72cd48b339d73eadfcc30498 to your computer and use it in GitHub Desktop.
Save HriBB/65fabece72cd48b339d73eadfcc30498 to your computer and use it in GitHub Desktop.
React confirmation dialog using new context API
// @flow
import React from 'react'
import { Button } from 'ui/button'
import { Dialog } from 'ui/dialog'
import { withHandlers } from 'recompose'
const { Provider, Consumer } = React.createContext({
isOpen: false,
open: () => {},
close: () => {},
})
const YesButton = withHandlers({
handleClick: ({ confirm: { data, close }, onClick }) => (e) => {
if (typeof onClick === 'function') {
onClick(data)
}
close()
}
})(({ children, confirm, onClick, handleClick, ...props }: any) => (
<Button {...props} onClick={handleClick}>
{children || 'Yes'}
</Button>
))
export class ConfirmProvider extends React.Component {
state = {
isOpen: false,
data: null,
}
static Dialog = ({ children, ...props }: any) => (
<Consumer>
{({ isOpen }) => (
<Dialog
{...props}
disableBackdropClick
disableEscapeKeyDown
maxWidth={'xs'}
open={isOpen}
>
{children}
</Dialog>
)}
</Consumer>
)
static YesButton = ({ children, ...props }: any) => (
<Consumer>
{(confirm) => (
<YesButton {...props} confirm={confirm}>
{children || 'Yes'}
</YesButton>
)}
</Consumer>
)
static NoButton = ({ children, ...props }: any) => (
<Consumer>
{(confirm) => (
<Button {...props} onClick={confirm.close}>
{children || 'No'}
</Button>
)}
</Consumer>
)
open = (data: any) => {
this.setState({ isOpen: true, data })
}
close = () => {
this.setState({ isOpen: false, data: null })
}
render() {
return (
<Provider value={{
isOpen: this.state.isOpen,
data: this.state.data,
open: this.open,
close: this.close,
}}>
{this.props.children}
</Provider>
)
}
}
export const ConfirmConsumer = Consumer
// @flow
import React, { Fragment } from 'react'
import { Link } from 'react-router-dom'
import MoreVertIcon from '@material-ui/icons/MoreVert'
import { DialogActions, DialogContent } from 'ui/dialog'
import { IconMenu, IconMenuItem } from 'ui/icon'
import { ConfirmProvider, ConfirmConsumer } from './Confirm'
const Options = ({ item, deleteItem }) => {
return (
<ConfirmProvider>
<ConfirmConsumer>
{(confirm) => (
<Fragment>
<IconMenu icon={<MoreVertIcon/>}>
<IconMenuItem component={Link} to={`/edit${item.id}`}>
Edit
</IconMenuItem>
<IconMenuItem onClick={confirm.open}>
Delete
</IconMenuItem>
</IconMenu>
<ConfirmProvider.Dialog>
<DialogContent>
Are you sure you want to do that?
</DialogContent>
<DialogActions>
<ConfirmProvider.NoButton color={'primary'}>
No
</ConfirmProvider.NoButton>
<ConfirmProvider.YesButton onClick={props.deleteItem} color={'primary'}>
Yes
</ConfirmProvider.YesButton>
</DialogActions>
</ConfirmProvider.Dialog>
</Fragment>
)}
</ConfirmConsumer>
</ConfirmProvider>
)
}
export default withHandlers({
deleteItem: (props) => (data) => {
console.log('deleteItem', data)
}
)(Options)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment