Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

createPortal制作模态窗 #32

Open
lewenweijia opened this issue Oct 16, 2019 · 1 comment
Open

createPortal制作模态窗 #32

lewenweijia opened this issue Oct 16, 2019 · 1 comment

Comments

@lewenweijia
Copy link
Owner

import React, { Component } from 'react';
import ReactDOM, { createPortal, unmountComponentAtNode } from 'react-dom';
import './dummy-modal.less';

interface DummyModalProps {
  // 左上角文案
  title?: string;
  // 中心内容
  content?: string | string[];

  // 不展示取消按钮
  noCancel?: boolean;
  // 点击确认按钮回调
  onConfirm?: () => void;
  // 点击取消按钮
  onCancel?: () => void;
  // 确认文本
  onText?: string;
}

class DummyModal extends Component<DummyModalProps> {
  // 傀儡容器
  static overlay: HTMLDivElement | null = null;

  static show(props: DummyModalProps) {
    const overlay = document.createElement('div');

    ReactDOM.render(<DummyModal {...props} />, overlay);

    DummyModal.overlay = overlay;
  }

  // 关闭
  static close() {
    DummyModal.overlay && unmountComponentAtNode(DummyModal.overlay);
  }

  // 弹窗关闭
  handleCancel = () => {
    const { onCancel } = this.props;
    onCancel && onCancel();
    DummyModal.close();
  };

  // 弹窗确认
  handleConfirm = () => {
    this.props.onConfirm && this.props.onConfirm();

    this.handleCancel();
  };

  render() {
    const { title, content, noCancel = false, onText } = this.props;

    const Content = (
      <div className="dummy-modal-wrapper">
        {/* 中心框框 */}
        <div className="dummy-modal-body">
          {/* 头部 */}
          <div className="dummy-modal-header">
            <div className="left-side">{title}</div>
            <div className="right-side close" onClick={this.handleCancel}>
              <i className="neibugongzuotai_iconfont icon-xiaochacha" />
            </div>
          </div>

          {/* 内容区 */}
          <div className="dummy-modal-content">
            {Array.isArray(content)
              ? content.map(i => <div key={i}>{i}</div>)
              : content}
          </div>

          {/* 底部按钮区 */}
          <div className="dummy-modal-btn-actions">
            {!noCancel && (
              <span className="btn btn-cancel" onClick={this.handleCancel}>
                取消
              </span>
            )}
            <span className="btn btn-confirm" onClick={this.handleConfirm}>
              {onText || '确认'}
            </span>
          </div>
        </div>
      </div>
    );

    return createPortal(Content, document.body);
  }
}

export default DummyModal;
@lewenweijia
Copy link
Owner Author

.dummy-modal-wrapper {
  position: absolute;
  height: 100%;
  width: 100%;
  top: 0;
  left: 0;
  background: rgba(255, 255, 255, 0.8);
  z-index: 2;
  display: flex;
  justify-content: center;
  align-items: center;
}

.dummy-modal-wrapper > .dummy-modal-body {
  box-shadow: 0px 6px 16px 0px rgba(0, 0, 0, 0.08);
  border: 1px solid rgba(230, 230, 230, 1);
  background: white;
  border-radius: 4px;
  min-width: 540px;
  font-size: 14px;

  // 头部
  .dummy-modal-header {
    display: flex;
    padding: 20px;
    .left-side {
      color: #4c4c4c;
    }

    .right-side.close {
      margin-left: auto;

      .icon-xiaochacha {
        cursor: pointer;
        font-size: 13px;
        color: #999;
        position: relative;
        top: 1px;
      }
    }
  }

  // 内容区
  .dummy-modal-content {
    margin-top: 40px;
    margin-bottom: 30px;
    padding: 0 55px;
    font-size: 16px;
    display: flex;
    flex-flow: column nowrap;
    align-items: center;
  }

  // 底部按钮区
  .dummy-modal-btn-actions {
    display: flex;
    margin: 0 95px 50px;
    justify-content: center;

    .btn {
      width: 160px;
      height: 40px;
      border-radius: 2px;
      display: flex;
      justify-content: center;
      align-items: center;
      cursor: pointer;

      &.btn-cancel {
        color: #1989fa;
        background: white;
        border: 1px solid #1989fa;
        margin-right: 30px;
        &:hover {
          background: rgba(25, 137, 250, 0.3);
        }
        &:active {
          color: white;
          background: #1989fa;
        }
      }

      &.btn-confirm {
        color: white;
        background: #1989fa;
        border: 1px solid #1989fa;
        &:hover {
          background: #1571ce;
        }
      }
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant