GoScrobble/web/node_modules/reactjs-popup/dist/reactjs-popup.esm.js

631 lines
21 KiB
JavaScript
Raw Normal View History

2022-04-25 02:47:15 +00:00
import React, { useEffect, useLayoutEffect, forwardRef, useState, useRef, useImperativeHandle } from 'react';
import ReactDOM from 'react-dom';
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
var useOnEscape = function useOnEscape(handler, active) {
if (active === void 0) {
active = true;
}
useEffect(function () {
if (!active) return;
var listener = function listener(event) {
// check if key is an Escape
if (event.key === 'Escape') handler(event);
};
document.addEventListener('keyup', listener);
return function () {
if (!active) return;
document.removeEventListener('keyup', listener);
};
}, [handler, active]);
};
var useRepositionOnResize = function useRepositionOnResize(handler, active) {
if (active === void 0) {
active = true;
}
useEffect(function () {
if (!active) return;
var listener = function listener() {
handler();
};
window.addEventListener('resize', listener);
return function () {
if (!active) return;
window.removeEventListener('resize', listener);
};
}, [handler, active]);
};
var useOnClickOutside = function useOnClickOutside(ref, handler, active) {
if (active === void 0) {
active = true;
}
useEffect(function () {
if (!active) return;
var listener = function listener(event) {
// Do nothing if clicking ref's element or descendent elements
var refs = Array.isArray(ref) ? ref : [ref];
var contains = false;
refs.forEach(function (r) {
if (!r.current || r.current.contains(event.target)) {
contains = true;
return;
}
});
event.stopPropagation();
if (!contains) handler(event);
};
document.addEventListener('mousedown', listener);
document.addEventListener('touchstart', listener);
return function () {
if (!active) return;
document.removeEventListener('mousedown', listener);
document.removeEventListener('touchstart', listener);
};
}, [ref, handler, active]);
}; // Make sure that user is not able TAB out of the Modal content on Open
var useTabbing = function useTabbing(contentRef, active) {
if (active === void 0) {
active = true;
}
useEffect(function () {
if (!active) return;
var listener = function listener(event) {
// check if key is an Tab
if (event.keyCode === 9) {
var _contentRef$current;
var els = contentRef === null || contentRef === void 0 ? void 0 : (_contentRef$current = contentRef.current) === null || _contentRef$current === void 0 ? void 0 : _contentRef$current.querySelectorAll('a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [tabindex="0"]');
var focusableEls = Array.prototype.slice.call(els);
if (focusableEls.length === 1) {
event.preventDefault();
return;
}
var firstFocusableEl = focusableEls[0];
var lastFocusableEl = focusableEls[focusableEls.length - 1];
if (event.shiftKey && document.activeElement === firstFocusableEl) {
event.preventDefault();
lastFocusableEl.focus();
} else if (document.activeElement === lastFocusableEl) {
event.preventDefault();
firstFocusableEl.focus();
}
}
};
document.addEventListener('keydown', listener);
return function () {
if (!active) return;
document.removeEventListener('keydown', listener);
};
}, [contentRef, active]);
};
var useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
var Style = {
popupContent: {
tooltip: {
position: 'absolute',
zIndex: 999
},
modal: {
position: 'relative',
margin: 'auto'
}
},
popupArrow: {
height: '8px',
width: '16px',
position: 'absolute',
background: 'transparent',
color: '#FFF',
zIndex: -1
},
overlay: {
tooltip: {
position: 'fixed',
top: '0',
bottom: '0',
left: '0',
right: '0',
zIndex: 999
},
modal: {
position: 'fixed',
top: '0',
bottom: '0',
left: '0',
right: '0',
display: 'flex',
zIndex: 999
}
}
};
var POSITION_TYPES = ['top left', 'top center', 'top right', 'right top', 'right center', 'right bottom', 'bottom left', 'bottom center', 'bottom right', 'left top', 'left center', 'left bottom'];
var getCoordinatesForPosition = function getCoordinatesForPosition(triggerBounding, ContentBounding, position, //PopupPosition | PopupPosition[],
arrow, _ref) {
var offsetX = _ref.offsetX,
offsetY = _ref.offsetY;
var margin = arrow ? 8 : 0;
var args = position.split(' '); // the step N 1 : center the popup content => ok
var CenterTop = triggerBounding.top + triggerBounding.height / 2;
var CenterLeft = triggerBounding.left + triggerBounding.width / 2;
var height = ContentBounding.height,
width = ContentBounding.width;
var top = CenterTop - height / 2;
var left = CenterLeft - width / 2;
var transform = '';
var arrowTop = '0%';
var arrowLeft = '0%'; // the step N 2 : => ok
switch (args[0]) {
case 'top':
top -= height / 2 + triggerBounding.height / 2 + margin;
transform = "rotate(180deg) translateX(50%)";
arrowTop = '100%';
arrowLeft = '50%';
break;
case 'bottom':
top += height / 2 + triggerBounding.height / 2 + margin;
transform = "rotate(0deg) translateY(-100%) translateX(-50%)";
arrowLeft = '50%';
break;
case 'left':
left -= width / 2 + triggerBounding.width / 2 + margin;
transform = " rotate(90deg) translateY(50%) translateX(-25%)";
arrowLeft = '100%';
arrowTop = '50%';
break;
case 'right':
left += width / 2 + triggerBounding.width / 2 + margin;
transform = "rotate(-90deg) translateY(-150%) translateX(25%)";
arrowTop = '50%';
break;
}
switch (args[1]) {
case 'top':
top = triggerBounding.top;
arrowTop = triggerBounding.height / 2 + "px";
break;
case 'bottom':
top = triggerBounding.top - height + triggerBounding.height;
arrowTop = height - triggerBounding.height / 2 + "px";
break;
case 'left':
left = triggerBounding.left;
arrowLeft = triggerBounding.width / 2 + "px";
break;
case 'right':
left = triggerBounding.left - width + triggerBounding.width;
arrowLeft = width - triggerBounding.width / 2 + "px";
break;
}
top = args[0] === 'top' ? top - offsetY : top + offsetY;
left = args[0] === 'left' ? left - offsetX : left + offsetX;
return {
top: top,
left: left,
transform: transform,
arrowLeft: arrowLeft,
arrowTop: arrowTop
};
};
var getTooltipBoundary = function getTooltipBoundary(keepTooltipInside) {
// add viewport
var boundingBox = {
top: 0,
left: 0,
/* eslint-disable-next-line no-undef */
width: window.innerWidth,
/* eslint-disable-next-line no-undef */
height: window.innerHeight
};
if (typeof keepTooltipInside === 'string') {
/* eslint-disable-next-line no-undef */
var selector = document.querySelector(keepTooltipInside);
if (process.env.NODE_ENV !== 'production') {
if (selector === null) throw new Error(keepTooltipInside + " selector does not exist : keepTooltipInside must be a valid html selector 'class' or 'Id' or a boolean value");
}
if (selector !== null) boundingBox = selector.getBoundingClientRect();
}
return boundingBox;
};
var calculatePosition = function calculatePosition(triggerBounding, ContentBounding, position, arrow, _ref2, keepTooltipInside) {
var offsetX = _ref2.offsetX,
offsetY = _ref2.offsetY;
var bestCoords = {
arrowLeft: '0%',
arrowTop: '0%',
left: 0,
top: 0,
transform: 'rotate(135deg)'
};
var i = 0;
var wrapperBox = getTooltipBoundary(keepTooltipInside);
var positions = Array.isArray(position) ? position : [position]; // keepTooltipInside would be activated if the keepTooltipInside exist or the position is Array
if (keepTooltipInside || Array.isArray(position)) positions = [].concat(positions, POSITION_TYPES); // add viewPort for WarpperBox
// wrapperBox.top = wrapperBox.top + window.scrollY;
// wrapperBox.left = wrapperBox.left + window.scrollX;
while (i < positions.length) {
bestCoords = getCoordinatesForPosition(triggerBounding, ContentBounding, positions[i], arrow, {
offsetX: offsetX,
offsetY: offsetY
});
var contentBox = {
top: bestCoords.top,
left: bestCoords.left,
width: ContentBounding.width,
height: ContentBounding.height
};
if (contentBox.top <= wrapperBox.top || contentBox.left <= wrapperBox.left || contentBox.top + contentBox.height >= wrapperBox.top + wrapperBox.height || contentBox.left + contentBox.width >= wrapperBox.left + wrapperBox.width) {
i++;
} else {
break;
}
}
return bestCoords;
};
var popupIdCounter = 0;
var getRootPopup = function getRootPopup() {
var PopupRoot = document.getElementById('popup-root');
if (PopupRoot === null) {
PopupRoot = document.createElement('div');
PopupRoot.setAttribute('id', 'popup-root');
document.body.appendChild(PopupRoot);
}
return PopupRoot;
};
var Popup = /*#__PURE__*/forwardRef(function (_ref, ref) {
var _ref$trigger = _ref.trigger,
trigger = _ref$trigger === void 0 ? null : _ref$trigger,
_ref$onOpen = _ref.onOpen,
onOpen = _ref$onOpen === void 0 ? function () {} : _ref$onOpen,
_ref$onClose = _ref.onClose,
onClose = _ref$onClose === void 0 ? function () {} : _ref$onClose,
_ref$defaultOpen = _ref.defaultOpen,
defaultOpen = _ref$defaultOpen === void 0 ? false : _ref$defaultOpen,
_ref$open = _ref.open,
open = _ref$open === void 0 ? undefined : _ref$open,
_ref$disabled = _ref.disabled,
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
_ref$nested = _ref.nested,
nested = _ref$nested === void 0 ? false : _ref$nested,
_ref$closeOnDocumentC = _ref.closeOnDocumentClick,
closeOnDocumentClick = _ref$closeOnDocumentC === void 0 ? true : _ref$closeOnDocumentC,
_ref$repositionOnResi = _ref.repositionOnResize,
repositionOnResize = _ref$repositionOnResi === void 0 ? true : _ref$repositionOnResi,
_ref$closeOnEscape = _ref.closeOnEscape,
closeOnEscape = _ref$closeOnEscape === void 0 ? true : _ref$closeOnEscape,
_ref$on = _ref.on,
on = _ref$on === void 0 ? ['click'] : _ref$on,
_ref$contentStyle = _ref.contentStyle,
contentStyle = _ref$contentStyle === void 0 ? {} : _ref$contentStyle,
_ref$arrowStyle = _ref.arrowStyle,
arrowStyle = _ref$arrowStyle === void 0 ? {} : _ref$arrowStyle,
_ref$overlayStyle = _ref.overlayStyle,
overlayStyle = _ref$overlayStyle === void 0 ? {} : _ref$overlayStyle,
_ref$className = _ref.className,
className = _ref$className === void 0 ? '' : _ref$className,
_ref$position = _ref.position,
position = _ref$position === void 0 ? 'bottom center' : _ref$position,
_ref$modal = _ref.modal,
modal = _ref$modal === void 0 ? false : _ref$modal,
_ref$lockScroll = _ref.lockScroll,
lockScroll = _ref$lockScroll === void 0 ? false : _ref$lockScroll,
_ref$arrow = _ref.arrow,
arrow = _ref$arrow === void 0 ? true : _ref$arrow,
_ref$offsetX = _ref.offsetX,
offsetX = _ref$offsetX === void 0 ? 0 : _ref$offsetX,
_ref$offsetY = _ref.offsetY,
offsetY = _ref$offsetY === void 0 ? 0 : _ref$offsetY,
_ref$mouseEnterDelay = _ref.mouseEnterDelay,
mouseEnterDelay = _ref$mouseEnterDelay === void 0 ? 100 : _ref$mouseEnterDelay,
_ref$mouseLeaveDelay = _ref.mouseLeaveDelay,
mouseLeaveDelay = _ref$mouseLeaveDelay === void 0 ? 100 : _ref$mouseLeaveDelay,
_ref$keepTooltipInsid = _ref.keepTooltipInside,
keepTooltipInside = _ref$keepTooltipInsid === void 0 ? false : _ref$keepTooltipInsid,
children = _ref.children;
var _useState = useState(open || defaultOpen),
isOpen = _useState[0],
setIsOpen = _useState[1];
var triggerRef = useRef(null);
var contentRef = useRef(null);
var arrowRef = useRef(null);
var focusedElBeforeOpen = useRef(null);
var popupId = useRef("popup-" + ++popupIdCounter);
var isModal = modal ? true : !trigger;
var timeOut = useRef(0);
useIsomorphicLayoutEffect(function () {
if (isOpen) {
focusedElBeforeOpen.current = document.activeElement;
setPosition();
focusContentOnOpen(); // for accessibility
lockScrolll();
} else {
resetScroll();
}
return function () {
clearTimeout(timeOut.current);
};
}, [isOpen]); // for uncontrolled popup we need to sync isOpen with open prop
useEffect(function () {
if (typeof open === 'boolean') {
if (open) openPopup();else closePopup();
}
}, [open, disabled]);
var openPopup = function openPopup(event) {
if (isOpen || disabled) return;
setIsOpen(true);
setTimeout(function () {
return onOpen(event);
}, 0);
};
var closePopup = function closePopup(event) {
var _focusedElBeforeOpen$;
if (!isOpen || disabled) return;
setIsOpen(false);
if (isModal) (_focusedElBeforeOpen$ = focusedElBeforeOpen.current) === null || _focusedElBeforeOpen$ === void 0 ? void 0 : _focusedElBeforeOpen$.focus();
setTimeout(function () {
return onClose(event);
}, 0);
};
var togglePopup = function togglePopup(event) {
event === null || event === void 0 ? void 0 : event.stopPropagation();
if (!isOpen) openPopup(event);else closePopup(event);
};
var onMouseEnter = function onMouseEnter(event) {
clearTimeout(timeOut.current);
timeOut.current = setTimeout(function () {
return openPopup(event);
}, mouseEnterDelay);
};
var onContextMenu = function onContextMenu(event) {
event === null || event === void 0 ? void 0 : event.preventDefault();
togglePopup();
};
var onMouseLeave = function onMouseLeave(event) {
clearTimeout(timeOut.current);
timeOut.current = setTimeout(function () {
return closePopup(event);
}, mouseLeaveDelay);
};
var lockScrolll = function lockScrolll() {
if (isModal && lockScroll) document.getElementsByTagName('body')[0].style.overflow = 'hidden'; // migrate to document.body
};
var resetScroll = function resetScroll() {
if (isModal && lockScroll) document.getElementsByTagName('body')[0].style.overflow = 'auto';
};
var focusContentOnOpen = function focusContentOnOpen() {
var _contentRef$current;
var focusableEls = contentRef === null || contentRef === void 0 ? void 0 : (_contentRef$current = contentRef.current) === null || _contentRef$current === void 0 ? void 0 : _contentRef$current.querySelectorAll('a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [tabindex="0"]');
var firstEl = Array.prototype.slice.call(focusableEls)[0];
firstEl === null || firstEl === void 0 ? void 0 : firstEl.focus();
};
useImperativeHandle(ref, function () {
return {
open: function open() {
openPopup();
},
close: function close() {
closePopup();
},
toggle: function toggle() {
togglePopup();
}
};
}); // set Position
var setPosition = function setPosition() {
if (isModal || !isOpen) return;
if (!(triggerRef === null || triggerRef === void 0 ? void 0 : triggerRef.current) || !(triggerRef === null || triggerRef === void 0 ? void 0 : triggerRef.current) || !(contentRef === null || contentRef === void 0 ? void 0 : contentRef.current)) return; /// show error as one of ref is undefined
var trigger = triggerRef.current.getBoundingClientRect();
var content = contentRef.current.getBoundingClientRect();
var cords = calculatePosition(trigger, content, position, arrow, {
offsetX: offsetX,
offsetY: offsetY
}, keepTooltipInside);
contentRef.current.style.top = cords.top + window.scrollY + "px";
contentRef.current.style.left = cords.left + window.scrollX + "px";
if (arrow && !!arrowRef.current) {
var _arrowStyle$top, _arrowStyle$left;
arrowRef.current.style.transform = cords.transform;
arrowRef.current.style.setProperty('-ms-transform', cords.transform);
arrowRef.current.style.setProperty('-webkit-transform', cords.transform);
arrowRef.current.style.top = ((_arrowStyle$top = arrowStyle.top) === null || _arrowStyle$top === void 0 ? void 0 : _arrowStyle$top.toString()) || cords.arrowTop;
arrowRef.current.style.left = ((_arrowStyle$left = arrowStyle.left) === null || _arrowStyle$left === void 0 ? void 0 : _arrowStyle$left.toString()) || cords.arrowLeft;
}
}; // hooks
useOnEscape(closePopup, closeOnEscape); // can be optimized if we disabled for hover
useTabbing(contentRef, isOpen && isModal);
useRepositionOnResize(setPosition, repositionOnResize);
useOnClickOutside(!!trigger ? [contentRef, triggerRef] : [contentRef], closePopup, closeOnDocumentClick && !nested); // we need to add a ne
// render the trigger element and add events
var renderTrigger = function renderTrigger() {
var triggerProps = {
key: 'T',
ref: triggerRef,
'aria-describedby': popupId.current
};
var onAsArray = Array.isArray(on) ? on : [on];
for (var i = 0, len = onAsArray.length; i < len; i++) {
switch (onAsArray[i]) {
case 'click':
triggerProps.onClick = togglePopup;
break;
case 'right-click':
triggerProps.onContextMenu = onContextMenu;
break;
case 'hover':
triggerProps.onMouseEnter = onMouseEnter;
triggerProps.onMouseLeave = onMouseLeave;
break;
case 'focus':
triggerProps.onFocus = onMouseEnter;
triggerProps.onBlur = onMouseLeave;
break;
}
}
if (typeof trigger === 'function') {
var comp = trigger(isOpen);
return !!trigger && React.cloneElement(comp, triggerProps);
}
return !!trigger && React.cloneElement(trigger, triggerProps);
};
var addWarperAction = function addWarperAction() {
var popupContentStyle = isModal ? Style.popupContent.modal : Style.popupContent.tooltip;
var childrenElementProps = {
className: "popup-content " + (className !== '' ? className.split(' ').map(function (c) {
return c + "-content";
}).join(' ') : ''),
style: _extends({}, popupContentStyle, contentStyle, {
pointerEvents: 'auto'
}),
ref: contentRef,
onClick: function onClick(e) {
e.stopPropagation();
}
};
if (!modal && on.indexOf('hover') >= 0) {
childrenElementProps.onMouseEnter = onMouseEnter;
childrenElementProps.onMouseLeave = onMouseLeave;
}
return childrenElementProps;
};
var renderContent = function renderContent() {
return React.createElement("div", Object.assign({}, addWarperAction(), {
key: "C",
role: isModal ? 'dialog' : 'tooltip',
id: popupId.current
}), arrow && !isModal && React.createElement("div", {
ref: arrowRef,
style: Style.popupArrow
}, React.createElement("svg", {
"data-testid": "arrow",
className: "popup-arrow " + (className !== '' ? className.split(' ').map(function (c) {
return c + "-arrow";
}).join(' ') : ''),
viewBox: "0 0 32 16",
style: _extends({
position: 'absolute'
}, arrowStyle)
}, React.createElement("path", {
d: "M16 0l16 16H0z",
fill: "currentcolor"
}))), children && typeof children === 'function' ? children(closePopup, isOpen) : children);
};
var overlay = !(on.indexOf('hover') >= 0);
var ovStyle = isModal ? Style.overlay.modal : Style.overlay.tooltip;
var content = [overlay && React.createElement("div", {
key: "O",
"data-testid": "overlay",
"data-popup": isModal ? 'modal' : 'tooltip',
className: "popup-overlay " + (className !== '' ? className.split(' ').map(function (c) {
return c + "-overlay";
}).join(' ') : ''),
style: _extends({}, ovStyle, overlayStyle, {
pointerEvents: closeOnDocumentClick && nested || isModal ? 'auto' : 'none'
}),
onClick: closeOnDocumentClick && nested ? closePopup : undefined,
tabIndex: -1
}, isModal && renderContent()), !isModal && renderContent()];
return React.createElement(React.Fragment, null, renderTrigger(), isOpen && ReactDOM.createPortal(content, getRootPopup()));
});
export default Popup;
export { Popup };
//# sourceMappingURL=reactjs-popup.esm.js.map