All files / src/components SDDialog.react.js

93.33% Statements 14/15
50% Branches 2/4
83.33% Functions 5/6
93.33% Lines 14/15
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107                                        1x                                                                   1x                     2x 2x       2x 2x       2x   2x 2x     2x       4x   4x                                 1x 1x  
// @flow
 
import React, { Component } from 'react';
import PropTypes from 'prop-types';
 
import Dialog from 'material-ui/Dialog';
import lightBaseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
 
type Props = {
  id: string,
  actions?: Node,
  children?: Node,
  className?: string,
  modal?: boolean,
  open?: boolean,
  setProps?: (props: { modal?: boolean, open?: boolean }) => void,
};
 
const propTypes = {
  /** Dialog ID */
  id: PropTypes.string.isRequired,
 
  /** Actions component or list of components for the Dialog */
  actions: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)]),
 
  /**
   * The css class name of the root element.
   */
  className: PropTypes.string,
 
  /** Is the Dialog a modal (must click on an action to close the Dialog)? */
  modal: PropTypes.bool,
 
  /** Is the dialog open?
 * IMPORTANT: When using this component in Dash, a listener must be set up (either as state or
 * an input) for this component's props.open value in order to achieve the desired behavior.
 * If such a listener is not in place, the non-modal version of this dialog will contaminate
 * other callbacks in the browser
 */
  open: PropTypes.bool,
 
  /** Dash callback to update props on the server */
  setProps: PropTypes.func,
 
  /** children of the Dialog */
  children: PropTypes.node,
};
 
type State = {
  open: boolean,
};
 
const defaultProps = {
  actions: null,
  children: null,
  className: '',
  open: false,
  modal: false,
  setProps: () => {},
};
 
export default class SDDialog extends Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = {open: props.open};
  }
 
  componentWillReceiveProps(nextProps: Props): void {
    Eif (nextProps.open !== this.state.open)
      this.changeDialogOpenStatus(nextProps.open);
  }
 
  changeDialogOpenStatus = (open: boolean): void => {
    const { setProps } = this.props;
 
    Eif (typeof setProps === 'function') {
      setProps({open});
    }
 
    this.setState({open});
  };
 
  render() {
    const { id, className, modal, actions } = this.props;
 
    return (
      <div id={id} className="sd-dialog">
        <MuiThemeProvider muiTheme={getMuiTheme(lightBaseTheme)}>
          <Dialog
            actions={actions}
            className={className}
            modal={modal}
            open={this.state.open}
            onRequestClose={() => { this.changeDialogOpenStatus(false); }}
          >
            {this.props.children}
          </Dialog>
        </MuiThemeProvider>
      </div>);
  }
}
 
SDDialog.propTypes = propTypes;
SDDialog.defaultProps = defaultProps;