diff --git a/docs/src/app/components/pages/components/dialog.jsx b/docs/src/app/components/pages/components/dialog.jsx index 2ef62cc95b6f15..c083255c48359e 100644 --- a/docs/src/app/components/pages/components/dialog.jsx +++ b/docs/src/app/components/pages/components/dialog.jsx @@ -11,6 +11,9 @@ export default class DialogPage extends React.Component { super(); this.state = { modal: false, + showDialogStandardActions: false, + showDialogCustomActions: false, + showDialogScrollable: false, }; this._handleCustomDialogCancel = this._handleCustomDialogCancel.bind(this); this._handleCustomDialogSubmit = this._handleCustomDialogSubmit.bind(this); @@ -19,6 +22,7 @@ export default class DialogPage extends React.Component { this._handleCustomDialogTouchTap = this._handleCustomDialogTouchTap.bind(this); this._handleStandardDialogTouchTap = this._handleStandardDialogTouchTap.bind(this); this._handleScrollableDialogTouchTap = this._handleScrollableDialogTouchTap.bind(this); + this._handleRequestClose = this._handleRequestClose.bind(this); this._handleToggleChange = this._handleToggleChange.bind(this); } @@ -69,8 +73,20 @@ export default class DialogPage extends React.Component { name: 'openImmediately', type: 'bool', header: 'default: false', + desc: 'Deprecated: Set to true to have the dialog automatically open on mount.', + }, + { + name: 'defaultIsOpen', + type: 'bool', + header: 'default: false', desc: 'Set to true to have the dialog automatically open on mount.', }, + { + name: 'isOpen', + type: 'bool', + header: 'default: null', + desc: 'Controls whether the Dialog is opened or not.', + }, { name: 'title', type: 'node', @@ -95,16 +111,6 @@ export default class DialogPage extends React.Component { { name: 'Methods', infoArray: [ - { - name: 'dismiss', - header: 'Dialog.dismiss()', - desc: 'Hides the dialog.', - }, - { - name: 'show', - header: 'Dialog.show()', - desc: 'Shows the dialog.', - }, { name: 'isOpen', header: 'Dialog.isOpen()', @@ -116,14 +122,9 @@ export default class DialogPage extends React.Component { name: 'Events', infoArray: [ { - name: 'onDismiss', - header: 'function()', - desc: 'Fired when the dialog is dismissed.', - }, - { - name: 'onShow', - header: 'function()', - desc: 'Fired when the dialog is shown.', + name: 'onRequestClose', + header: 'function(buttonClicked)', + desc: 'Fired when the dialog is requested to be closed by a click outside the dialog or on the buttons.', }, ], }, @@ -175,7 +176,8 @@ export default class DialogPage extends React.Component { title="Dialog With Standard Actions" actions={standardActions} actionFocus="submit" - modal={this.state.modal}> + isOpen={this.state.showDialogStandardActions} + onRequestClose={this._handleRequestClose}> The actions in this window are created from the json that's passed in. @@ -183,7 +185,8 @@ export default class DialogPage extends React.Component { ref="customDialog" title="Dialog With Custom Actions" actions={customActions} - modal={this.state.modal}> + isOpen={this.state.showDialogCustomActions} + onRequestClose={this._handleRequestClose}> The actions in this window were passed in as an array of react objects.
@@ -196,9 +199,10 @@ export default class DialogPage extends React.Component { ref="scrollableContentDialog" title="Dialog With Scrollable Content" actions={scrollableCustomActions} - modal={this.state.modal} autoDetectWindowHeight={true} - autoScrollBodyContent={true}> + autoScrollBodyContent={true} + isOpen={this.state.showDialogScrollable} + onRequestClose={this._handleRequestClose}>
Really long content
@@ -214,11 +218,15 @@ export default class DialogPage extends React.Component { } _handleCustomDialogCancel() { - this.refs.customDialog.dismiss(); + this.setState({ + showDialogCustomActions: true, + }); } _handleCustomDialogSubmit() { - this.refs.customDialog.dismiss(); + this.setState({ + showDialogCustomActions: true, + }); } _handleToggleChange(e, toggled) { @@ -226,23 +234,42 @@ export default class DialogPage extends React.Component { } _handleScrollableDialogCancel() { - this.refs.scrollableContentDialog.dismiss(); + this.setState({ + showDialogScrollable: false, + }); } _handleScrollableDialogSubmit() { - this.refs.scrollableContentDialog.dismiss(); + this.setState({ + showDialogScrollable: false, + }); } _handleCustomDialogTouchTap() { - this.refs.customDialog.show(); + this.setState({ + showDialogScrollable: true, + }); } _handleStandardDialogTouchTap() { - this.refs.standardDialog.show(); + this.setState({ + showDialogStandardActions: true, + }); } _handleScrollableDialogTouchTap() { - this.refs.scrollableContentDialog.show(); + this.setState({ + showDialogScrollable: true, + }); + } + + _handleRequestClose(buttonClicked) { + if (!buttonClicked && this.state.modal) return; + this.setState({ + showDialogStandardActions: false, + showDialogCustomActions: false, + showDialogScrollable: false, + }); } } diff --git a/docs/src/app/components/raw-code/dialog-code.txt b/docs/src/app/components/raw-code/dialog-code.txt index ee89651d477e41..f55befb1450e41 100644 --- a/docs/src/app/components/raw-code/dialog-code.txt +++ b/docs/src/app/components/raw-code/dialog-code.txt @@ -8,7 +8,8 @@ let standardActions = [ title="Dialog With Standard Actions" actions={standardActions} actionFocus="submit" - modal={this.state.modal}> + isOpen={this.state.showDialogStandardActions} + onRequestClose={this._handleRequestClose}> The actions in this window are created from the json that's passed in. @@ -27,11 +28,19 @@ let customActions = [ + isOpen={this.state.showDialogCustomActions} + onRequestClose={this._handleRequestClose}> The actions in this window were passed in as an array of react objects. - -
Really long content
-
+ +
+ Really long content +
+
\ No newline at end of file diff --git a/src/dialog.jsx b/src/dialog.jsx index 77ee8650c49c27..e0823f6b2dcdfa 100644 --- a/src/dialog.jsx +++ b/src/dialog.jsx @@ -109,13 +109,12 @@ let Dialog = React.createClass({ bodyStyle: React.PropTypes.object, contentClassName: React.PropTypes.string, contentStyle: React.PropTypes.object, - modal: React.PropTypes.bool, openImmediately: React.PropTypes.bool, onClickAway: React.PropTypes.func, - onDismiss: React.PropTypes.func, - onShow: React.PropTypes.func, repositionOnUpdate: React.PropTypes.bool, title: React.PropTypes.node, + defaultIsOpen: React.PropTypes.bool, + isOpen: React.PropTypes.bool, }, windowListeners: { @@ -128,14 +127,20 @@ let Dialog = React.createClass({ autoDetectWindowHeight: false, autoScrollBodyContent: false, actions: [], - modal: false, repositionOnUpdate: true, + defaultIsOpen: false, + isOpen: null, }; }, getInitialState() { + let open = this.props.isOpen; + + if (open === null) + open = (this.props.openImmediately || this.props.defaultIsOpen); + return { - open: this.props.openImmediately || false, + open: open, muiTheme: this.context.muiTheme ? this.context.muiTheme : ThemeManager.getMuiTheme(DefaultRawTheme), }; }, @@ -145,13 +150,19 @@ let Dialog = React.createClass({ componentWillReceiveProps (nextProps, nextContext) { let newMuiTheme = nextContext.muiTheme ? nextContext.muiTheme : this.state.muiTheme; this.setState({muiTheme: newMuiTheme}); + + if (nextProps.isOpen !== this.props.isOpen) { + if (nextProps.isOpen && !this.state.open) + this._show(); + else if (!nextProps.isOpen && this.state.open) + this._dismiss(); + } }, componentDidMount() { this._positionDialog(); - if (this.props.openImmediately) { + if (this.isOpen()) { this.refs.dialogOverlay.preventScrolling(); - this._onShow(); } }, @@ -265,20 +276,6 @@ let Dialog = React.createClass({ return this.state.open; }, - dismiss() { - CssEvent.onTransitionEnd(ReactDOM.findDOMNode(this), () => { - this.refs.dialogOverlay.allowScrolling(); - }); - - this.setState({ open: false }); - this._onDismiss(); - }, - - show() { - this.refs.dialogOverlay.preventScrolling(); - this.setState({ open: true }, this._onShow); - }, - _getAction(actionJSON, key) { let styles = {marginRight: 8}; let props = { @@ -290,7 +287,7 @@ let Dialog = React.createClass({ actionJSON.onTouchTap.call(undefined); } if (!(actionJSON.onClick || actionJSON.onTouchTap)) { - this.dismiss(); + this._requestClose(true); } }, label: actionJSON.text, @@ -379,27 +376,32 @@ let Dialog = React.createClass({ } }, - _onShow() { - if (this.props.onShow) this.props.onShow(); + _show() { + this.refs.dialogOverlay.preventScrolling(); + this.setState({ open: true }); + }, + + _dismiss() { + CssEvent.onTransitionEnd(ReactDOM.findDOMNode(this), () => { + this.refs.dialogOverlay.allowScrolling(); + }); + + this.setState({ open: false }); }, - _onDismiss() { - if (this.props.onDismiss) this.props.onDismiss(); + _requestClose(buttonClicked) { + // Close the dialog if the isOpen state is not explicitly set. + if (this.props.isOpen === null) this._dismiss(); + if (this.props.onRequestClose) this.props.onRequestClose(!!buttonClicked); }, _handleOverlayTouchTap(e) { - if (this.props.modal) { - e.stopPropagation(); - } - else { - this.dismiss(); - if (this.props.onClickAway) this.props.onClickAway(); - } + this._requestClose(false); }, _handleWindowKeyUp(e) { - if (e.keyCode === KeyCode.ESC && !this.props.modal) { - this.dismiss(); + if (e.keyCode === KeyCode.ESC) { + this._requestClose(false); } },