birch-context-menu
Version:
Custom context menu for react
44 lines (43 loc) • 1.76 kB
JavaScript
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import * as React from 'react';
import { useRef, forwardRef } from 'react';
import { createPortal } from 'react-dom';
/** Creates DOM element to be used as React root. */
function createRootElement(id) {
const rootContainer = document.createElement('div');
rootContainer.setAttribute('id', id);
return rootContainer;
}
/** Appends element as last child of body. */
function addRootElement(rootElem) {
document.body.insertBefore(rootElem, document.body.lastElementChild.nextElementSibling);
}
/** Hook to create a Singleton div for React Portal */
function usePortalDiv(id) {
const rootElemRef = useRef(null);
if (!rootElemRef.current) {
const existingParent = document.querySelector(`#${id}`);
const parentElem = existingParent || createRootElement(id);
if (!existingParent) {
addRootElement(parentElem);
}
rootElemRef.current = parentElem;
}
return rootElemRef.current;
}
/** Render React Portal for given id */
export const Portal = forwardRef((_a, ref) => {
var { id, children } = _a, props = __rest(_a, ["id", "children"]);
const target = usePortalDiv(`${id}`);
return createPortal(React.createElement("div", Object.assign({ ref: ref }, props), children), target);
});