Last active
April 26, 2018 22:13
-
-
Save HriBB/65fabece72cd48b339d73eadfcc30498 to your computer and use it in GitHub Desktop.
React confirmation dialog using new context API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @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