Merge pull request #12490 from ToolJet/fix/modal-viewport-gap

fix: Removes extra gap between canvas and query panel when modal is open
This commit is contained in:
Johnson Cherian 2025-04-08 14:51:37 +05:30 committed by GitHub
commit 986cacfff5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -68,6 +68,54 @@ export const Modal = function Modal({
}, [showModal, id, mode]); }, [showModal, id, mode]);
/**** End - Logic to reset the zIndex of modal control box ****/ /**** End - Logic to reset the zIndex of modal control box ****/
// Side effects for modal, which include dom manipulation to hide overflow when opening
// And cleaning up dom when modal is closed
const onShowSideEffects = () => {
const canvasElement = document.querySelector('.page-container.canvas-container');
const realCanvasEl = document.getElementsByClassName('real-canvas')[0];
const allModalContainers = realCanvasEl.querySelectorAll('.modal');
const modalContainer = allModalContainers[allModalContainers.length - 1];
if (canvasElement && realCanvasEl && modalContainer) {
const currentScroll = canvasElement.scrollTop;
canvasElement.style.overflowY = 'hidden';
modalContainer.style.height = `${canvasElement.offsetHeight}px`;
modalContainer.style.top = `${currentScroll}px`;
fireEvent('onOpen');
}
};
const onHideSideEffects = () => {
const canvasElement = document.querySelector('.page-container.canvas-container');
const realCanvasEl = document.getElementsByClassName('real-canvas')[0];
const allModalContainers = realCanvasEl.querySelectorAll('.modal');
const modalContainer = allModalContainers[allModalContainers.length - 1];
const hasManyModalsOpen = allModalContainers.length > 1;
if (canvasElement && realCanvasEl && modalContainer) {
modalContainer.style.height = ``;
modalContainer.style.top = ``;
fireEvent('onClose');
}
if (canvasElement && !hasManyModalsOpen) {
canvasElement.style.overflow = 'auto';
}
};
// useEventListener('resize', onShowSideEffects, window);
const onShowModal = () => {
openModal();
onShowSideEffects();
};
const onHideModal = () => {
onHideSideEffects();
hideModal();
};
useEffect(() => { useEffect(() => {
const exposedVariables = { const exposedVariables = {
open: async function () { open: async function () {
@ -93,58 +141,48 @@ export const Modal = function Modal({
setShowModal(true); setShowModal(true);
} }
// Add debounced version of handleModalOpen
const debouncedModalOpen = debounce(() => {
onShowSideEffects();
}, 10);
useEffect(() => { useEffect(() => {
const handleModalOpen = () => { // Select the DOM element
openModal(); const canvasElement = document.querySelector('.page-container.canvas-container');
const canvasElement = document.getElementsByClassName('canvas-container')[0];
const modalBackdropEl = document.getElementsByClassName('modal-backdrop')[0];
const realCanvasEl = document.getElementsByClassName('real-canvas')[0];
const modalCanvasEl = document.getElementById(`canvas-${id}`);
if (canvasElement && modalBackdropEl && modalCanvasEl && realCanvasEl) {
realCanvasEl.style.height = '100vh';
realCanvasEl.style.position = 'absolute';
realCanvasEl.style.overflow = 'hidden';
modalBackdropEl.style.height = '100vh'; if (!canvasElement) return; // Ensure the element exists
modalBackdropEl.style.minHeight = '100vh';
modalBackdropEl.style.minHeight = '100vh'; // Create a ResizeObserver
modalCanvasEl.style.height = modalHeight; const resizeObserver = new ResizeObserver(() => {
} debouncedModalOpen();
});
// Observe the canvas element
resizeObserver.observe(canvasElement);
return () => {
// Cleanup observer on component unmount
resizeObserver.disconnect();
}; };
}, []);
// Add debounced version of handleModalOpen useEffect(() => {
const debouncedModalOpen = debounce(() => {
handleModalOpen();
}, 10);
const handleModalClose = () => {
const canvasElement = document.getElementsByClassName('canvas-container')[0];
const realCanvasEl = document.getElementsByClassName('real-canvas')[0];
const canvasHeight = realCanvasEl?.getAttribute('canvas-height');
if (canvasElement && realCanvasEl && canvasHeight) {
realCanvasEl.style.height = canvasHeight;
realCanvasEl.style.position = '';
realCanvasEl.style.overflow = 'auto';
}
};
if (showModal) { if (showModal) {
debouncedModalOpen(); debouncedModalOpen();
} else { } else {
// if (document.getElementsByClassName('modal-content')[0] == undefined) { if (document.getElementsByClassName('modal-content')[0] == undefined) {
handleModalClose(); onHideModal();
// } }
} }
// Cleanup the effect // Cleanup the effect
return () => { return () => {
if (document.getElementsByClassName('modal-content')[0] == undefined) { if (document.getElementsByClassName('modal-content')[0] == undefined) {
handleModalClose(); onHideModal();
} }
}; };
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [showModal, modalHeight]); }, [modalHeight, size]);
useEffect(() => { useEffect(() => {
if (isInitialRender.current) { if (isInitialRender.current) {
@ -245,7 +283,9 @@ export const Modal = function Modal({
keyboard={true} keyboard={true}
enforceFocus={false} enforceFocus={false}
animation={false} animation={false}
onEscapeKeyDown={() => hideOnEsc && hideModal()} onShow={() => onShowModal()}
onHide={() => onHideModal()}
onEscapeKeyDown={() => hideOnEsc && onHideModal()}
id="modal-container" id="modal-container"
component-id={id} component-id={id}
backdrop={'static'} backdrop={'static'}
@ -258,7 +298,7 @@ export const Modal = function Modal({
titleAlignment, titleAlignment,
hideTitleBar, hideTitleBar,
hideCloseButton, hideCloseButton,
hideModal, hideModal: onHideModal,
component, component,
showConfigHandler: mode === 'edit', showConfigHandler: mode === 'edit',
}} }}