UNPKG

@mskcc/carbon-react

Version:

Carbon react components for the MSKCC DSM

72 lines (67 loc) 2.12 kB
/** * MSKCC 2021, 2024 */ import { defineProperty as _defineProperty } from '../_virtual/_rollupPluginBabelHelpers.js'; import PropTypes from 'prop-types'; import React__default from 'react'; /** * Generic component used for reacting to a click event happening outside of a * given `children` element. */ class ClickListener extends React__default.Component { static getEventTarget(evt) { // support Shadow DOM if (evt.composed && typeof evt.composedPath === 'function') { return evt.composedPath()[0]; } return evt.target; } constructor(props) { super(props); // We manually bind handlers in this Component, versus using class // properties, so that we can properly test the `handleRef` handler. this.handleRef = this.handleRef.bind(this); this.handleDocumentClick = this.handleDocumentClick.bind(this); } componentDidMount() { document.addEventListener('click', this.handleDocumentClick); } componentWillUnmount() { document.removeEventListener('click', this.handleDocumentClick); } handleDocumentClick(evt) { if (this.element) { if (this.element.contains && !this.element.contains(ClickListener.getEventTarget(evt))) { this.props.onClickOutside(evt); } } } handleRef(el) { const { children } = this.props; this.element = el; /** * One important note, `children.ref` corresponds to a `ref` prop passed in * directly to the child, not necessarily a `ref` defined in the component. * This means that here we target the following `ref` location: * * <ClickListener onClickOutside={() => {}}> * <Child ref={targetedRefHere} /> * </ClickListener> */ if (children.ref && typeof children.ref === 'function') { children.ref(el); } } render() { return /*#__PURE__*/React__default.cloneElement(this.props.children, { ref: this.handleRef }); } } _defineProperty(ClickListener, "propTypes", { children: PropTypes.element.isRequired, onClickOutside: PropTypes.func.isRequired }); export { ClickListener as default };