diff --git a/src/components/Confirm.react.js b/src/components/ConfirmDialog.react.js similarity index 89% rename from src/components/Confirm.react.js rename to src/components/ConfirmDialog.react.js index f1bea40e7..035748d4c 100644 --- a/src/components/Confirm.react.js +++ b/src/components/ConfirmDialog.react.js @@ -2,9 +2,9 @@ import PropTypes from 'prop-types'; import {Component} from 'react'; /** - * Confirm wraps window.confirm + * ConfirmDialog wraps window.confirm */ -export default class Confirm extends Component { +export default class ConfirmDialog extends Component { constructor(props) { super(props); @@ -30,18 +30,14 @@ export default class Confirm extends Component { } } -Confirm.defaultProps = { - result: { - timestamp: -1 - }, - call_on_cancel: false, +ConfirmDialog.defaultProps = { n_clicks: 0, n_clicks_timestamp: -1, submit_n_clicks: 0, cancel_n_clicks: 0, }; -Confirm.propTypes = { +ConfirmDialog.propTypes = { id: PropTypes.string, /** diff --git a/src/components/ConfirmDialogProvider.react.js b/src/components/ConfirmDialogProvider.react.js new file mode 100644 index 000000000..d0320a49f --- /dev/null +++ b/src/components/ConfirmDialogProvider.react.js @@ -0,0 +1,81 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import ConfirmDialog from './ConfirmDialog.react' + + + +/** + * Wrap children onClick to send a confirmation dialog. + */ +export default class ConfirmDialogProvider extends React.Component { + render() { + const { id, setProps, children } = this.props; + + // Will lose the previous onClick of the child + const wrapClick = (child) => React.cloneElement(child, {onClick: () => + { + setProps({ + send_confirm: true + }); + } + }); + + const realChild = children.props ? children.props.children : children; + + return ( +
+ {realChild && realChild.length ? realChild.map(wrapClick) : + wrapClick(children.props.children)} + +
+ ) + } +}; + +ConfirmDialogProvider.defaultProps = { + n_clicks: 0, + n_clicks_timestamp: -1, + submit_n_clicks: 0, + cancel_n_clicks: 0, +}; + +ConfirmDialogProvider.propTypes = { + id: PropTypes.string, + + /** + * Message to show in the popup. + */ + message: PropTypes.string, + + /** + * Number of times the modal was submited or canceled. + */ + n_clicks: PropTypes.number, + /** + * Last timestamp the popup was clicked. + */ + n_clicks_timestamp: PropTypes.number, + /** + * Number of times the submit was clicked + */ + submit_n_clicks: PropTypes.number, + /** + * Number of times the popup was canceled. + */ + cancel_n_clicks: PropTypes.number, + /** + * Set to true to send the popup. + */ + send_confirm: PropTypes.bool, + /** + * Is the modal currently displayed. + */ + displayed: PropTypes.bool, + + /** + * Dash-assigned callback that gets fired when the value changes. + */ + setProps: PropTypes.func, + children: PropTypes.any, +}; diff --git a/src/index.js b/src/index.js index 329ad80f5..3afea0a19 100644 --- a/src/index.js +++ b/src/index.js @@ -15,11 +15,13 @@ import Textarea from './components/Textarea.react'; import DatePickerSingle from './components/DatePickerSingle.react'; import DatePickerRange from './components/DatePickerRange.react'; import Upload from './components/Upload.react'; -import Confirm from './components/Confirm.react'; +import ConfirmDialog from './components/ConfirmDialog.react'; +import ConfirmDialogProvider from './components/ConfirmDialogProvider.react' export { Checklist, - Confirm, + ConfirmDialog, + ConfirmDialogProvider, Dropdown, Graph, Input, diff --git a/test/test_integration.py b/test/test_integration.py index c51366ee3..d8b4a0aba 100644 --- a/test/test_integration.py +++ b/test/test_integration.py @@ -534,7 +534,7 @@ def test_confirm(self): app.layout = html.Div([ html.Button(id='button', children='Send confirm', n_clicks=0), - dcc.Confirm(id='confirm', message='Please confirm.'), + dcc.ConfirmDialog(id='confirm', message='Please confirm.'), html.Div(id='confirmed') ]) @@ -553,7 +553,6 @@ def on_confirmed(n_clicks, submit_n_clicks, cancel_n_clicks): elif n_clicks == 2: return 'canceled' - self.startServer(app) button = self.wait_for_element_by_css_selector('#button') self.snapshot('confirmation -> initial')