@itwin/core-react
Version:
A react component library of iTwin.js UI general purpose components
107 lines • 4.93 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
* @module Common
*/
import * as React from "react";
/** withOnOutsideClick is a React higher-order component that adds outside click support.
* @public
* @deprecated in 4.15.0. Used internally.
*/
export const withOnOutsideClick = (Component, defaultOnOutsideClick, useCapture = true, usePointerEvents = true) => {
return class WithOnOutsideClick extends React.PureComponent {
/** @internal */
outsideClickContainerDiv = null;
/** @internal */
isDownOutside = false;
/** @internal */
isInCorePopup(element) {
if (element.nodeName === "DIV") {
if (element.classList && element.classList.contains("core-popup"))
return true;
if (element.parentElement && this.isInCorePopup(element.parentElement))
return true;
}
else {
if (element.parentElement && this.isInCorePopup(element.parentElement))
return true;
}
return false;
}
/** @internal */
onOutsideClick(e) {
if (e.target instanceof Node && e.target.nodeType === Node.ELEMENT_NODE) {
if (!this.props.closeOnNestedPopupOutsideClick &&
this.isInCorePopup(e.target))
return;
}
if (this.props.onOutsideClick)
return this.props.onOutsideClick(e);
else if (defaultOnOutsideClick)
return defaultOnOutsideClick(e);
}
/** @internal */
handleDocumentClick = (e) => {
if (!this.outsideClickContainerDiv ||
!(e.target instanceof Node) ||
this.outsideClickContainerDiv.contains(e.target))
return;
return this.onOutsideClick(e);
};
/** @internal */
handleDocumentPointerDown = (e) => {
this.isDownOutside = true;
if (this.outsideClickContainerDiv) {
// typically e.target test for instance of Node, but this is not working from pop out windows
this.isDownOutside =
!!e.target &&
!this.outsideClickContainerDiv.contains(e.target);
}
};
/** @internal */
handleDocumentPointerUp = (e) => {
let isUpOutside = true;
if (this.outsideClickContainerDiv) {
// typically e.target test for instance of Node, but this is not working from pop out windows
isUpOutside =
!!e.target &&
!this.outsideClickContainerDiv.contains(e.target);
}
const isOutsideClick = isUpOutside && this.isDownOutside;
this.isDownOutside = false;
isOutsideClick && this.onOutsideClick(e);
};
handleOutsideClickContainerDivSet = (outsideClickContainerDiv) => {
this.outsideClickContainerDiv = outsideClickContainerDiv;
};
getParentDocument() {
return this.outsideClickContainerDiv?.ownerDocument ?? document;
}
componentDidMount() {
const outsideClickParentDocument = this.getParentDocument();
if (usePointerEvents) {
outsideClickParentDocument.addEventListener("pointerdown", this.handleDocumentPointerDown, useCapture);
outsideClickParentDocument.addEventListener("pointerup", this.handleDocumentPointerUp, useCapture);
}
else
outsideClickParentDocument.addEventListener("click", this.handleDocumentClick, useCapture);
}
componentWillUnmount() {
const outsideClickParentDocument = this.getParentDocument();
if (usePointerEvents) {
outsideClickParentDocument.removeEventListener("pointerdown", this.handleDocumentPointerDown, useCapture);
outsideClickParentDocument.removeEventListener("pointerup", this.handleDocumentPointerUp, useCapture);
}
else
outsideClickParentDocument.removeEventListener("click", this.handleDocumentClick, useCapture);
}
render() {
const { onOutsideClick, closeOnNestedPopupOutsideClick, ...props } = this.props;
return (React.createElement("div", { ref: this.handleOutsideClickContainerDivSet },
React.createElement(Component, { ...props })));
}
};
};
//# sourceMappingURL=withOnOutsideClick.js.map