@momentum-ui/react-collaboration
Version:
Cisco Momentum UI Framework for React Collaboration Applications
907 lines • 51.1 kB
JavaScript
/** @component event-overlay */
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
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 React from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import omit from 'lodash/omit';
import { FocusScope } from '@react-aria/focus';
var defaultDims = {
offsetTop: 0,
bottom: 0,
center: 0,
height: 0,
left: 0,
middle: 0,
right: 0,
top: 0,
width: 0,
};
function eventPath(evt) {
var _a;
var path = (evt.composedPath && evt.composedPath()) || evt.path, target = evt.target;
var isPathInShadowRoot = false;
var pathElementsInShadowRootToDelete = 0;
// check if any of the elements in the next 3 elements in the path are a shadow root
// this is a work around to make the deprecated EventOverlay to work with the Shadow DOM
if ((path === null || path === void 0 ? void 0 : path.length) > 1) {
for (var i = 1; i < 4; i++) {
if (((_a = path[i]) === null || _a === void 0 ? void 0 : _a.toString()) === '[object ShadowRoot]') {
isPathInShadowRoot = true;
pathElementsInShadowRootToDelete = i + 1;
break;
}
}
}
if (isPathInShadowRoot) {
// if path is in shadowroot, then we need to get rid of the first 2 elements in the path
path = path.slice(pathElementsInShadowRootToDelete);
}
if (path != null) {
// Safari doesn't include Window, and it should.
path = path.indexOf(window) < 0 ? path.concat([window]) : path;
return path;
}
if (target === window) {
return [window];
}
function getParents(node, memo) {
memo = memo || [];
var parentNode = node !== undefined ? node.parentNode : false;
if (!parentNode) {
return memo;
}
else {
return getParents(parentNode, memo.concat([parentNode]));
}
}
return [target].concat(getParents(target)).concat([window]);
}
/**
* @deprecated - Components in the legacy folder (/src/legacy) are deprecated. Please use a component from the components folder (/src/components) instead. Legacy components may not follow accessibility standards.
**/
var EventOverlay = /** @class */ (function (_super) {
__extends(EventOverlay, _super);
function EventOverlay() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.state = {
absoluteParent: null,
containerParent: null,
isOpen: false,
scrollParent: null,
transformParent: null,
visibleDirection: _this.props.direction,
};
_this.componentDidMount = function () {
_this.props.isOpen && _this.forceUpdate();
_this.addHandlers();
};
_this.componentDidUpdate = function (prevProps, prevState) {
var direction = _this.props.direction;
var isOpen = _this.state.isOpen;
if ((isOpen && prevState.isOpen !== isOpen) || prevProps.direction !== direction) {
return _this.forceUpdate(function () { return _this.isVisible(); });
}
else if (!isOpen && prevState.isOpen !== isOpen) {
_this.focusOnAnchorNode();
}
};
_this.componentWillUnmount = function () {
_this.removeHandlers();
};
_this.addHandlers = function () {
var _a = _this.props, absoluteParentID = _a.absoluteParentID, allowClickAway = _a.allowClickAway, boundingParentID = _a.boundingParentID, checkOverflow = _a.checkOverflow, closeOnClick = _a.closeOnClick, isContained = _a.isContained, scrollParentID = _a.scrollParentID, transformParentID = _a.transformParentID;
_this.handleResize = _this.isVisible;
_this.handleScroll = _this.isVisible;
var element = ReactDOM.findDOMNode(_this.container);
var elementParent = element && element.parentElement;
var elementParents = elementParent && _this.findParents(elementParent);
var scrollParent;
if (allowClickAway) {
document.addEventListener('click', _this.handleAllowClickAway, true);
document.addEventListener('keydown', _this.handleKeyDown, false);
}
closeOnClick && document.addEventListener('click', _this.handleCloseOnClick, false);
window.addEventListener('resize', _this.handleResize, false);
document.addEventListener('scroll', _this.handleScroll, false);
if (scrollParentID) {
scrollParent = document.getElementById(scrollParentID);
scrollParent && scrollParent.addEventListener('scroll', _this.handleScroll, false);
}
if (checkOverflow) {
scrollParent =
!scrollParent &&
elementParents &&
_this.findScrollParent(elementParents, ['overflow', 'overflow-y', 'overflow-x']);
scrollParent && scrollParent.addEventListener('scroll', _this.handleScroll, false);
}
var transformParent = transformParentID
? document.getElementById(transformParentID)
: elementParents && _this.findTransformParent(elementParents, ['transform'], 1);
var absoluteParent = absoluteParentID
? document.getElementById(absoluteParentID)
: elementParents && _this.findAbsoluteParent(elementParents, ['position'], 1);
var containerParent = (isContained && document.getElementById(boundingParentID)) || scrollParent;
_this.observer = new MutationObserver(_this.isVisible);
_this.observer.observe(document.body, {
attributes: false,
characterData: false,
childList: true,
subtree: true,
attributeOldValue: false,
characterDataOldValue: false,
});
_this.setState({
absoluteParent: absoluteParent,
containerParent: containerParent,
scrollParent: scrollParent,
transformParent: transformParent,
}, function () { return _this.isVisible(); });
};
_this.findOverflow = function (node, searchProps) {
return searchProps.reduce(function (agg, prop) {
var overflowElement = window.getComputedStyle(ReactDOM.findDOMNode(node))[prop];
return !overflowElement || agg.includes(overflowElement) ? agg : (agg += overflowElement);
}, '');
};
_this.findParents = function (ele, tempParentArr) {
if (tempParentArr === void 0) { tempParentArr = []; }
return !ele.parentElement
? tempParentArr
: _this.findParents(ele.parentElement, tempParentArr.concat(ele));
};
_this.findAbsoluteParent = function (elementParents, searchProps, startIndex) {
var absoluteElement;
var idx = startIndex;
while (!absoluteElement && elementParents[idx]) {
var currentAbsoluteElement = _this.findOverflow(elementParents[idx], searchProps);
if (/(absolute)/.test(currentAbsoluteElement)) {
return (absoluteElement = elementParents[idx]);
}
idx++;
}
return absoluteElement ? absoluteElement : null;
};
_this.findScrollParent = function (elementParents, searchProps) {
var overflowElement = null;
var idx = 1;
while (!overflowElement && elementParents[idx]) {
var currentOverflowElement = _this.findOverflow(elementParents[idx], searchProps);
if (/(auto|scroll|hidden)/.test(currentOverflowElement)) {
return (overflowElement = elementParents[idx]);
}
idx++;
}
return overflowElement ? overflowElement : null;
};
_this.findTransformParent = function (elementParents, searchProps, startIndex) {
var transformElement = null;
var idx = startIndex;
while (!transformElement && elementParents[idx]) {
var potentialTransformElement = _this.findOverflow(elementParents[idx], ['will-change']);
var currentTransformElement = _this.findOverflow(elementParents[idx], searchProps);
if (/(transform)/.test(potentialTransformElement) || currentTransformElement !== 'none') {
return (transformElement = elementParents[idx]);
}
idx++;
}
return transformElement ? transformElement : null;
};
_this.focusOnAnchorNode = function () {
var anchorNode = _this.props.anchorNode;
if (anchorNode) {
var domAnchorNode = (anchorNode.props ? anchorNode.props.onClick : false) && ReactDOM.findDOMNode(anchorNode);
if (domAnchorNode) {
domAnchorNode.focus();
}
else if (anchorNode.focus) {
// handle fallback for MRv2 trigger elements (functional components)
anchorNode.focus();
}
}
};
_this.getAnchorPosition = function (node) {
var transformParent = _this.state.transformParent;
var rect = node.getBoundingClientRect();
var transformParentDims = transformParent && _this.getElementPosition(transformParent);
var parentRect = transformParentDims || defaultDims;
var anchorPosition = {
top: rect.top - parentRect.top,
left: rect.left - parentRect.left,
width: node.offsetWidth,
height: node.offsetHeight,
};
anchorPosition.right =
(rect.right || anchorPosition.left + anchorPosition.width) - parentRect.left;
anchorPosition.bottom =
(rect.bottom || anchorPosition.top + anchorPosition.height) - parentRect.top;
anchorPosition.middle = anchorPosition.left + (anchorPosition.right - anchorPosition.left) / 2;
anchorPosition.center = anchorPosition.top + (anchorPosition.bottom - anchorPosition.top) / 2;
return anchorPosition;
};
_this.getAbsoluteAnchorPosition = function (node, absoluteParentDims) {
var scrollParent = _this.state.scrollParent;
var rect = node.getBoundingClientRect();
var parentRect = absoluteParentDims;
var scrollAdjust = (scrollParent && scrollParent.scrollTop) || 0;
var anchorPosition = {
top: absoluteParentDims.offsetTop
? absoluteParentDims.offsetTop + node.offsetTop - scrollAdjust
: rect.top - parentRect.top,
left: absoluteParentDims.offsetLeft
? absoluteParentDims.offsetLeft - node.offsetLeft
: rect.left - parentRect.left,
width: node.offsetWidth,
height: node.offsetHeight,
};
anchorPosition.right =
(rect.right || anchorPosition.left + anchorPosition.width) - parentRect.left;
anchorPosition.bottom = anchorPosition.top + anchorPosition.height;
anchorPosition.middle = anchorPosition.left + (anchorPosition.right - anchorPosition.left) / 2;
anchorPosition.center = anchorPosition.top + (anchorPosition.bottom - anchorPosition.top) / 2;
return anchorPosition;
};
_this.getElementPosition = function (element) {
var elementRect = element.getBoundingClientRect();
return {
offsetTop: element.offsetTop,
offsetLeft: element.offsetLeft,
bottom: elementRect.bottom,
top: elementRect.top,
left: elementRect.left,
height: elementRect.height,
width: elementRect.width,
hasAbsParent: element.offsetTop !== elementRect.top || element.offsetLeft !== elementRect.left,
};
};
_this.getOrigin = function () {
var side = _this.state.visibleDirection.split('-')[0];
var alignment = _this.props.direction.split('-')[1];
var origin = {
anchor: {},
target: {},
};
if (side === 'top' || side === 'bottom') {
origin.anchor.vertical = side;
origin.anchor.horizontal = alignment === 'center' ? 'middle' : alignment;
origin.target.vertical = side === 'top' ? 'bottom' : 'top';
origin.target.horizontal = alignment === 'center' ? 'middle' : alignment;
}
if (side === 'left' || side === 'right') {
origin.anchor.vertical = alignment;
origin.anchor.horizontal = side;
origin.target.vertical = alignment;
origin.target.horizontal = side === 'left' ? 'right' : 'left';
}
return origin;
};
_this.getTargetPosition = function (targetNode) {
return {
top: 0,
center: targetNode.offsetHeight / 2,
bottom: targetNode.offsetHeight,
left: 0,
middle: targetNode.offsetWidth / 2,
right: targetNode.offsetWidth,
};
};
_this.handleAllowClickAway = function (e) {
if (!_this.props.isOpen)
return;
var eventTarget = eventPath(e)[0];
var anchorNode = ReactDOM.findDOMNode(_this.props.anchorNode);
return (_this.container &&
!anchorNode.contains(eventTarget) &&
!ReactDOM.findDOMNode(_this.container).contains(eventTarget) &&
_this.handleClickAway(e));
};
_this.handleClickAway = function (e) {
var close = _this.props.close;
_this.focusOnAnchorNode();
close && close(e);
};
_this.handleCloseOnClick = function (e) {
if (!_this.props.isOpen)
return;
var eventTarget = eventPath(e)[0];
var closeOnClick = _this.props.closeOnClick;
return (closeOnClick &&
_this.container &&
ReactDOM.findDOMNode(_this.container).contains(eventTarget) &&
_this.handleClickAway(e));
};
_this.handleKeyDown = function (e) {
var _a = _this.props, isOpen = _a.isOpen, disableCloseOnEnterOrSpaceKey = _a.disableCloseOnEnterOrSpaceKey;
if (!isOpen)
return;
if (e.keyCode === 27)
return _this.handleClickAway(e);
if (!disableCloseOnEnterOrSpaceKey ||
(disableCloseOnEnterOrSpaceKey && e.which !== 13 && e.which !== 32)) {
var eventTarget = eventPath(e)[0];
var anchorNode = ReactDOM.findDOMNode(_this.props.anchorNode);
return (_this.container &&
anchorNode &&
!anchorNode.contains(eventTarget) &&
!ReactDOM.findDOMNode(_this.container).contains(eventTarget) &&
_this.handleClickAway(e));
}
};
_this.isVisible = function () {
var _a = _this.props, anchorNode = _a.anchorNode, direction = _a.direction, isOpen = _a.isOpen, isDynamic = _a.isDynamic;
if (!isOpen)
return;
if (!isDynamic)
return _this.setPlacement();
var anchorElement = ReactDOM.findDOMNode(anchorNode);
var element = ReactDOM.findDOMNode(_this.container);
var side = direction.split('-')[0];
var alignment = direction.split('-')[1];
var anchorDims = anchorElement && anchorElement.getBoundingClientRect();
var elementBoundingRect = element.getBoundingClientRect();
var elementParent = element.parentElement;
['top', 'bottom'].includes(side)
? _this.setVerticalClass(alignment, anchorDims, elementBoundingRect, elementParent)
: _this.setHorizontalClass(alignment, anchorDims, elementBoundingRect, elementParent);
};
_this.removeHandlers = function () {
var scrollParent = _this.state.scrollParent;
document.removeEventListener('click', _this.handleAllowClickAway, true);
document.removeEventListener('click', _this.handleCloseOnClick, false);
document.removeEventListener('keydown', _this.handleKeyDown, false);
window.removeEventListener('resize', _this.handleResize, false);
document.removeEventListener('scroll', _this.handleScroll, false);
scrollParent && scrollParent.removeEventListener('scroll', _this.handleScroll, false);
_this.observer && _this.observer.disconnect() && _this.observer.takeRecords();
};
_this.setArrowPlacement = function (anchor, container) {
var arrow = _this.arrow;
var targetOffset = _this.props.targetOffset;
var visibleDirection = _this.state.visibleDirection;
var side = visibleDirection.split('-')[0];
var verticalOffset = targetOffset.vertical || 0;
var horizontalOffset = targetOffset.horizontal || 0;
var isAnchorWider = anchor.width > container.right;
var isAnchorTaller = anchor.height > container.bottom;
var arrowLeft = isAnchorWider && !visibleDirection.includes('center')
? visibleDirection.includes('left')
? container.middle + anchor.left
: anchor.right - container.middle
: anchor.middle;
var arrowTop = isAnchorTaller && !visibleDirection.includes('center')
? visibleDirection.includes('top')
? container.center + anchor.top
: anchor.bottom - container.center
: anchor.center;
switch (side) {
case 'top':
arrow.style.left = "".concat(arrowLeft, "px");
arrow.style.top = "".concat(anchor.top - verticalOffset, "px");
break;
case 'bottom':
arrow.style.left = "".concat(arrowLeft, "px");
arrow.style.top = "".concat(anchor.bottom + verticalOffset, "px");
break;
case 'left':
arrow.style.left = "".concat(anchor.left - horizontalOffset, "px");
arrow.style.top = "".concat(arrowTop, "px");
break;
case 'right':
arrow.style.left = "".concat(anchor.right + horizontalOffset, "px");
arrow.style.top = "".concat(arrowTop, "px");
break;
}
};
_this.setBoundingBox = function (side, targetNode, anchorPosition) {
var _a = _this.props, checkOverflow = _a.checkOverflow, isContained = _a.isContained, maxHeight = _a.maxHeight, maxWidth = _a.maxWidth, showArrow = _a.showArrow, targetOffset = _a.targetOffset;
var _b = _this.state, absoluteParent = _b.absoluteParent, scrollParent = _b.scrollParent, transformParent = _b.transformParent;
var arrowDims = showArrow && ReactDOM.findDOMNode(_this.arrow).getBoundingClientRect();
var checkVertical = isContained === 'vertical';
var checkHorizontal = isContained === 'horizontal';
var element = ReactDOM.findDOMNode(_this.container);
var documentScrollTop = document.documentElement.scrollTop;
var documentBottom = document.documentElement.scrollHeight;
var windowBottom = window.pageXOffset + window.innerHeight;
var documentRight = Math.max(document.documentElement.offsetWidth, document.documentElement.clientWidth);
var arrowHeight = (arrowDims && arrowDims.height) || 0;
var arrowWidth = (arrowDims && arrowDims.width) || 0;
var offsetHeight = targetOffset.vertical || 0;
var offsetWidth = targetOffset.horizontal || 0;
var elementDims = element.getBoundingClientRect();
var elementVerticalHeight = elementDims.height + offsetHeight;
var elementVerticalWidth = elementDims.width + offsetWidth;
var getAvailableTopSpace = function (top) {
return top + anchorPosition.top - (_this.elementHeight + arrowHeight);
};
var scrollParentDimsv2 = _this.setBoundingContainer(scrollParent);
var scrollParentDims = scrollParent ? scrollParent.getBoundingClientRect() : defaultDims;
var absoluteParentDims = absoluteParent && _this.getElementPosition(absoluteParent);
var transformParentDims = transformParent && _this.getElementPosition(transformParent);
var scrollParentScrollTop = (scrollParent && scrollParent.offsetTop) || 0;
if (targetNode && targetNode.style && !targetNode.style.bottom && elementVerticalHeight) {
_this.elementHeight = elementVerticalHeight;
_this.elementBottom = elementDims.bottom;
}
if (targetNode && targetNode.style && !targetNode.style.right && elementVerticalWidth) {
_this.elementWidth = elementVerticalWidth;
_this.elementLeft = elementDims.left;
_this.elementRight = elementDims.right;
}
switch (side) {
case 'top':
if (!scrollParent && !transformParentDims) {
if (!checkHorizontal) {
targetNode.style.bottom = "".concat(windowBottom - anchorPosition.top + arrowHeight + offsetHeight, "px");
if (getAvailableTopSpace(documentScrollTop) < 0) {
targetNode.style.top = "".concat(arrowHeight - documentScrollTop, "px");
}
}
if (!checkVertical) {
if (elementDims.right > documentRight || _this.elementWidth > documentRight) {
targetNode.style.right = '0px';
if (_this.elementWidth < documentRight) {
targetNode.style.left = "".concat(documentRight - _this.elementWidth, "px");
}
}
if (_this.elementLeft < 0) {
targetNode.style.left = '0px';
}
}
}
else {
if (transformParentDims) {
targetNode.style.bottom = "".concat(transformParentDims.height - anchorPosition.top + arrowHeight + offsetHeight, "px");
if (anchorPosition.top - scrollParentScrollTop - _this.elementHeight - arrowHeight < 0) {
targetNode.style.top = "".concat(scrollParentScrollTop + arrowHeight, "px");
targetNode.style.maxHeight = "".concat(maxHeight || transformParentDims.height, "px");
}
if (!checkVertical) {
if (_this.elementWidth > transformParentDims.width ||
_this.elementRight > transformParentDims.right) {
targetNode.style.right = "".concat(0, "px");
if (_this.elementWidth > transformParentDims.width) {
targetNode.style.left = "0px";
}
else {
targetNode.style.left = "".concat(_this.elementWidth, "px");
}
}
if (_this.elementLeft < transformParentDims.left) {
targetNode.style.left = "".concat(0, "px");
}
}
if (arrowDims &&
(arrowDims.top - (scrollParent ? scrollParentDims.top : transformParentDims.top) <
0 ||
arrowDims.bottom + 1 >
(scrollParent ? scrollParentDims.bottom : transformParentDims.bottom))) {
_this.arrow.style.visibility = 'hidden';
}
else if (arrowDims) {
_this.arrow.style.visibility = 'visible';
}
}
else {
targetNode.style.bottom = "".concat(windowBottom - anchorPosition.top + arrowHeight + offsetHeight, "px");
if (!checkHorizontal) {
if (anchorPosition.top - scrollParentDimsv2.top - _this.elementHeight - arrowHeight <
0) {
targetNode.style.top = "".concat(scrollParentDimsv2.top + arrowHeight, "px");
targetNode.style.maxHeight = "".concat(maxHeight || scrollParentDimsv2.height, "px");
}
}
if (!checkVertical) {
if (_this.elementWidth > scrollParentDimsv2.width ||
_this.elementRight > scrollParentDimsv2.right) {
targetNode.style.right = "".concat(documentRight - scrollParentDimsv2.right, "px");
}
if (_this.elementLeft < scrollParentDimsv2.left) {
targetNode.style.left = "".concat(scrollParentDimsv2.left, "px");
}
}
if (arrowDims &&
(arrowDims.top < scrollParentDims.top ||
arrowDims.bottom + 1 > scrollParentDims.bottom)) {
_this.arrow.style.visibility = 'hidden';
}
else if (arrowDims) {
_this.arrow.style.visibility = 'visible';
}
}
}
break;
case 'bottom':
if (!scrollParentDims.bottom && !transformParentDims) {
if (_this.elementHeight + arrowHeight + anchorPosition.bottom + documentScrollTop >
documentBottom) {
targetNode.style.bottom = "".concat(documentScrollTop + windowBottom - documentBottom, "px");
}
if (elementDims.right >= documentRight || _this.elementWidth > documentRight) {
targetNode.style.right = '0px';
if (_this.elementWidth < documentRight) {
targetNode.style.left = 'inherit';
}
}
if (elementDims.left < 0) {
targetNode.style.left = '0px';
}
}
else if (scrollParentDims.bottom && !transformParentDims) {
targetNode.style.bottom = 'auto';
if (anchorPosition.bottom + arrowHeight - scrollParentDims.top < 0) {
targetNode.style.top = "".concat(scrollParentDims.top - arrowHeight, "px");
}
if (_this.elementHeight + arrowHeight + anchorPosition.bottom > scrollParentDims.bottom) {
targetNode.style.bottom = "".concat(windowBottom - scrollParentDims.bottom, "px");
targetNode.style.maxHeight = "".concat(maxHeight || scrollParentDims.height, "px");
}
if (_this.elementWidth > scrollParentDims.width ||
_this.elementRight > scrollParentDims.right) {
targetNode.style.right = "".concat(documentRight - scrollParentDims.right, "px");
}
if (_this.elementLeft < scrollParentDims.left) {
targetNode.style.left = "".concat(scrollParentDims.left, "px");
}
if (arrowDims &&
(arrowDims.top < scrollParentDims.top || arrowDims.bottom + 1 > scrollParentDims.bottom)) {
_this.arrow.style.visibility = 'hidden';
}
else if (arrowDims) {
_this.arrow.style.visibility = 'visible';
}
}
else {
if (anchorPosition.bottom + arrowHeight + offsetHeight <
scrollParentDims.top - transformParentDims.top) {
targetNode.style.top = "".concat(scrollParentDims.top - transformParentDims.top - arrowHeight, "px");
}
if (_this.elementHeight + arrowHeight + anchorPosition.bottom >
transformParentDims.height + ((absoluteParentDims && absoluteParentDims.offsetTop) || 0)) {
targetNode.style.bottom = "0px";
}
if (_this.elementLeft < transformParentDims.left) {
targetNode.style.left = "0px";
}
if (_this.elementWidth > transformParentDims.width ||
_this.elementRight > transformParentDims.right) {
targetNode.style.right = "0px";
if (_this.elementWidth > transformParentDims.width) {
targetNode.style.left = "0px";
}
else {
targetNode.style.left = "".concat(transformParentDims.width - _this.elementWidth, "px");
}
}
if (arrowDims &&
(arrowDims.top < (checkOverflow ? scrollParentDims.top : transformParentDims.top) ||
arrowDims.bottom + 1 >
(checkOverflow ? scrollParentDims.bottom : transformParentDims.bottom))) {
_this.arrow.style.visibility = 'hidden';
}
else if (arrowDims) {
_this.arrow.style.visibility = 'visible';
}
}
break;
case 'left':
if (!scrollParentDims.left && !transformParentDims) {
targetNode.style.right = "".concat(documentRight - anchorPosition.left + arrowWidth + offsetWidth, "px");
if (elementDims.left - arrowWidth < 0) {
targetNode.style.left = "".concat(arrowWidth, "px");
}
else {
targetNode.style.left = 'inherit';
}
if (getAvailableTopSpace(documentScrollTop) < 0) {
targetNode.style.top = "".concat(-documentScrollTop, "px");
}
if (_this.elementHeight + arrowHeight + anchorPosition.bottom + documentScrollTop >
documentBottom) {
targetNode.style.bottom = "".concat(documentScrollTop + windowBottom - documentBottom, "px");
}
}
else if (scrollParentDims.left && !transformParentDims) {
if (anchorPosition.left - scrollParentDims.left < _this.elementWidth + arrowWidth) {
targetNode.style.left = "".concat(scrollParentDims.left + arrowWidth, "px");
targetNode.style.right = "".concat(documentRight - anchorPosition.left + arrowWidth + offsetWidth, "px");
targetNode.style.maxWidth = "".concat(maxWidth || scrollParentDims.width, "px");
}
if (anchorPosition.top - scrollParentDims.top - _this.elementHeight < 0) {
targetNode.style.top = "".concat(scrollParentDims.top, "px");
}
if (_this.elementHeight + anchorPosition.bottom > scrollParentDims.bottom) {
targetNode.style.bottom = "".concat(windowBottom - scrollParentDims.bottom, "px");
}
if (arrowDims &&
(arrowDims.top < scrollParentDims.top || arrowDims.bottom > scrollParentDims.bottom)) {
_this.arrow.style.visibility = 'hidden';
}
else if (arrowDims) {
_this.arrow.style.visibility = 'visible';
}
}
break;
case 'right':
if (!scrollParentDims.right && !transformParentDims) {
if (arrowWidth + offsetWidth + elementDims.width + anchorPosition.right > documentRight) {
targetNode.style.right = '0px';
}
if (getAvailableTopSpace(documentScrollTop) < 0) {
targetNode.style.top = "".concat(-documentScrollTop, "px");
}
if (_this.elementHeight + arrowHeight + anchorPosition.bottom + documentScrollTop >
documentBottom) {
targetNode.style.bottom = "".concat(documentScrollTop + windowBottom - documentBottom, "px");
}
}
else if (scrollParentDims.right && !transformParentDims) {
if (anchorPosition.right + _this.elementWidth + arrowWidth > scrollParentDims.right) {
targetNode.style.left = "".concat(anchorPosition.right + offsetWidth, "px");
targetNode.style.right = transformParentDims
? "".concat(scrollParentDims.width, "px")
: "".concat(documentRight - scrollParentDims.right, "px");
targetNode.style.maxWidth = "".concat(maxWidth || scrollParentDims.width, "px");
}
if (anchorPosition.top - scrollParentDims.top - _this.elementHeight < 0) {
targetNode.style.top = "".concat(scrollParentDims.top, "px");
}
if (_this.elementHeight + anchorPosition.bottom > scrollParentDims.bottom) {
targetNode.style.bottom = "".concat(windowBottom - scrollParentDims.bottom, "px");
}
if (arrowDims &&
(arrowDims.top < scrollParentDims.top || arrowDims.bottom > scrollParentDims.bottom)) {
_this.arrow.style.visibility = 'hidden';
}
else if (arrowDims) {
_this.arrow.style.visibility = 'visible';
}
}
break;
}
};
_this.setBoundingContainer = function (containerNode) {
var _a = _this.props, boundingParentID = _a.boundingParentID, isContained = _a.isContained;
var containerParent = _this.state.containerParent;
var containerNodeDims = (containerNode && containerNode.getBoundingClientRect()) || defaultDims;
var containerParentDims = (containerParent && containerParent.getBoundingClientRect()) || defaultDims;
var checkVertical = isContained === true || isContained === 'vertical';
var checkHorizontal = isContained === true || isContained === 'horizontal';
return {
bottom: checkVertical && boundingParentID ? containerParentDims.bottom : containerNodeDims.bottom,
center: 0,
height: checkVertical && boundingParentID ? containerParentDims.height : containerNodeDims.height,
left: checkHorizontal && boundingParentID ? containerParentDims.left : containerNodeDims.left,
middle: 0,
right: checkHorizontal && boundingParentID ? containerParentDims.right : containerNodeDims.right,
top: checkVertical && boundingParentID ? containerParentDims.top : containerNodeDims.top,
width: checkHorizontal && boundingParentID ? containerParentDims.width : containerNodeDims.width,
};
};
_this.setHorizontalClass = function (alignment, anchor, elementBoundingRect, elementParent) {
var _a = _this.props, showArrow = _a.showArrow, checkOverflow = _a.checkOverflow, targetOffset = _a.targetOffset, scrollParentID = _a.scrollParentID;
var windowRight = window.pageYOffset + window.innerWidth;
var elementWidth = elementBoundingRect.width;
var anchorRight = anchor.right;
var arrowWidth = showArrow
? ReactDOM.findDOMNode(_this.arrow).getBoundingClientRect().width
: 0;
var offsetWidth = targetOffset.horizontal || 0;
var totalWidth = anchorRight + elementWidth + arrowWidth + offsetWidth;
var elementParents = _this.findParents(elementParent);
var scrollParent = scrollParentID
? React.findDOMNode(scrollParentID)
: _this.findScrollParent(elementParents, ['overflow', 'overflow-x']);
var parentRight = (checkOverflow &&
!!scrollParent.getBoundingClientRect &&
scrollParent.getBoundingClientRect().right) ||
windowRight;
return totalWidth < parentRight && totalWidth < windowRight
? _this.setState({ visibleDirection: "right-".concat(alignment) }, function () { return _this.setPlacement(); })
: _this.setState({ visibleDirection: "left-".concat(alignment) }, function () { return _this.setPlacement(); });
};
_this.setPlacement = function () {
var _a = _this.props, anchorNode = _a.anchorNode, isOpen = _a.isOpen, isContained = _a.isContained, showArrow = _a.showArrow, targetOffset = _a.targetOffset;
var _b = _this.state, visibleDirection = _b.visibleDirection, absoluteParent = _b.absoluteParent, transformParent = _b.transformParent;
if (!isOpen)
return;
var anchorElement = ReactDOM.findDOMNode(anchorNode);
var side = visibleDirection.split('-')[0];
var targetNode = _this.container;
var verticalOffset = targetOffset.vertical || 0;
var horizontalOffset = targetOffset.horizontal || 0;
var absoluteParentDims = absoluteParent && _this.getElementPosition(absoluteParent);
if (!targetNode || !anchorElement)
return;
anchorElement.link = _this.state.id;
var anchorPosition = !!transformParent && absoluteParentDims && absoluteParentDims.hasAbsParent
? _this.getAbsoluteAnchorPosition(anchorElement, absoluteParentDims)
: _this.getAnchorPosition(anchorElement);
var targetPosition = _this.getTargetPosition(targetNode);
var origin = _this.getOrigin();
var anchorOrigin = origin.anchor;
var targetOrigin = origin.target;
var targetNodePosition = {
top: anchorPosition[anchorOrigin.vertical] -
targetPosition[targetOrigin.vertical] +
(side === 'top' ? -verticalOffset : verticalOffset),
left: anchorPosition[anchorOrigin.horizontal] -
targetPosition[targetOrigin.horizontal] +
(side === 'left' ? -horizontalOffset : horizontalOffset),
};
targetNode.style.top = "".concat(targetNodePosition.top, "px");
targetNode.style.left = "".concat(targetNodePosition.left, "px");
showArrow && _this.setArrowPlacement(anchorPosition, targetPosition);
isContained && _this.setBoundingBox(side, targetNode, anchorPosition);
};
_this.setVerticalClass = function (alignment, anchor, elementBoundingRect, elementParent) {
var _a = _this.props, showArrow = _a.showArrow, checkOverflow = _a.checkOverflow, targetOffset = _a.targetOffset, scrollParentID = _a.scrollParentID;
var windowBottom = window.pageXOffset + window.innerHeight;
var elementHeight = elementBoundingRect.height;
var anchorBottom = anchor.bottom;
var arrowHeight = showArrow
? ReactDOM.findDOMNode(_this.arrow).getBoundingClientRect().height
: 0;
var offsetHeight = targetOffset.vertical || 0;
var totalHeight = anchorBottom + elementHeight + arrowHeight + offsetHeight;
var elementParents = _this.findParents(elementParent);
var scrollParent = scrollParentID
? React.findDOMNode(scrollParentID)
: _this.findScrollParent(elementParents, ['overflow', 'overflow-x']);
var parentBottom = (checkOverflow &&
!!scrollParent.getBoundingClientRect &&
scrollParent.getBoundingClientRect().bottom) ||
windowBottom;
return totalHeight < parentBottom && totalHeight < windowBottom
? _this.setState({ visibleDirection: "bottom-".concat(alignment) }, function () { return _this.setPlacement(); })
: _this.setState({ visibleDirection: "top-".concat(alignment) }, function () { return _this.setPlacement(); });
};
return _this;
}
EventOverlay.getDerivedStateFromProps = function (_a, state) {
var isOpen = _a.isOpen;
return __assign(__assign({}, state), { isOpen: isOpen });
};
EventOverlay.prototype.render = function () {
var _this = this;
var _a = this.props, children = _a.children, className = _a.className, focusLockProps = _a.focusLockProps, isOpen = _a.isOpen, maxHeight = _a.maxHeight, maxWidth = _a.maxWidth, portalNode = _a.portalNode, shouldLockFocus = _a.shouldLockFocus, showArrow = _a.showArrow, style = _a.style, props = __rest(_a, ["children", "className", "focusLockProps", "isOpen", "maxHeight", "maxWidth", "portalNode", "shouldLockFocus", "showArrow", "style"]);
var side = this.state.visibleDirection.split('-')[0];
var otherProps = omit(__assign({}, props), [
'absoluteParentID',
'allowClickAway',
'anchorNode',
'boundingParentID',
'checkOverflow',
'close',
'closeOnClick',
'direction',
'disableCloseOnEnterOrSpaceKey',
'isDynamic',
'isContained',
'scrollParentID',
'targetOffset',
'transformParentID',
]);
var contentNodes = isOpen && (React.createElement("div", { className: 'md-event-overlay' +
"".concat((showArrow && " md-event-overlay--arrow") || '') +
"".concat((side && " md-event-overlay--".concat(side)) || '') +
"".concat((className && " ".concat(className)) || '') },
showArrow && React.createElement("div", { ref: function (ref) { return (_this.arrow = ref); }, className: "md-event-overlay__arrow" }),
React.createElement("div", __assign({ className: "md-event-overlay__children", ref: function (ref) { return (_this.container = ref); }, style: __assign(__assign(__assign({}, (maxWidth && { maxWidth: "".concat(maxWidth, "px") })), (maxHeight && { maxHeight: "".concat(maxHeight, "px") })), style) }, otherProps), children)));
var withFocusLock = function (content) {
return shouldLockFocus ? (React.createElement(FocusScope, __assign({}, focusLockProps, { contain: true }), content)) : (content);
};
var withPortal = function (content) {
return portalNode ? ReactDOM.createPortal(content, portalNode) : content;
};
return withFocusLock(withPortal(contentNodes));
};
return EventOverlay;
}(React.Component));
EventOverlay.defaultProps = {
absoluteParentID: null,
allowClickAway: true,
anchorNode: null,
boundingParentID: null,
children: null,
checkOverflow: false,
className: '',
close: null,
direction: 'bottom-left',
disableCloseOnEnterOrSpaceKey: false,
focusLockProps: null,
isContained: '',
isDynamic: false,
isOpen: false,
maxHeight: null,
maxWidth: null,
portalNode: null,
scrollParentID: null,
shouldLockFocus: false,
showArrow: false,
style: null,
targetOffset: {
horizontal: 0,
vertical: 0,
},
transformParentID: null,
};
EventOverlay.propTypes = {
/** @prop Set the id of the absoluteParent | null */
absoluteParentID: PropTypes.string,
/** @prop Allows user to click outside of EventOverlay | true */
allowClickAway: PropTypes.bool,
/** @prop Node which serves as basis of dom positioning | null */
anchorNode: PropTypes.object,
/** @prop Set the id of the boundingParent | null */
boundingParentID: PropTypes.string,
/** @prop Set to determine if dom ancestors have overflow property | false */
checkOverflow: PropTypes.bool,
/** @prop Children nodes to render inside the EventOverlay | null */
children: PropTypes.node,
/** @prop Optional css class string | '' */
className: PropTypes.string,
/** @prop Function to close EventOverlay | null */
close: PropTypes.func,
/** @prop Determines if the EventOverlay should close when clicked on | true */
closeOnClick: PropTypes.bool,
/** @prop Sets the direction in which the EventOverlay extends | 'bottom-left' */
direction: PropTypes.oneOf([
'top-center',
'left-center',
'right-center',
'bottom-center',
'top-left',
'top-right',
'bottom-left',
'bottom-right',
'left-top',
'left-bottom',
'right-top',
'right-bottom',
]),
/** @prop Prevent closing on ENTER or SPACE keydown event | false */
disableCloseOnEnterOrSpaceKey: PropTypes.bool,
/** @prop Props to be passed to focus lock component | null */
focusLockProps: PropTypes.object,
/** @prop Determines if the overlay is contained in bounding ancestor | '' */
isContained: PropTypes.oneOf([true, false, 'horizontal', 'vertical', 'both', '']),
/** @prop When true, will flip children based on space available (does not work with isContained) | false */
isDynamic: PropTypes.bool,
/** @prop Sets the visibility of the EventOverlay | false */
isOpen: PropTypes.bool,
/** @prop Sets the max h