"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.BlockSwitcher = void 0;
var _i18n = require("@wordpress/i18n");
var _components = require("@wordpress/components");
var _blocks2 = require("@wordpress/blocks");
var _data = require("@wordpress/data");
var _icons = require("@wordpress/icons");
var _store = require("../../store");
var _blockIcon = _interopRequireDefault(require("../block-icon"));
var _blockTransformationsMenu = _interopRequireDefault(require("./block-transformations-menu"));
var _blockVariationTransformations = require("./block-variation-transformations");
var _blockStylesMenu = _interopRequireDefault(require("./block-styles-menu"));
var _patternTransformationsMenu = _interopRequireDefault(require("./pattern-transformations-menu"));
var _useBlockDisplayTitle = _interopRequireDefault(require("../block-title/use-block-display-title"));
var _jsxRuntime = require("react/jsx-runtime");
/**
 * WordPress dependencies
 */

/**
 * Internal dependencies
 */

function BlockSwitcherDropdownMenuContents({
  onClose,
  clientIds,
  hasBlockStyles,
  canRemove,
  isUsingBindings
}) {
  const {
    replaceBlocks,
    multiSelect,
    updateBlockAttributes
  } = (0, _data.useDispatch)(_store.store);
  const {
    possibleBlockTransformations,
    patterns,
    blocks
  } = (0, _data.useSelect)(select => {
    const {
      getBlocksByClientId,
      getBlockRootClientId,
      getBlockTransformItems,
      __experimentalGetPatternTransformItems
    } = select(_store.store);
    const rootClientId = getBlockRootClientId(Array.isArray(clientIds) ? clientIds[0] : clientIds);
    const _blocks = getBlocksByClientId(clientIds);
    return {
      blocks: _blocks,
      possibleBlockTransformations: getBlockTransformItems(_blocks, rootClientId),
      patterns: __experimentalGetPatternTransformItems(_blocks, rootClientId)
    };
  }, [clientIds]);
  const blockVariationTransformations = (0, _blockVariationTransformations.useBlockVariationTransforms)({
    clientIds,
    blocks
  });
  function selectForMultipleBlocks(insertedBlocks) {
    if (insertedBlocks.length > 1) {
      multiSelect(insertedBlocks[0].clientId, insertedBlocks[insertedBlocks.length - 1].clientId);
    }
  }
  // Simple block tranformation based on the `Block Transforms` API.
  function onBlockTransform(name) {
    const newBlocks = (0, _blocks2.switchToBlockType)(blocks, name);
    replaceBlocks(clientIds, newBlocks);
    selectForMultipleBlocks(newBlocks);
  }
  function onBlockVariationTransform(name) {
    updateBlockAttributes(blocks[0].clientId, {
      ...blockVariationTransformations.find(({
        name: variationName
      }) => variationName === name).attributes
    });
  }
  // Pattern transformation through the `Patterns` API.
  function onPatternTransform(transformedBlocks) {
    replaceBlocks(clientIds, transformedBlocks);
    selectForMultipleBlocks(transformedBlocks);
  }
  /**
   * The `isTemplate` check is a stopgap solution here.
   * Ideally, the Transforms API should handle this
   * by allowing to exclude blocks from wildcard transformations.
   */
  const isSingleBlock = blocks.length === 1;
  const isTemplate = isSingleBlock && (0, _blocks2.isTemplatePart)(blocks[0]);
  const hasPossibleBlockTransformations = !!possibleBlockTransformations.length && canRemove && !isTemplate;
  const hasPossibleBlockVariationTransformations = !!blockVariationTransformations?.length;
  const hasPatternTransformation = !!patterns?.length && canRemove;
  const hasBlockOrBlockVariationTransforms = hasPossibleBlockTransformations || hasPossibleBlockVariationTransformations;
  const hasContents = hasBlockStyles || hasBlockOrBlockVariationTransforms || hasPatternTransformation;
  if (!hasContents) {
    return /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
      className: "block-editor-block-switcher__no-transforms",
      children: (0, _i18n.__)('No transforms.')
    });
  }
  const connectedBlockDescription = isSingleBlock ? (0, _i18n._x)('This block is connected.', 'block toolbar button label and description') : (0, _i18n._x)('These blocks are connected.', 'block toolbar button label and description');
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
    className: "block-editor-block-switcher__container",
    children: [hasPatternTransformation && /*#__PURE__*/(0, _jsxRuntime.jsx)(_patternTransformationsMenu.default, {
      blocks: blocks,
      patterns: patterns,
      onSelect: transformedBlocks => {
        onPatternTransform(transformedBlocks);
        onClose();
      }
    }), hasBlockOrBlockVariationTransforms && /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockTransformationsMenu.default, {
      className: "block-editor-block-switcher__transforms__menugroup",
      possibleBlockTransformations: possibleBlockTransformations,
      possibleBlockVariationTransformations: blockVariationTransformations,
      blocks: blocks,
      onSelect: name => {
        onBlockTransform(name);
        onClose();
      },
      onSelectVariation: name => {
        onBlockVariationTransform(name);
        onClose();
      }
    }), hasBlockStyles && /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockStylesMenu.default, {
      hoveredBlock: blocks[0],
      onSwitch: onClose
    }), isUsingBindings && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.MenuGroup, {
      children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__experimentalText, {
        className: "block-editor-block-switcher__binding-indicator",
        children: connectedBlockDescription
      })
    })]
  });
}
const BlockIndicator = ({
  icon,
  showTitle,
  blockTitle
}) => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_blockIcon.default, {
    className: "block-editor-block-switcher__toggle",
    icon: icon,
    showColors: true
  }), showTitle && blockTitle && /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
    className: "block-editor-block-switcher__toggle-text",
    children: blockTitle
  })]
});
const BlockSwitcher = ({
  clientIds,
  disabled,
  isUsingBindings
}) => {
  const {
    hasContentOnlyLocking,
    canRemove,
    hasBlockStyles,
    icon,
    invalidBlocks,
    isReusable,
    isTemplate
  } = (0, _data.useSelect)(select => {
    const {
      getTemplateLock,
      getBlocksByClientId,
      getBlockAttributes,
      canRemoveBlocks
    } = select(_store.store);
    const {
      getBlockStyles,
      getBlockType,
      getActiveBlockVariation
    } = select(_blocks2.store);
    const _blocks = getBlocksByClientId(clientIds);
    if (!_blocks.length || _blocks.some(block => !block)) {
      return {
        invalidBlocks: true
      };
    }
    const [{
      name: firstBlockName
    }] = _blocks;
    const _isSingleBlockSelected = _blocks.length === 1;
    const blockType = getBlockType(firstBlockName);
    let _icon;
    let _hasTemplateLock;
    if (_isSingleBlockSelected) {
      const match = getActiveBlockVariation(firstBlockName, getBlockAttributes(clientIds[0]));
      // Take into account active block variations.
      _icon = match?.icon || blockType.icon;
      _hasTemplateLock = getTemplateLock(clientIds[0]) === 'contentOnly';
    } else {
      const isSelectionOfSameType = new Set(_blocks.map(({
        name
      }) => name)).size === 1;
      _hasTemplateLock = clientIds.some(id => getTemplateLock(id) === 'contentOnly');
      // When selection consists of blocks of multiple types, display an
      // appropriate icon to communicate the non-uniformity.
      _icon = isSelectionOfSameType ? blockType.icon : _icons.copy;
    }
    return {
      canRemove: canRemoveBlocks(clientIds),
      hasBlockStyles: _isSingleBlockSelected && !!getBlockStyles(firstBlockName)?.length,
      icon: _icon,
      isReusable: _isSingleBlockSelected && (0, _blocks2.isReusableBlock)(_blocks[0]),
      isTemplate: _isSingleBlockSelected && (0, _blocks2.isTemplatePart)(_blocks[0]),
      hasContentOnlyLocking: _hasTemplateLock
    };
  }, [clientIds]);
  const blockTitle = (0, _useBlockDisplayTitle.default)({
    clientId: clientIds?.[0],
    maximumLength: 35
  });
  if (invalidBlocks) {
    return null;
  }
  const isSingleBlock = clientIds.length === 1;
  const blockSwitcherLabel = isSingleBlock ? blockTitle : (0, _i18n.__)('Multiple blocks selected');
  const hideDropdown = disabled || !hasBlockStyles && !canRemove || hasContentOnlyLocking;
  if (hideDropdown) {
    return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.ToolbarGroup, {
      children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.ToolbarButton, {
        disabled: true,
        className: "block-editor-block-switcher__no-switcher-icon",
        title: blockSwitcherLabel,
        icon: /*#__PURE__*/(0, _jsxRuntime.jsx)(BlockIndicator, {
          icon: icon,
          showTitle: isReusable || isTemplate,
          blockTitle: blockTitle
        })
      })
    });
  }
  const blockSwitcherDescription = isSingleBlock ? (0, _i18n.__)('Change block type or style') : (0, _i18n.sprintf)( /* translators: %d: number of blocks. */
  (0, _i18n._n)('Change type of %d block', 'Change type of %d blocks', clientIds.length), clientIds.length);
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.ToolbarGroup, {
    children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.ToolbarItem, {
      children: toggleProps => /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.DropdownMenu, {
        className: "block-editor-block-switcher",
        label: blockSwitcherLabel,
        popoverProps: {
          placement: 'bottom-start',
          className: 'block-editor-block-switcher__popover'
        },
        icon: /*#__PURE__*/(0, _jsxRuntime.jsx)(BlockIndicator, {
          icon: icon,
          showTitle: isReusable || isTemplate,
          blockTitle: blockTitle
        }),
        toggleProps: {
          description: blockSwitcherDescription,
          ...toggleProps
        },
        menuProps: {
          orientation: 'both'
        },
        children: ({
          onClose
        }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(BlockSwitcherDropdownMenuContents, {
          onClose: onClose,
          clientIds: clientIds,
          hasBlockStyles: hasBlockStyles,
          canRemove: canRemove,
          isUsingBindings: isUsingBindings
        })
      })
    })
  });
};
exports.BlockSwitcher = BlockSwitcher;
var _default = exports.default = BlockSwitcher;
//# sourceMappingURL=index.js.map