UNPKG

@brizy/ui

Version:
83 lines (82 loc) 3.32 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ClickOutside = void 0; const react_1 = __importDefault(require("react")); const react_dom_1 = __importDefault(require("react-dom")); const instances = []; class ClickOutside extends react_1.default.Component { constructor() { super(...arguments); this.handleAll = (e) => { const el = e.target; instances.forEach(instance => { const { exceptions, onClickOutside } = instance.props; let exceptionsCount = 0; if (exceptions.length > 0) { const { functionExceptions, stringExceptions } = exceptions.reduce((acc, exception) => { switch (typeof exception) { case "function": acc.functionExceptions.push(exception); break; case "string": acc.stringExceptions.push(exception); break; } return acc; }, { functionExceptions: [], stringExceptions: [] }); if (functionExceptions.length > 0) { exceptionsCount += functionExceptions.filter(exception => exception(el)).length; } if (exceptionsCount === 0 && stringExceptions.length > 0) { exceptionsCount += el.closest(stringExceptions.join(",")) ? 1 : 0; } } if (exceptionsCount === 0) { // eslint-disable-next-line react/no-find-dom-node const node = react_dom_1.default.findDOMNode(instance); if (node && !node.contains(el)) { onClickOutside(e); } } }); }; } componentDidMount() { // we add just one listener for all instances // because otherwise we would end up with tens of // listeners on the document // (and it's a little faster when adding just one) if (instances.length === 0) { try { document.addEventListener("mousedown", this.handleAll, true); window.parent.document.addEventListener("mousedown", this.handleAll, true); } catch (error) { console.error(error); } } instances.push(this); } componentWillUnmount() { instances.splice(instances.indexOf(this), 1); if (instances.length === 0) { try { document.removeEventListener("mousedown", this.handleAll, true); window.parent.document.removeEventListener("mousedown", this.handleAll, true); } catch (error) { console.error(error); } } } render() { return react_1.default.Children.only(this.props.children); } } exports.ClickOutside = ClickOutside; ClickOutside.defaultProps = { exceptions: [], };