import { useCallback, useState, useRef, useEffect } from 'react';
import { u as useOpenCloseTransitionStates } from './useOpenCloseTransitionStates-CiTYrLGi.js';
import { t as tabbable } from './index.esm-K9kxJhLx.js';

const useDialogTransitionStates = (ref, openProp, options = {}) => {
  const { onOpenAnimationStart, onCloseAnimationComplete } = options;
  const getDurationMs = useCallback(() => {
    if (!ref.current || !window) return 0;
    const duration = window.getComputedStyle(ref.current).animationDuration;
    return parseFloat(duration) * 1e3;
  }, [ref]);
  const handleOpenAnimationStart = useCallback(() => {
    if (!ref.current) return;
    ref.current.showModal();
    onOpenAnimationStart?.();
  }, [ref, onOpenAnimationStart]);
  const handleCloseAnimationComplete = useCallback(() => {
    if (!ref.current) return;
    ref.current.close();
    onCloseAnimationComplete?.();
  }, [ref, onCloseAnimationComplete]);
  return useOpenCloseTransitionStates(openProp, {
    ...options,
    onOpenAnimationStart: handleOpenAnimationStart,
    onCloseAnimationComplete: handleCloseAnimationComplete,
    durationMs: getDurationMs
  });
};

const useKeyboardFocusables = (element, options = {
  observeChange: true,
  attributes: true,
  characterData: true,
  childList: true,
  subtree: true
}) => {
  const [focusables, setFocusables] = useState(null);
  const observerRef = useRef();
  useEffect(() => {
    const target = element instanceof HTMLElement ? element : element?.current;
    if (!target) return;
    if (!options.observeChange && !focusables) {
      setFocusables(tabbable(target));
      return;
    }
    const mutationCallback = () => {
      const targetArr = tabbable(target);
      if (targetArr.length === 0) return;
      setFocusables(targetArr);
    };
    const observer = new MutationObserver(mutationCallback);
    observerRef.current = observer;
    observer.observe(target, {
      childList: true,
      // Observe changes to child elements
      subtree: true,
      // Observe changes to descendants of the target
      attributes: true,
      // Observe changes to attributes
      characterData: true
      // Observe changes to text content
    });
    return () => {
      observer.disconnect();
    };
  }, [element, options, focusables]);
  return { focusables };
};

function useDrillDownContextState({
  defaultDrillDownIndex = 0
}) {
  const [drillDownIndex, setDrillDownIndex] = useState(void 0);
  const [registeredIndices, setRegisteredIndices] = useState([]);
  const drillDownPath = useRef([]);
  const [onClose, setOnClose] = useState([]);
  const triggerFocusRef = useRef(null);
  const restoreFocus = useCallback(() => {
    requestAnimationFrame(() => {
      triggerFocusRef.current?.focus();
      triggerFocusRef.current = null;
    });
  }, [triggerFocusRef]);
  const back = useCallback(() => {
    const newIndex = drillDownPath.current.pop();
    if (newIndex == null && triggerFocusRef.current) {
      setDrillDownIndex(void 0);
      restoreFocus();
      return;
    }
    setDrillDownIndex(newIndex);
  }, [setDrillDownIndex, drillDownPath, restoreFocus]);
  const next = useCallback(() => {
    if (drillDownIndex == null) {
      triggerFocusRef.current = document.activeElement;
      drillDownPath.current = [];
      setDrillDownIndex(defaultDrillDownIndex);
      return;
    }
    if (registeredIndices && registeredIndices[drillDownIndex + 1] == null) {
      drillDownPath.current = [];
      setDrillDownIndex(void 0);
      restoreFocus();
      return;
    }
    drillDownPath.current.push(drillDownIndex);
    setDrillDownIndex(drillDownIndex + 1);
  }, [
    drillDownIndex,
    setDrillDownIndex,
    defaultDrillDownIndex,
    drillDownPath,
    registeredIndices,
    restoreFocus
  ]);
  const setIndexWithinBounds = useCallback(
    (index) => {
      if (index == null || index < 0 || registeredIndices && registeredIndices[index] == null) {
        setDrillDownIndex(void 0);
        restoreFocus();
        return;
      }
      if (drillDownIndex === void 0) {
        triggerFocusRef.current = document.activeElement;
        drillDownPath.current = [];
      } else {
        drillDownPath.current.push(drillDownIndex);
      }
      setDrillDownIndex(index);
    },
    [
      drillDownIndex,
      setDrillDownIndex,
      drillDownPath,
      registeredIndices,
      restoreFocus
    ]
  );
  const setOnCloseForIndex = useCallback(
    (fn, index) => {
      setOnClose((arr) => {
        arr[index] = () => {
          fn();
          setDrillDownIndex(void 0);
          restoreFocus();
        };
        return arr;
      });
    },
    [restoreFocus]
  );
  return {
    index: drillDownIndex,
    setIndex: setIndexWithinBounds,
    back,
    next,
    registeredIndices,
    setRegisteredIndices,
    onClose,
    setOnClose: setOnCloseForIndex
  };
}

const useInitialFocus = (dialogRef, { computeFocus }) => {
  useEffect(() => {
    if (!dialogRef.current) {
      return () => {
      };
    }
    const observer = new MutationObserver((mutations) => {
      mutations.forEach((mutation) => {
        if (mutation.attributeName === "open" && mutation.target === dialogRef.current && mutation.target instanceof HTMLDialogElement && mutation.target.open === true) {
          const focusables = tabbable(dialogRef.current);
          const target = computeFocus?.(focusables) || focusables[0];
          target?.focus();
        }
      });
    });
    observer.observe(dialogRef.current, {
      attributes: true,
      attributeFilter: ["open"]
    });
    return () => {
      observer.disconnect();
    };
  }, [dialogRef, computeFocus]);
};

export { useDialogTransitionStates as a, useKeyboardFocusables as b, useInitialFocus as c, useDrillDownContextState as u };
//# sourceMappingURL=useInitialFocus-BRRbylek.js.map
