From b6be1f2e9c40e68205bec436f062319d21a899d2 Mon Sep 17 00:00:00 2001 From: Evangeline Ireland Date: Mon, 22 Jul 2024 09:26:13 -0700 Subject: [PATCH] 187932225 movable modals (#1358) * Makes modals movable * Fixes not being able to input anything into the modals * PR fix - could not use `forwardRef` as it is a React ref * PR Fix --- v3/src/components/codap-modal.scss | 15 ++++ v3/src/components/codap-modal.tsx | 122 +++++++++++++++++++++++++---- 2 files changed, 123 insertions(+), 14 deletions(-) diff --git a/v3/src/components/codap-modal.scss b/v3/src/components/codap-modal.scss index e49469d020..a986ff991a 100644 --- a/v3/src/components/codap-modal.scss +++ b/v3/src/components/codap-modal.scss @@ -1,5 +1,7 @@ @import "./vars.scss"; $header-height: 30px; +$modal-height: 350px; +$modal-width: 350px; .chakra-modal__content { font-family: "museo-sans", sans-serif; @@ -74,3 +76,16 @@ $header-height: 30px; background-color: white; } } + +.codap-modal-content { + position: absolute !important; + margin-top: 0 !important; +} + +.chakra-modal__content-container { + position: absolute !important; +} + +.chakra-modal__overlay { + opacity: 0.01 !important; +} diff --git a/v3/src/components/codap-modal.tsx b/v3/src/components/codap-modal.tsx index 57632b6716..5c98d04433 100644 --- a/v3/src/components/codap-modal.tsx +++ b/v3/src/components/codap-modal.tsx @@ -1,5 +1,5 @@ -import { Modal, ModalContent, ModalOverlay } from "@chakra-ui/react" -import React, { ReactNode, forwardRef } from "react" +import { Modal, ModalContent, ModalOverlay, useMergeRefs } from "@chakra-ui/react" +import React, { ReactNode, forwardRef, useEffect, useRef, useState } from "react" import "./codap-modal.scss" @@ -15,11 +15,11 @@ interface IProps { } export const CodapModal = forwardRef(({ - children, closeOnOverlayClick=true, initialRef, isOpen, onClick, onClose, modalWidth, modalHeight -}: IProps, ref: React.LegacyRef | undefined) => { + children, initialRef, isOpen, onClick, onClose, modalWidth, modalHeight +}: IProps, ref: React.Ref | undefined) => { + return ( - - {children} - + + {children} + ) }) CodapModal.displayName = "CodapModal" + +interface IDraggableModalContentProps { + children: ReactNode + modalWidth?: string + modalHeight?: string + onClick?: () => void + fRef: React.Ref | undefined + isOpen: boolean +} + +const DraggableModalContent = ({children, modalWidth, modalHeight, onClick, fRef, isOpen + }: IDraggableModalContentProps) => { + const [modalPos, setModalPos] = useState({left: 350, top: 250}) + const modalRef = useRef(null) + const mergedRef = useMergeRefs(fRef, modalRef) + + useEffect(() => { + const modalElement = modalRef.current + if (!modalElement) { + return + } + + let isDragging = false + let startX = 0 + let startY = 0 + let initialX = 0 + let initialY = 0 + + const handleMouseDown = (e: MouseEvent) => { + e.stopPropagation() + isDragging = true + startX = e.clientX + startY = e.clientY + if (modalElement) { + initialX = modalElement.offsetLeft + initialY = modalElement.offsetTop + } + + document.addEventListener("mousemove", handleMouseMove) + document.addEventListener("mouseup", handleMouseUp) + } + + const handleMouseMove = (e: MouseEvent) => { + if (isDragging) { + const deltaX = e.clientX - startX + const deltaY = e.clientY - startY + modalElement.style.left = `${initialX + deltaX}px` + modalElement.style.top = `${initialY + deltaY}px` + setModalPos({left: initialX + deltaX, top: initialY + deltaY}) + } + } + + const handleMouseUp = (e: MouseEvent) => { + isDragging = false + document.removeEventListener("mousemove", handleMouseMove) + document.removeEventListener("mouseup", handleMouseUp) + } + + modalElement.addEventListener("mousedown", handleMouseDown) + + return () => { + modalElement.removeEventListener("mousedown", handleMouseDown) + document.removeEventListener("mousemove", handleMouseMove) + document.removeEventListener("mouseup", handleMouseUp) + } + }, []) + + + + const style: React.CSSProperties = { + width: modalWidth || "400px", + height: modalHeight || "400px", + cursor: "move", + top: modalPos.top, + left: modalPos.left, + position: "absolute" + } + + const varStyle = { + "--modal-width": modalWidth || "400px", + "--modal-height": modalHeight || "400px" + } + + return ( + + {children} + + ) +}