UNPKG

@momentum-ui/react-collaboration

Version:

Cisco Momentum UI Framework for React Collaboration Applications

907 lines 51.1 kB
/** @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