@adaptabletools/adaptable-cjs
Version:
Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
115 lines (114 loc) • 4.28 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WindowModal = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const re_resizable_1 = require("re-resizable");
const useDraggable_1 = tslib_1.__importDefault(require("../utils/useDraggable"));
const UIHelper_1 = require("../../View/UIHelper");
const react_dom_1 = require("react-dom");
const useStacking_1 = require("./useStacking");
let portalElement;
const ensurePortalElement = () => {
if (!(0, UIHelper_1.isBrowserDocumentAvailable)()) {
return;
}
if (portalElement) {
return;
}
portalElement = document.createElement('div');
portalElement.classList.add('ab-cmp-modal-window');
document.body.appendChild(portalElement);
};
const normalizeTopLeft = (position) => (position < 0 ? 0 : position);
const getResizePositionDelta = (direction, delta) => {
const positionDelta = { x: 0, y: 0 };
const left = -delta.width;
const top = -delta.height;
const directions = ['top', 'left', 'topLeft', 'bottomLeft', 'topRight'];
if (directions.indexOf(direction) !== -1) {
if (direction === 'bottomLeft') {
positionDelta.x += left;
}
else if (direction === 'topRight') {
positionDelta.y += top;
}
else {
positionDelta.x += left;
positionDelta.y += top;
}
return positionDelta;
}
return null;
};
const WindowModal = (props) => {
ensurePortalElement();
const positionDeltaRef = React.useRef(null);
const normalizedPosition = {
x: normalizeTopLeft(props.position?.x),
y: normalizeTopLeft(props.position?.y),
};
const positionRef = React.useRef(normalizedPosition);
const stacking = (0, useStacking_1.useStacking)();
/**
* This is needed because the function called in onDrop is saved when
* it gets attached to the DOM element event handler.
* This handler changes only when the underlying node changes.
*/
positionRef.current = normalizedPosition;
const style = {
zIndex: stacking.zIndex,
position: 'absolute',
left: normalizedPosition.x,
top: normalizedPosition.y,
};
const handleDrop = (dx, dy) => {
const newPosition = {
x: positionRef.current.x + dx,
y: positionRef.current.y + dy,
};
props.onChange({
position: newPosition,
size: props.size,
});
};
const { targetRef, applyTransform } = (0, useDraggable_1.default)({
handleSelector: props.handleSelector,
onDrop: handleDrop,
});
const handleResizeStop = (event, direction, elementRef, delta) => {
let newPosition = normalizedPosition;
if (positionDeltaRef.current) {
newPosition = {
x: normalizedPosition.x + positionDeltaRef.current.x,
y: normalizedPosition.y + positionDeltaRef.current.y,
};
positionDeltaRef.current = null;
applyTransform(0, 0);
}
const newSize = {
width: props.size.width + delta.width,
height: props.size.height + delta.height,
};
props.onChange({
position: newPosition,
size: newSize,
});
};
const handleResize = React.useCallback((event, direction, elementRef, delta) => {
const positionDelta = getResizePositionDelta(direction, delta);
if (positionDelta) {
positionDeltaRef.current = positionDelta;
applyTransform(positionDelta.x, positionDelta.y);
}
}, []);
const ResizableCmp = re_resizable_1.Resizable;
return (0, react_dom_1.createPortal)(React.createElement("div", { style: style,
//@ts-ignore
ref: targetRef, onMouseDown: stacking.bringInFront },
React.createElement(ResizableCmp, { minWidth: props.minWidth, minHeight: props.minHeight, onResizeStop: handleResizeStop, onResize: handleResize, bounds: "window", defaultSize: {
width: props.size.width,
height: props.size.height,
} }, props.children)), portalElement);
};
exports.WindowModal = WindowModal;