Learn more  » Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

lnguyenacl / acl-ui   js

Repository URL to install this package:

Version: 3.0.0 

/ components / Modal / Modal.js

'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

const warnings = {
  missingTitle: 'Default Title Text',
  missingContent: 'Add some children to your component'
};

// config for the panel sizes
const widthOptions = {
  small: 'acl-modal--size-small',
  oneThird: 'acl-modal--size-one-third',
  half: 'acl-modal--size-half',
  threeQuarters: 'acl-modal--size-three-quarters',
  maximum: 'acl-modal--size-max'
};

class Modal extends _react.Component {

  constructor(props) {
    super(props);
    this.modalContainer = null;
    this.observers();
    this.state = {
      open: this.props.open
    };
  }
  // Component lifecycle
  componentDidMount() {
    this.modalContainer = document.createElement('div');
    const id = `modal_${ new Date().getUTCMilliseconds() }`;
    this.modalContainer.setAttribute('key', id); // React
    this.modalContainer.setAttribute('id', id); // Dom
    document.body.appendChild(this.modalContainer);
    this.renderModal();
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.open !== nextProps.open) {
      this.setState({ open: nextProps.open }, () => {
        this.renderModal();
      });
    }
  }

  componentWillUnmount() {
    this.destroy();
  }

  onKeyUpEsc(event) {
    // esc key
    if (event.keyCode === 27) {
      this.close();
    }
  }

  observers() {
    document.addEventListener('keyup', this.onKeyUpEsc.bind(this), false);
  }

  // Methods
  open() {
    // there should be a className for this?
    const openStyle = 'display:block; visibility:visible';
    this.modal.setAttribute('style', openStyle);
    this.overlay.setAttribute('style', openStyle);
    this.props.onOpen();
    this.setState({ open: true });
  }

  close() {
    const hideStyle = 'display:none; visibility:hidden';
    this.modal.setAttribute('style', hideStyle);
    this.overlay.setAttribute('style', hideStyle);
    this.props.onClose();
    this.setState({ open: false });
  }

  toggle() {
    if (this.modal.hasAttribute('display', 'block')) {
      this.open();
      this.props.onOpen();
    } else {
      this.close();
      this.props.onClose();
    }
  }

  destroy() {
    if (this.modalContainer) {
      this.setState({ open: false });
      document.body.removeChild(this.modalContainer);
    }
  }

  renderModal() {
    _reactDom2.default.render(_react2.default.createElement(
      'div',
      null,
      _react2.default.createElement('div', { className: this.props.overlayClassName, onClick: () => this.close() }),
      _react2.default.createElement(
        'div',
        { className: this.props.modalClassName },
        this.props.children
      )
    ), this.modalContainer);

    this.modal = this.modalContainer.querySelector(`.${ this.props.modalClassName }`);
    this.overlay = this.modalContainer.querySelector(`.${ this.props.overlayClassName }`);

    if (this.state.open) {
      this.open();
    } else {
      this.close();
    }
  }

  render() {
    // create a portal we want to append the modal at the root of the document
    // and stop the rendering from this component
    // https://youtu.be/WGjv-p9jYf0?t=9m44s
    return null;
  }
}

Modal.propTypes = {
  /**
   * The content for the Modal
   */
  children: _react.PropTypes.node,

  /**
   * Modify the width of the panel
   */
  // extracting the accept values for the sizes property.
  width: _react.PropTypes.oneOf(Object.keys(widthOptions).map(key => key)),

  /**
   * Class name of the modal
   */
  modalClassName: _react.PropTypes.string,

  /**
   * Class name of layout
   */
  overlayClassName: _react.PropTypes.string,

  /**
   * Controls the visibility of the modal
   */
  open: _react.PropTypes.bool,

  /**
   * Controls the visibility of the close button (top right corner)
   */
  hasCloseButton: _react.PropTypes.bool,

  /**
   * Disable the displaying of the overlay
   */
  hasOverlay: _react.PropTypes.bool,

  /**
   * Disable the event of key up "esc"
   */
  closeOnEscKeyDown: _react.PropTypes.bool,

  /**
   * Disable the click event for the overlay
   */
  clickableOverlay: _react.PropTypes.bool,

  /**
   * Callback onOpen event
   */
  onOpen: _react.PropTypes.func,

  /**
   * Callback onClose event
   */
  onClose: _react.PropTypes.func,

  /**
   * Callback for onCancel click event
   */
  onCancel: _react.PropTypes.func,

  /**
   * Callback for onAccept click event
   */
  onAccept: _react.PropTypes.func
};
Modal.defaultProps = {
  children: warnings.missingContent,
  width: 'half',
  modalClassName: 'acl-popup',
  overlayClassName: 'reveal-modal-bg',

  open: false,
  hasCloseButton: true,
  hasOverlay: true,
  closeOnEscKeyDown: true,
  clickableOverlay: true,

  onOpen: _lodash2.default.noop,
  onClose: _lodash2.default.noop,
  onCancel: _lodash2.default.noop,
  onAccept: _lodash2.default.noop
};
exports.default = Modal;