flexlayout-react
Version:
A multi-tab docking layout manager
90 lines • 4 kB
JavaScript
import * as React from "react";
import { CLASSES } from "../Types";
import { TabButtonStamp } from "./TabButtonStamp";
import { useEffect, useRef } from "react";
/** @internal */
export function showPopup(triggerElement, parentNode, items, onSelect, layout) {
var _a;
const layoutDiv = layout.getRootDiv();
const classNameMapper = layout.getClassName;
const currentDocument = triggerElement.ownerDocument;
const triggerRect = triggerElement.getBoundingClientRect();
const layoutRect = (_a = layoutDiv === null || layoutDiv === void 0 ? void 0 : layoutDiv.getBoundingClientRect()) !== null && _a !== void 0 ? _a : new DOMRect(0, 0, 100, 100);
const elm = currentDocument.createElement("div");
elm.className = classNameMapper(CLASSES.FLEXLAYOUT__POPUP_MENU_CONTAINER);
if (triggerRect.left < layoutRect.left + layoutRect.width / 2) {
elm.style.left = triggerRect.left - layoutRect.left + "px";
}
else {
elm.style.right = layoutRect.right - triggerRect.right + "px";
}
if (triggerRect.top < layoutRect.top + layoutRect.height / 2) {
elm.style.top = triggerRect.top - layoutRect.top + "px";
}
else {
elm.style.bottom = layoutRect.bottom - triggerRect.bottom + "px";
}
layout.showOverlay(true);
if (layoutDiv) {
layoutDiv.appendChild(elm);
}
const onHide = () => {
layout.hideControlInPortal();
layout.showOverlay(false);
if (layoutDiv) {
layoutDiv.removeChild(elm);
}
elm.removeEventListener("pointerdown", onElementPointerDown);
currentDocument.removeEventListener("pointerdown", onDocPointerDown);
};
const onElementPointerDown = (event) => {
event.stopPropagation();
};
const onDocPointerDown = (_event) => {
onHide();
};
elm.addEventListener("pointerdown", onElementPointerDown);
currentDocument.addEventListener("pointerdown", onDocPointerDown);
layout.showControlInPortal(React.createElement(PopupMenu, { currentDocument: currentDocument, parentNode: parentNode, onSelect: onSelect, onHide: onHide, items: items, classNameMapper: classNameMapper, layout: layout }), elm);
}
/** @internal */
const PopupMenu = (props) => {
const { parentNode, items, onHide, onSelect, classNameMapper, layout } = props;
const divRef = useRef(null);
useEffect(() => {
// Set focus when the component mounts
if (divRef.current) {
divRef.current.focus();
}
}, []);
const onItemClick = (item, event) => {
onSelect(item);
onHide();
event.stopPropagation();
};
const onDragStart = (event, node) => {
event.stopPropagation(); // prevent starting a tabset drag as well
layout.setDragNode(event.nativeEvent, node);
setTimeout(() => {
onHide();
}, 0);
};
const onDragEnd = (event) => {
layout.clearDragMain();
};
const handleKeyDown = (event) => {
if (event.key === "Escape") {
onHide();
}
};
const itemElements = items.map((item, i) => {
let classes = classNameMapper(CLASSES.FLEXLAYOUT__POPUP_MENU_ITEM);
if (parentNode.getSelected() === item.index) {
classes += " " + classNameMapper(CLASSES.FLEXLAYOUT__POPUP_MENU_ITEM__SELECTED);
}
return (React.createElement("div", { key: item.index, className: classes, "data-layout-path": "/popup-menu/tb" + i, onClick: (event) => onItemClick(item, event), draggable: true, onDragStart: (e) => onDragStart(e, item.node), onDragEnd: onDragEnd, title: item.node.getHelpText() },
React.createElement(TabButtonStamp, { node: item.node, layout: layout })));
});
return (React.createElement("div", { className: classNameMapper(CLASSES.FLEXLAYOUT__POPUP_MENU), ref: divRef, tabIndex: 0, onKeyDown: handleKeyDown, "data-layout-path": "/popup-menu" }, itemElements));
};
//# sourceMappingURL=PopupMenu.js.map