index.js 5.04 KB
/*
	* @Author: Sakura
 * @LastEditors: Sakura
	* @Date: 2024-02-26 10:55:04
	* @Description: 可拖动函数组件封装
	*/
import { Button, Modal } from "antd";
import React, { useRef, useState } from "react";
import Draggable from "react-draggable";
import { InfoCircleOutlined } from "@ant-design/icons";
import "./index.less";

/**
 * 可拖动确认框
 * @param {string} title - 确认框头部文字
 * @param {boolean} btnShow - 是否需要按钮触发
 * @param {string} btnText - 调用按钮文字内容
 * @param {string | ReactNode} content - 确认框内容主体
 * @param {Function} onOk - 用户 确定 回调函数
 * @param {Function} onCancel - 用户 取消 回调函数
 */
export const DraggableConfirmModal = ({
  btnShow = true,
  btnText = "确定",
  title = "温馨提示",
  content,
  onOk = () => {},
  onCancel = () => {}
}) => {
  const [open, setOpen] = useState(!btnShow);
  const [disabled, setDisabled] = useState(true);
  const [bounds, setBounds] = useState({
    left: 0,
    top: 0,
    bottom: 0,
    right: 0
  });
  const draggleRef = useRef(null);

  // const FriendlyReminder = commonFunc.showLocalMessage(this.props, 'FriendlyReminder', '温馨提示');

  const showModal = () => {
    setOpen(true);
  };

  const handleOk = e => {
    setOpen(false);
    onOk();
  };

  const handleCancel = e => {
    setOpen(false);
    onCancel();
  };
  const onStart = (_event, uiData) => {
    const { clientWidth, clientHeight } = window.document.documentElement;
    const targetRect = draggleRef.current?.getBoundingClientRect();
    if (!targetRect) {
      return;
    }
    setBounds({
      left: -targetRect.left + uiData.x,
      right: clientWidth - (targetRect.right - uiData.x),
      top: -targetRect.top + uiData.y,
      bottom: clientHeight - (targetRect.bottom - uiData.y)
    });
  };
  return (
    <>
      {btnShow && (
        <Button
          type="primary"
          onClick={showModal}
          style={{ width: "100px", height: "40px", borderRadius: "5px" }}
        >
          {" "}
          {btnText}{" "}
        </Button>
      )}
      <Modal
        className="mesComfirm mesCommonModal"
        title={
          <div
            style={{
              width: "100%",
              cursor: "move"
            }}
            onMouseOver={() => {
              if (disabled) {
                setDisabled(false);
              }
            }}
            onMouseOut={() => {
              setDisabled(true);
            }}
          >
            <InfoCircleOutlined style={{ marginRight: "5px" }} />
            {title}
          </div>
        }
        open={open}
        onOk={handleOk}
        onCancel={handleCancel}
        modalRender={modal => (
          <Draggable
            disabled={disabled}
            bounds={bounds}
            onStart={(event, uiData) => onStart(event, uiData)}
          >
            <div ref={draggleRef}>{modal}</div>
          </Draggable>
        )}
      >
        <div
          style={{
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            width: "100%",
            height: 60,
            fontSize: 20
          }}
        >
          {content}
        </div>
      </Modal>
    </>
  );
};

/**
 * 可拖动页面
 * @param {string} title - 确认框头部文字
 * @param {number} width - 拖动框宽度
 * @param {Node | string | number} conent - 页面级组件
 * @param {Function} onCancel - 用户 取消 回调函数
 */
export const DraggablePage = ({
  title,
  conent,
  width = 520,
  onCancel = () => {}
}) => {
  const [open, setOpen] = useState(true);
  const [disabled, setDisabled] = useState(true);
  const [bounds, setBounds] = useState({
    left: 0,
    top: 0,
    bottom: 0,
    right: 0
  });
  const draggleRef = useRef(null);

  const handleCancel = e => {
    setOpen(false);
    onCancel();
  };

  const onStart = (_event, uiData) => {
    const { clientWidth, clientHeight } = window.document.documentElement;
    const targetRect = draggleRef.current?.getBoundingClientRect();
    if (!targetRect) {
      return;
    }
    setBounds({
      left: -targetRect.left + uiData.x,
      right: clientWidth - (targetRect.right - uiData.x),
      top: -targetRect.top + uiData.y,
      bottom: clientHeight - (targetRect.bottom - uiData.y)
    });
  };
  return (
    <Modal
      className="mesComfirm"
      footer={null}
      width={width}
      title={
        <div
          style={{
            width: "100%",
            cursor: "move"
          }}
          onMouseOver={() => {
            if (disabled) {
              setDisabled(false);
            }
          }}
          onMouseOut={() => {
            setDisabled(true);
          }}
        >
          {title}
        </div>
      }
      open={open}
      onCancel={handleCancel}

      modalRender={modal => (
        <Draggable
          disabled={disabled}
          bounds={bounds}
          onStart={(event, uiData) => onStart(event, uiData)}
        >
          <div ref={draggleRef}>{modal}</div>
        </Draggable>
      )}
    >
      {conent}
    </Modal>
  );
};