react+ant封装可拖拽(Modal)弹窗,继承官方属性。可进行拓展

react+ant封装可拖拽(Modal)弹窗,继承官方属性。可进行拓展
import { useState, useRef, useEffect } from "react";
import { Modal, ModalProps } from "antd";
import Draggable from "react-draggable";
import styles from "./index.module.less";

//ModalProps 继承官方modal属性,使用时属性提示
interface WebModal extends ModalProps {
  openDrag?: boolean; //是否开启弹窗的拖拽
  dragHandle?: boolean; //开启头部拖拽或者弹窗拖拽
}
const WebReactModal= ({
  openDrag = false,
  dragHandle = false,
  ...props
}: WebModal) => {
  const [position,setPosition]=useState({ x: 0, y: 0 })
  const [bounds, setBounds] = useState({
    left: 0,
    top: 0,
    bottom: 0,
    right: 0,
  }); //存储模态框的边界值
   const draggleRef = useRef<any>();
  //模态框开始移动计算莫太框的位置和边界
  const onStart = (event, uiData) => {
    const { clientWidth, clientHeight } = window?.document?.documentElement;
    //获取到模态框的位置,从而计算可以动的边界值
    const targetRect = draggleRef?.current?.getBoundingClientRect(); 
       setBounds({
      left: -targetRect?.left + uiData.x,
      right: clientWidth - (targetRect?.right - uiData.x),
      top: -targetRect?.top + uiData.y,
      bottom: clientHeight - (targetRect?.bottom - uiData.y),
    });
  };
  //因为设置了初始位置,所以添加模态框移动时更新位置
   const onDrag = (e, data) => {
    const { x, y } = data;
    setPosition({ x, y });
  };
  //监听模态框的关闭,恢复到初始的位置
  useEffect(() => {
    if (!props.open) {
      setPosition({ x: 0, y: 0 });
    }
  }, [props?.open]);
  return (
    <Modal
      maskClosable={false}
      className={styles.webModal}
      modalRender={(modal) => (
        <Draggable
          handle={dragHandle?"":'.ant-modal-header'}
          disabled={openDrag}
          onDrag={onDrag} 
          bounds={bounds}
          position={position}
          onStart={(event, uiData) => onStart(event, uiData)}
        >
         <div ref={draggleRef}>{modal}</div>
        </Draggable>
      )}
      {...props}
    >
      {props?.children}
    </Modal>
  );
};

export default WebReactModal;
//index.module.less样式文件
.webModal {
  :global {
    .ant-modal-content {
      .ant-modal-header {
        padding: 10px;
        background: #e5f0ff;
        border-bottom: 1px solid #f0f0f0;
        border-radius: 2px 2px 0 0;
      }
    }
    //标题样式,可根据自己需要修改样式
    .ant-modal-title {
      color: #566286;
      width: 100%;
      cursor: move;
      user-select: none;
      font-weight: bold;
    }
//关闭弹窗的X的样式
    .ant-modal-close-x {
      width: 42px;
      height: 42px;
      display: flex;
      align-items: center;
      justify-content: center;
    }
  }
}
//使用方法----记得应用组件哦
<WebModalwidth={1200} onOk={()=>{}} title={"测试弹窗"} open={openA} onCancel={()=>{setOpenA(false)}}>
  <div>存放弹窗中的内容</div>
</WebModal>
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值