"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// packages/block-editor/src/components/inserter/index.js
var inserter_exports = {};
__export(inserter_exports, {
  default: () => inserter_default
});
module.exports = __toCommonJS(inserter_exports);
var import_clsx = __toESM(require("clsx"));
var import_a11y = require("@wordpress/a11y");
var import_i18n = require("@wordpress/i18n");
var import_components = require("@wordpress/components");
var import_element = require("@wordpress/element");
var import_data = require("@wordpress/data");
var import_compose = require("@wordpress/compose");
var import_blocks = require("@wordpress/blocks");
var import_icons = require("@wordpress/icons");
var import_menu = __toESM(require("./menu.cjs"));
var import_quick_inserter = __toESM(require("./quick-inserter.cjs"));
var import_store = require("../../store/index.cjs");
var import_get_appender_label = require("./get-appender-label.cjs");
var import_jsx_runtime = require("react/jsx-runtime");
var defaultRenderToggle = ({
  onToggle,
  disabled,
  isOpen,
  blockTitle,
  hasSingleBlockType,
  appenderLabel,
  toggleProps = {}
}) => {
  const {
    as: Wrapper = import_components.Button,
    label: labelProp,
    onClick,
    ...rest
  } = toggleProps;
  let label = labelProp;
  if (!label && appenderLabel) {
    label = appenderLabel;
  } else if (!label && hasSingleBlockType) {
    label = (0, import_i18n.sprintf)(
      // translators: %s: the name of the block when there is only one
      (0, import_i18n._x)("Add %s", "directly add the only allowed block"),
      blockTitle.toLowerCase()
    );
  } else if (!label) {
    label = (0, import_i18n._x)("Add block", "Generic label for block inserter button");
  }
  function handleClick(event) {
    if (onToggle) {
      onToggle(event);
    }
    if (onClick) {
      onClick(event);
    }
  }
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
    Wrapper,
    {
      __next40pxDefaultSize: toggleProps.as ? void 0 : true,
      icon: import_icons.plus,
      label,
      tooltipPosition: "bottom",
      onClick: handleClick,
      className: "block-editor-inserter__toggle",
      "aria-haspopup": !hasSingleBlockType ? "true" : false,
      "aria-expanded": !hasSingleBlockType ? isOpen : false,
      disabled,
      ...rest
    }
  );
};
var Inserter = class extends import_element.Component {
  constructor() {
    super(...arguments);
    this.onToggle = this.onToggle.bind(this);
    this.renderToggle = this.renderToggle.bind(this);
    this.renderContent = this.renderContent.bind(this);
  }
  onToggle(isOpen) {
    const { onToggle } = this.props;
    if (onToggle) {
      onToggle(isOpen);
    }
  }
  /**
   * Render callback to display Dropdown toggle element.
   *
   * @param {Object}   options
   * @param {Function} options.onToggle Callback to invoke when toggle is
   *                                    pressed.
   * @param {boolean}  options.isOpen   Whether dropdown is currently open.
   *
   * @return {Element} Dropdown toggle element.
   */
  renderToggle({ onToggle, isOpen }) {
    const {
      disabled,
      blockTitle,
      hasSingleBlockType,
      appenderLabel,
      toggleProps,
      hasItems,
      renderToggle = defaultRenderToggle
    } = this.props;
    return renderToggle({
      onToggle,
      isOpen,
      disabled: disabled || !hasItems,
      blockTitle,
      hasSingleBlockType,
      appenderLabel,
      toggleProps
    });
  }
  /**
   * Render callback to display Dropdown content element.
   *
   * @param {Object}   options
   * @param {Function} options.onClose Callback to invoke when dropdown is
   *                                   closed.
   *
   * @return {Element} Dropdown content element.
   */
  renderContent({ onClose }) {
    const {
      rootClientId,
      clientId,
      isAppender,
      showInserterHelpPanel,
      // This prop is experimental to give some time for the quick inserter to mature
      // Feel free to make them stable after a few releases.
      __experimentalIsQuick: isQuick,
      onSelectOrClose,
      selectBlockOnInsert
    } = this.props;
    if (isQuick) {
      return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
        import_quick_inserter.default,
        {
          onSelect: (blocks) => {
            const firstBlock = Array.isArray(blocks) && blocks?.length ? blocks[0] : blocks;
            if (onSelectOrClose && typeof onSelectOrClose === "function") {
              onSelectOrClose(firstBlock);
            }
            onClose();
          },
          rootClientId,
          clientId,
          isAppender,
          selectBlockOnInsert
        }
      );
    }
    return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
      import_menu.default,
      {
        onSelect: () => {
          onClose();
        },
        onClose,
        rootClientId,
        clientId,
        isAppender,
        showInserterHelpPanel
      }
    );
  }
  render() {
    const {
      position,
      hasSingleBlockType,
      blockToInsert,
      insertOnlyAllowedBlock,
      __experimentalIsQuick: isQuick,
      onSelectOrClose
    } = this.props;
    if (hasSingleBlockType || blockToInsert) {
      return this.renderToggle({ onToggle: insertOnlyAllowedBlock });
    }
    return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
      import_components.Dropdown,
      {
        className: "block-editor-inserter",
        contentClassName: (0, import_clsx.default)("block-editor-inserter__popover", {
          "is-quick": isQuick
        }),
        popoverProps: { position, shift: true },
        onToggle: this.onToggle,
        expandOnMobile: true,
        headerTitle: (0, import_i18n.__)("Add a block"),
        renderToggle: this.renderToggle,
        renderContent: this.renderContent,
        onClose: onSelectOrClose
      }
    );
  }
};
var inserter_default = (0, import_compose.compose)([
  (0, import_data.withSelect)(
    (select, { clientId, rootClientId, shouldDirectInsert = true }) => {
      const {
        getBlockRootClientId,
        hasInserterItems,
        getAllowedBlocks,
        getDirectInsertBlock,
        getBlockListSettings
      } = select(import_store.store);
      const { getBlockVariations, getBlockType } = select(import_blocks.store);
      rootClientId = rootClientId || getBlockRootClientId(clientId) || void 0;
      const allowedBlocks = getAllowedBlocks(rootClientId);
      const directInsertBlock = shouldDirectInsert && getDirectInsertBlock(rootClientId);
      const { defaultBlock } = getBlockListSettings(rootClientId) ?? {};
      const hasSingleBlockType = allowedBlocks?.length === 1 && getBlockVariations(allowedBlocks[0].name, "inserter")?.length === 0;
      const allowedBlockType = hasSingleBlockType ? allowedBlocks[0] : null;
      let blockToInsert = directInsertBlock || null;
      if (!blockToInsert && hasSingleBlockType && defaultBlock?.name === allowedBlockType.name) {
        blockToInsert = defaultBlock;
      }
      const defaultBlockType = directInsertBlock ? getBlockType(directInsertBlock.name) : null;
      const appenderLabel = (0, import_get_appender_label.getAppenderLabel)(
        directInsertBlock,
        defaultBlockType
      );
      return {
        hasItems: hasInserterItems(rootClientId),
        hasSingleBlockType,
        blockTitle: allowedBlockType ? allowedBlockType.title : "",
        allowedBlockType,
        blockToInsert,
        appenderLabel,
        rootClientId
      };
    }
  ),
  (0, import_data.withDispatch)((dispatch, ownProps, { select }) => {
    return {
      insertOnlyAllowedBlock() {
        const {
          rootClientId,
          clientId,
          isAppender,
          hasSingleBlockType,
          allowedBlockType,
          blockToInsert,
          onSelectOrClose,
          selectBlockOnInsert
        } = ownProps;
        if (!hasSingleBlockType && !blockToInsert) {
          return;
        }
        const blockName = blockToInsert?.name ?? allowedBlockType.name;
        function getAdjacentBlockAttributes(attributesToCopy) {
          if (!attributesToCopy?.length) {
            return {};
          }
          const { getBlock, getPreviousBlockClientId } = select(import_store.store);
          let adjacentAttributes;
          if (clientId) {
            const currentBlock = getBlock(clientId);
            const previousBlock = getBlock(
              getPreviousBlockClientId(clientId)
            );
            if (currentBlock?.name === previousBlock?.name) {
              adjacentAttributes = previousBlock?.attributes;
            }
          } else if (rootClientId) {
            const lastInnerBlock = getBlock(rootClientId)?.innerBlocks?.at(-1);
            if (lastInnerBlock?.name === blockName) {
              adjacentAttributes = lastInnerBlock.attributes;
            }
          }
          if (!adjacentAttributes) {
            return {};
          }
          return Object.fromEntries(
            attributesToCopy.filter((attr) => attr in adjacentAttributes).map((attr) => [
              attr,
              adjacentAttributes[attr]
            ])
          );
        }
        function getInsertionIndex() {
          const {
            getBlockIndex,
            getBlockSelectionEnd,
            getBlockOrder,
            getBlockRootClientId
          } = select(import_store.store);
          if (clientId) {
            return getBlockIndex(clientId);
          }
          const end = getBlockSelectionEnd();
          if (!isAppender && end && getBlockRootClientId(end) === rootClientId) {
            return getBlockIndex(end) + 1;
          }
          return getBlockOrder(rootClientId).length;
        }
        const { insertBlock } = dispatch(import_store.store);
        const newAttributes = getAdjacentBlockAttributes(
          blockToInsert?.attributesToCopy
        );
        const newBlock = (0, import_blocks.createBlock)(blockName, {
          ...blockToInsert?.attributes || {},
          ...newAttributes
        });
        insertBlock(
          newBlock,
          getInsertionIndex(),
          rootClientId,
          selectBlockOnInsert
        );
        if (onSelectOrClose) {
          onSelectOrClose(newBlock);
        }
        const message = (0, import_i18n.sprintf)(
          // translators: %s: the name of the block that has been added
          (0, import_i18n.__)("%s block added"),
          allowedBlockType.title
        );
        (0, import_a11y.speak)(message);
      }
    };
  }),
  // The global inserter should always be visible, we are using ( ! isAppender && ! rootClientId && ! clientId ) as
  // a way to detect the global Inserter.
  (0, import_compose.ifCondition)(
    ({ hasItems, isAppender, rootClientId, clientId }) => hasItems || !isAppender && !rootClientId && !clientId
  )
])(Inserter);
//# sourceMappingURL=index.cjs.map
