"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.useObserver = void 0;
var _react = require("react");
/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0 and the Server Side Public License, v 1; you may not use this file except
 * in compliance with, at your election, the Elastic License 2.0 or the Server
 * Side Public License, v 1.
 */

/**
 * A shared custom hook that provides a pattern for observing DOM nodes
 * via browser observer APIs. Used by `EuiResizeObserver` and `EuiMutationObserver`.
 *
 * @param beginObserve - A callback that receives the target DOM element and should
 *   create and return the observer instance (e.g., `ResizeObserver`).
 * @param componentName - Optional name used in error messages when no ref is
 *   attached on mount, mirroring the guard previously in `EuiObserver`.
 */
var useObserver = exports.useObserver = function useObserver(beginObserve) {
  var componentName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'useObserver';
  var childNodeRef = (0, _react.useRef)(null);
  var observerRef = (0, _react.useRef)(null);

  // Store beginObserve in a ref so the ref callback doesn't cycle
  var beginObserveRef = (0, _react.useRef)(beginObserve);
  beginObserveRef.current = beginObserve;

  // Store componentName in a ref so the mount-only effect can access the
  // latest value without needing it as a dependency.
  var componentNameRef = (0, _react.useRef)(componentName);
  componentNameRef.current = componentName;

  // Guard: throw if the ref callback was never called (no element attached),
  // mirroring the check previously in EuiObserver.componentDidMount.
  // Also cleans up the observer on unmount.
  // Empty deps: run only on mount/unmount — componentName is only used for the
  // error message and changing it must not disconnect/re-connect the observer.
  (0, _react.useEffect)(function () {
    if (childNodeRef.current == null) {
      throw new Error("".concat(componentNameRef.current, " did not receive a ref"));
    }
    return function () {
      var _observerRef$current;
      (_observerRef$current = observerRef.current) === null || _observerRef$current === void 0 || _observerRef$current.disconnect();
    };
  }, []);
  var updateChildNode = (0, _react.useCallback)(function (ref) {
    if (childNodeRef.current === ref) return; // node hasn't changed

    // if there's an existing observer disconnect it
    if (observerRef.current != null) {
      observerRef.current.disconnect();
      observerRef.current = null;
    }
    childNodeRef.current = ref;
    if (childNodeRef.current != null) {
      var _beginObserveRef$curr;
      observerRef.current = (_beginObserveRef$curr = beginObserveRef.current(childNodeRef.current)) !== null && _beginObserveRef$curr !== void 0 ? _beginObserveRef$curr : null;
    }
  }, []);
  return updateChildNode;
};