Skip to content

Commit

Permalink
[Dialog] Switch from imperative control to props.
Browse files Browse the repository at this point in the history
- Remove .dismiss() and .show()
- Remove onShow and onDismiss callback
- Added onRequestClose callback
- Removed modal property
- Updated docs
- Add default values for defaultIsOpen and isOpen.
  • Loading branch information
JorgenEvens committed Nov 4, 2015
1 parent dfb8363 commit 8050f49
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 70 deletions.
85 changes: 56 additions & 29 deletions docs/src/app/components/pages/components/dialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
}

Expand Down Expand Up @@ -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',
Expand All @@ -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()',
Expand All @@ -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.',
},
],
},
Expand Down Expand Up @@ -175,15 +176,17 @@ 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.
</Dialog>

<Dialog
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.
</Dialog>
<div style={{width: '300px', margin: '0 auto', paddingTop: '20px'}}>
Expand All @@ -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}>
<div style={{height: '1000px'}}>
Really long content
</div>
Expand All @@ -214,35 +218,58 @@ 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) {
this.setState({modal: toggled});
}

_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,
});
}

}
21 changes: 15 additions & 6 deletions docs/src/app/components/raw-code/dialog-code.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
</Dialog>

Expand All @@ -27,11 +28,19 @@ let customActions = [
<Dialog
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.
</Dialog>

<Dialog title="Dialog With Scrollable Content" actions={customActions}
autoDetectWindowHeight={true} autoScrollBodyContent={true}>
<div style={{height: '2000px'}}>Really long content</div>
</Dialog>
<Dialog
title="Dialog With Scrollable Content"
actions={customActions}
autoDetectWindowHeight={true}
autoScrollBodyContent={true}
isOpen={this.state.showDialogScrollable}
onRequestClose={this._handleRequestClose}>
<div style={{height: '1000px'}}>
Really long content
</div>
</Dialog>
72 changes: 37 additions & 35 deletions src/dialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand All @@ -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),
};
},
Expand All @@ -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();
}
},

Expand Down Expand Up @@ -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 = {
Expand All @@ -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,
Expand Down Expand Up @@ -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);
}
},

Expand Down

0 comments on commit 8050f49

Please sign in to comment.