import * as React from 'react';
export function useFocusTrap(_ref) {
  var dialogRef = _ref.dialogRef,
      overlayRef = _ref.overlayRef;
  React.useEffect(function () {
    var originalActiveElement = document.activeElement;
    var overlayElement = overlayRef.current;
    var dialogElement = dialogRef.current;

    if (!dialogElement || !overlayElement) {
      return;
    } // Initial focus


    focusDescendant(dialogElement, true);
    var isTabbingForward = true;

    function handleKeydown(event) {
      isTabbingForward = event.key === 'Tab' && !event.shiftKey;
    }

    function handleKeyup() {
      isTabbingForward = true;
    }

    function handleFocusTrap(event) {
      if (event.target instanceof Node && dialogElement.contains(event.target)) {
        return;
      }

      focusDescendant(dialogElement, isTabbingForward);
    }

    dialogElement.addEventListener('keydown', handleKeydown);
    dialogElement.addEventListener('keyup', handleKeyup);
    overlayElement.addEventListener('focusin', handleFocusTrap);
    return function () {
      dialogElement.removeEventListener('keydown', handleKeydown);
      dialogElement.removeEventListener('keyup', handleKeyup);
      overlayElement.removeEventListener('focusin', handleFocusTrap); // Should restore original focus on unmount.

      originalActiveElement === null || originalActiveElement === void 0 ? void 0 : originalActiveElement.focus();
    };
  }, [dialogRef, overlayRef]);
}

function focusDescendant(element, isTabbingForward) {
  var descendantFocused = isTabbingForward ? focusFirstDescendant(element) : focusLastDescendant(element);
  return descendantFocused || attemptFocus(element);
} // https://www.w3.org/TR/wai-aria-practices-1.1/examples/dialog-modal/js/dialog.js


function focusFirstDescendant(element) {
  for (var i = 0; i < element.children.length; i++) {
    var child = element.children[i];

    if (attemptFocus(child) || focusFirstDescendant(child)) {
      return true;
    }
  }

  return false;
}

function focusLastDescendant(element) {
  for (var i = element.children.length - 1; i >= 0; i--) {
    var child = element.children[i];

    if (attemptFocus(child) || focusLastDescendant(child)) {
      return true;
    }
  }

  return false;
}

function attemptFocus(element) {
  if (!isFocusable(element)) {
    return false;
  }

  try {
    element.focus();
  } catch (_unused) {}

  return document.activeElement === element;
} // https://w3c.github.io/aria-practices/examples/js/utils.js


function isFocusable(element) {
  if (element.tabIndex < -1 || element.getAttribute('disabled')) {
    return false;
  }

  switch (element.nodeName) {
    case 'A':
      return !!element.getAttribute('href') && element.getAttribute('rel') !== 'ignore';

    case 'INPUT':
      return element.getAttribute('type') !== 'hidden';

    case 'BUTTON':
    case 'SELECT':
    case 'TEXTAREA':
      return true;

    default:
      {
        return element.tabIndex >= -1;
      }
  }
}