import React, { Component } from 'react';
import { jsx as _jsx } from "react/jsx-runtime";
export const OUTSIDE_CLICK_IGNORED_CLASS = 'outside-click-listener-ignore';
export class OutsideClickListener extends Component {
  static defaultProps = {
    onClickOutside: () => {},
    shouldCloseOnEsc: false
  };
  constructor(props) {
    super(props);
    this.setWrapperRef = this.setWrapperRef.bind(this);
    this.isOutsideClick = this.isOutsideClick.bind(this);
    this.onMouseDown = this.onMouseDown.bind(this);
    this.onMouseUp = this.onMouseUp.bind(this);
    this.onKeyDown = this.onKeyDown.bind(this);
  }
  componentDidMount() {
    this.addMouseDownEventListener();
    if (this.props.shouldCloseOnEsc) {
      this.addKeyDownEventListener();
    }
  }
  componentWillUnmount() {
    this.removeMouseUp();
    this.removeMouseDown();
    this.removeKeyDownEventListener();
  }
  onMouseDown(e) {
    const isOutsideClick = this.isOutsideClick(e);

    // Click is outside, so start listening for the mouseup event.
    if (isOutsideClick) {
      this.removeMouseUp();
      document.addEventListener('mouseup', this.onMouseUp, {
        capture: true
      });
    }
  }
  onMouseUp(e) {
    this.removeMouseUp();
    const isOutsideClick = this.isOutsideClick(e);
    if (isOutsideClick) {
      this.props.onClickOutside(e);
    }
  }
  onKeyDown(e) {
    if (e.key === 'Escape') {
      this.props.onClickOutside();
    }
  }
  addMouseDownEventListener() {
    document.addEventListener('mousedown', this.onMouseDown, {
      capture: true
    });
  }
  removeMouseUp() {
    document.removeEventListener('mouseup', this.onMouseUp, {
      capture: true
    });
  }
  removeMouseDown() {
    document.removeEventListener('mousedown', this.onMouseDown, {
      capture: true
    });
  }
  addKeyDownEventListener() {
    document.addEventListener('keydown', this.onKeyDown, {
      capture: true
    });
  }
  removeKeyDownEventListener() {
    document.removeEventListener('keydown', this.onKeyDown, {
      capture: true
    });
  }
  setWrapperRef(node) {
    this.wrapperRef = node;
  }
  isOutsideClick(event) {
    const elementsToAvoidOutsideClick = document.querySelectorAll(`.${OUTSIDE_CLICK_IGNORED_CLASS}`);
    let isInsideIgnoredElement = false;
    elementsToAvoidOutsideClick.forEach(element => {
      if (element.contains(event.target)) {
        isInsideIgnoredElement = true;
      }
    });
    if (isInsideIgnoredElement) {
      return false;
    }
    return this.wrapperRef && !this.wrapperRef.contains(event.target);
  }
  render() {
    return /*#__PURE__*/_jsx("div", {
      "test-id": "outside-click-listener",
      ref: this.setWrapperRef,
      className: "outside-click-listener-container",
      children: this.props.children
    });
  }
}