// packages/block-editor/src/components/inserter/menu.js
import clsx from "clsx";
import {
  forwardRef,
  useState,
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useLayoutEffect
} from "@wordpress/element";
import { SearchControl, Popover } from "@wordpress/components";
import { VisuallyHidden } from "@wordpress/ui";
import { __ } from "@wordpress/i18n";
import { useDebouncedInput, useViewportMatch } from "@wordpress/compose";
import { useSelect } from "@wordpress/data";
import Tips from "./tips.mjs";
import InserterPreviewPanel from "./preview-panel.mjs";
import BlockTypesTab from "./block-types-tab.mjs";
import BlockPatternsTab from "./block-patterns-tab/index.mjs";
import { PatternCategoryPreviews } from "./block-patterns-tab/pattern-category-previews.mjs";
import { MediaTab, MediaCategoryPanel } from "./media-tab/index.mjs";
import InserterSearchResults from "./search-results.mjs";
import useInsertionPoint from "./hooks/use-insertion-point.mjs";
import { store as blockEditorStore } from "../../store/index.mjs";
import TabbedSidebar from "../tabbed-sidebar/index.mjs";
import { useZoomOut } from "../../hooks/use-zoom-out.mjs";
import { unlock } from "../../lock-unlock.mjs";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
var NOOP = () => {
};
function InserterMenu({
  rootClientId,
  clientId,
  isAppender,
  __experimentalInsertionIndex,
  onSelect,
  showInserterHelpPanel,
  showMostUsedBlocks,
  __experimentalFilterValue = "",
  shouldFocusBlock = true,
  onPatternCategorySelection,
  onClose,
  __experimentalInitialTab,
  __experimentalInitialCategory
}, ref) {
  const { isZoomOutMode, hasSectionRootClientId } = useSelect((select) => {
    const { isZoomOut, getSectionRootClientId } = unlock(
      select(blockEditorStore)
    );
    return {
      isZoomOutMode: isZoomOut(),
      hasSectionRootClientId: !!getSectionRootClientId()
    };
  }, []);
  const [filterValue, setFilterValue, delayedFilterValue] = useDebouncedInput(__experimentalFilterValue);
  const [hoveredItem, setHoveredItem] = useState(null);
  const [selectedPatternCategory, setSelectedPatternCategory] = useState(
    __experimentalInitialCategory
  );
  const [patternFilter, setPatternFilter] = useState("all");
  const [selectedMediaCategory, setSelectedMediaCategory] = useState(null);
  const isLargeViewport = useViewportMatch("large");
  const isMobileViewport = useViewportMatch("medium", "<");
  const maybeCloseInserter = isMobileViewport ? onClose : NOOP;
  function getInitialTab() {
    if (__experimentalInitialTab) {
      return __experimentalInitialTab;
    }
    if (isZoomOutMode) {
      return "patterns";
    }
    return "blocks";
  }
  const [selectedTab, setSelectedTab] = useState(getInitialTab());
  const shouldUseZoomOut = hasSectionRootClientId && (selectedTab === "patterns" || selectedTab === "media");
  useZoomOut(shouldUseZoomOut && isLargeViewport);
  const [destinationRootClientId, onInsertBlocks, onToggleInsertionPoint] = useInsertionPoint({
    rootClientId,
    clientId,
    isAppender,
    insertionIndex: __experimentalInsertionIndex,
    shouldFocusBlock
  });
  const blockTypesTabRef = useRef();
  const onInsert = useCallback(
    (blocks, meta, shouldForceFocusBlock, _rootClientId) => {
      onInsertBlocks(
        blocks,
        meta,
        shouldForceFocusBlock,
        _rootClientId
      );
      onSelect(blocks);
      maybeCloseInserter();
      window.requestAnimationFrame(() => {
        if (!shouldFocusBlock && !blockTypesTabRef.current?.contains(
          ref.current.ownerDocument.activeElement
        )) {
          blockTypesTabRef.current?.querySelector("button").focus();
        }
      });
    },
    [onInsertBlocks, maybeCloseInserter, onSelect, ref, shouldFocusBlock]
  );
  const onInsertPattern = useCallback(
    (blocks, patternName, ...args) => {
      onToggleInsertionPoint(false);
      onInsertBlocks(blocks, { patternName }, ...args);
      onSelect();
      maybeCloseInserter();
    },
    [onInsertBlocks, maybeCloseInserter, onSelect, onToggleInsertionPoint]
  );
  const onHover = useCallback(
    (item) => {
      onToggleInsertionPoint(item);
      setHoveredItem(item);
    },
    [onToggleInsertionPoint, setHoveredItem]
  );
  const onClickPatternCategory = useCallback(
    (patternCategory, filter) => {
      setSelectedPatternCategory(patternCategory);
      setPatternFilter(filter);
      onPatternCategorySelection?.();
    },
    [setSelectedPatternCategory, onPatternCategorySelection]
  );
  const showPatternPanel = selectedTab === "patterns" && !delayedFilterValue && !!selectedPatternCategory;
  const showMediaPanel = selectedTab === "media" && !!selectedMediaCategory;
  const [isScrolled, setIsScrolled] = useState(false);
  const blocksPanelRef = useRef(null);
  const patternsPanelRef = useRef(null);
  const mediaPanelRef = useRef(null);
  useEffect(() => {
    const handleScroll = (event) => {
      setIsScrolled(event.currentTarget.scrollTop > 0);
    };
    const panels = [
      blocksPanelRef.current,
      patternsPanelRef.current,
      mediaPanelRef.current
    ].filter(Boolean);
    panels.forEach(
      (panel) => panel.addEventListener("scroll", handleScroll)
    );
    return () => {
      panels.forEach(
        (panel) => panel.removeEventListener("scroll", handleScroll)
      );
    };
  }, []);
  const inserterSearch = useMemo(() => {
    if (selectedTab === "media") {
      return null;
    }
    return /* @__PURE__ */ jsxs(Fragment, { children: [
      /* @__PURE__ */ jsx(
        SearchControl,
        {
          className: clsx("block-editor-inserter__search", {
            "is-scrolled": isScrolled
          }),
          onChange: (value) => {
            if (hoveredItem) {
              setHoveredItem(null);
            }
            setFilterValue(value);
          },
          value: filterValue,
          label: __("Search"),
          placeholder: __("Search")
        }
      ),
      !!delayedFilterValue && /* @__PURE__ */ jsx(
        InserterSearchResults,
        {
          filterValue: delayedFilterValue,
          onSelect,
          onHover,
          rootClientId,
          clientId,
          isAppender,
          __experimentalInsertionIndex,
          showBlockDirectory: true,
          shouldFocusBlock,
          prioritizePatterns: selectedTab === "patterns"
        }
      )
    ] });
  }, [
    selectedTab,
    hoveredItem,
    setHoveredItem,
    setFilterValue,
    filterValue,
    delayedFilterValue,
    onSelect,
    onHover,
    shouldFocusBlock,
    clientId,
    rootClientId,
    __experimentalInsertionIndex,
    isAppender,
    isScrolled
  ]);
  const blocksTab = useMemo(() => {
    return /* @__PURE__ */ jsxs(Fragment, { children: [
      /* @__PURE__ */ jsx("div", { className: "block-editor-inserter__block-list", children: /* @__PURE__ */ jsx(
        BlockTypesTab,
        {
          ref: blockTypesTabRef,
          rootClientId: destinationRootClientId,
          onInsert,
          onHover,
          showMostUsedBlocks
        }
      ) }),
      showInserterHelpPanel && /* @__PURE__ */ jsxs("div", { className: "block-editor-inserter__tips", children: [
        /* @__PURE__ */ jsx(VisuallyHidden, { render: /* @__PURE__ */ jsx("h2", {}), children: __("A tip for using the block editor") }),
        /* @__PURE__ */ jsx(Tips, {})
      ] })
    ] });
  }, [
    destinationRootClientId,
    onInsert,
    onHover,
    showMostUsedBlocks,
    showInserterHelpPanel
  ]);
  const patternsTab = useMemo(() => {
    return /* @__PURE__ */ jsx(
      BlockPatternsTab,
      {
        rootClientId: destinationRootClientId,
        onInsert: onInsertPattern,
        onSelectCategory: onClickPatternCategory,
        selectedCategory: selectedPatternCategory,
        children: showPatternPanel && /* @__PURE__ */ jsx(
          PatternCategoryPreviews,
          {
            rootClientId: destinationRootClientId,
            onInsert: onInsertPattern,
            category: selectedPatternCategory,
            patternFilter,
            showTitlesAsTooltip: true
          }
        )
      }
    );
  }, [
    destinationRootClientId,
    onInsertPattern,
    onClickPatternCategory,
    patternFilter,
    selectedPatternCategory,
    showPatternPanel
  ]);
  const mediaTab = useMemo(() => {
    return /* @__PURE__ */ jsx(
      MediaTab,
      {
        rootClientId: destinationRootClientId,
        selectedCategory: selectedMediaCategory,
        onSelectCategory: setSelectedMediaCategory,
        onInsert,
        children: showMediaPanel && /* @__PURE__ */ jsx(
          MediaCategoryPanel,
          {
            rootClientId: destinationRootClientId,
            onInsert,
            category: selectedMediaCategory
          }
        )
      }
    );
  }, [
    destinationRootClientId,
    onInsert,
    selectedMediaCategory,
    setSelectedMediaCategory,
    showMediaPanel
  ]);
  const handleSetSelectedTab = (value) => {
    if (value !== "patterns") {
      setSelectedPatternCategory(null);
    }
    setSelectedTab(value);
  };
  const tabsRef = useRef();
  useLayoutEffect(() => {
    if (tabsRef.current) {
      window.requestAnimationFrame(() => {
        tabsRef.current.querySelector('[role="tab"][aria-selected="true"]')?.focus();
      });
    }
  }, []);
  return /* @__PURE__ */ jsxs(
    "div",
    {
      className: clsx("block-editor-inserter__menu", {
        "show-panel": showPatternPanel || showMediaPanel,
        "is-zoom-out": isZoomOutMode
      }),
      ref,
      children: [
        /* @__PURE__ */ jsx("div", { className: "block-editor-inserter__main-area", children: /* @__PURE__ */ jsx(
          TabbedSidebar,
          {
            ref: tabsRef,
            onSelect: handleSetSelectedTab,
            onClose,
            selectedTab,
            closeButtonLabel: __("Close Block Inserter"),
            tabs: [
              {
                name: "blocks",
                title: __("Blocks"),
                panelRef: blocksPanelRef,
                panel: /* @__PURE__ */ jsxs(Fragment, { children: [
                  inserterSearch,
                  selectedTab === "blocks" && !delayedFilterValue && blocksTab
                ] })
              },
              {
                name: "patterns",
                title: __("Patterns"),
                panelRef: patternsPanelRef,
                panel: /* @__PURE__ */ jsxs(Fragment, { children: [
                  inserterSearch,
                  selectedTab === "patterns" && !delayedFilterValue && patternsTab
                ] })
              },
              {
                name: "media",
                title: __("Media"),
                panelRef: mediaPanelRef,
                panel: /* @__PURE__ */ jsxs(Fragment, { children: [
                  inserterSearch,
                  mediaTab
                ] })
              }
            ]
          }
        ) }),
        showInserterHelpPanel && hoveredItem && /* @__PURE__ */ jsx(
          Popover,
          {
            className: "block-editor-inserter__preview-container__popover",
            placement: "right-start",
            offset: 16,
            focusOnMount: false,
            animate: false,
            children: /* @__PURE__ */ jsx(InserterPreviewPanel, { item: hoveredItem })
          }
        )
      ]
    }
  );
}
var PrivateInserterMenu = forwardRef(InserterMenu);
function PublicInserterMenu(props, ref) {
  return /* @__PURE__ */ jsx(
    PrivateInserterMenu,
    {
      ...props,
      onPatternCategorySelection: NOOP,
      ref
    }
  );
}
var menu_default = forwardRef(PublicInserterMenu);
export {
  PrivateInserterMenu,
  menu_default as default
};
//# sourceMappingURL=menu.mjs.map
