"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
exports.useInnerBlocksProps = useInnerBlocksProps;
var _clsx = _interopRequireDefault(require("clsx"));
var _compose = require("@wordpress/compose");
var _element = require("@wordpress/element");
var _data = require("@wordpress/data");
var _blocks = require("@wordpress/blocks");
var _buttonBlockAppender = _interopRequireDefault(require("./button-block-appender"));
var _defaultBlockAppender = _interopRequireDefault(require("./default-block-appender"));
var _useNestedSettingsUpdate = _interopRequireDefault(require("./use-nested-settings-update"));
var _useInnerBlockTemplateSync = _interopRequireDefault(require("./use-inner-block-template-sync"));
var _useBlockContext = _interopRequireDefault(require("./use-block-context"));
var _blockList = require("../block-list");
var _blockContext = require("../block-context");
var _context = require("../block-edit/context");
var _useBlockSync = _interopRequireDefault(require("../provider/use-block-sync"));
var _store = require("../../store");
var _useBlockDropZone = _interopRequireDefault(require("../use-block-drop-zone"));
var _lockUnlock = require("../../lock-unlock");
var _jsxRuntime = require("react/jsx-runtime");
/**
 * External dependencies
 */

/**
 * WordPress dependencies
 */

/**
 * Internal dependencies
 */

const EMPTY_OBJECT = {};
function BlockContext({
  children,
  clientId
}) {
  const context = (0, _useBlockContext.default)(clientId);
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockContext.BlockContextProvider, {
    value: context,
    children: children
  });
}
const BlockListItemsMemo = (0, _element.memo)(_blockList.BlockListItems);

/**
 * InnerBlocks is a component which allows a single block to have multiple blocks
 * as children. The UncontrolledInnerBlocks component is used whenever the inner
 * blocks are not controlled by another entity. In other words, it is normally
 * used for inner blocks in the post editor
 *
 * @param {Object} props The component props.
 */
function UncontrolledInnerBlocks(props) {
  const {
    clientId,
    allowedBlocks,
    prioritizedInserterBlocks,
    defaultBlock,
    directInsert,
    __experimentalDefaultBlock,
    __experimentalDirectInsert,
    template,
    templateLock,
    wrapperRef,
    templateInsertUpdatesSelection,
    __experimentalCaptureToolbars: captureToolbars,
    __experimentalAppenderTagName,
    renderAppender,
    orientation,
    placeholder,
    layout,
    name,
    blockType,
    parentLock,
    defaultLayout
  } = props;
  (0, _useNestedSettingsUpdate.default)(clientId, parentLock, allowedBlocks, prioritizedInserterBlocks, defaultBlock, directInsert, __experimentalDefaultBlock, __experimentalDirectInsert, templateLock, captureToolbars, orientation, layout);
  (0, _useInnerBlockTemplateSync.default)(clientId, template, templateLock, templateInsertUpdatesSelection);
  const defaultLayoutBlockSupport = (0, _blocks.getBlockSupport)(name, 'layout') || (0, _blocks.getBlockSupport)(name, '__experimentalLayout') || EMPTY_OBJECT;
  const {
    allowSizingOnChildren = false
  } = defaultLayoutBlockSupport;
  const usedLayout = layout || defaultLayoutBlockSupport;
  const memoedLayout = (0, _element.useMemo)(() => ({
    // Default layout will know about any content/wide size defined by the theme.
    ...defaultLayout,
    ...usedLayout,
    ...(allowSizingOnChildren && {
      allowSizingOnChildren: true
    })
  }), [defaultLayout, usedLayout, allowSizingOnChildren]);

  // For controlled inner blocks, we don't want a change in blocks to
  // re-render the blocks list.
  const items = /*#__PURE__*/(0, _jsxRuntime.jsx)(BlockListItemsMemo, {
    rootClientId: clientId,
    renderAppender: renderAppender,
    __experimentalAppenderTagName: __experimentalAppenderTagName,
    layout: memoedLayout,
    wrapperRef: wrapperRef,
    placeholder: placeholder
  });
  if (!blockType?.providesContext || Object.keys(blockType.providesContext).length === 0) {
    return items;
  }
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(BlockContext, {
    clientId: clientId,
    children: items
  });
}

/**
 * The controlled inner blocks component wraps the uncontrolled inner blocks
 * component with the blockSync hook. This keeps the innerBlocks of the block in
 * the block-editor store in sync with the blocks of the controlling entity. An
 * example of an inner block controller is a template part block, which provides
 * its own blocks from the template part entity data source.
 *
 * @param {Object} props The component props.
 */
function ControlledInnerBlocks(props) {
  (0, _useBlockSync.default)(props);
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(UncontrolledInnerBlocks, {
    ...props
  });
}
const ForwardedInnerBlocks = (0, _element.forwardRef)((props, ref) => {
  const innerBlocksProps = useInnerBlocksProps({
    ref
  }, props);
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
    className: "block-editor-inner-blocks",
    children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
      ...innerBlocksProps
    })
  });
});

/**
 * This hook is used to lightly mark an element as an inner blocks wrapper
 * element. Call this hook and pass the returned props to the element to mark as
 * an inner blocks wrapper, automatically rendering inner blocks as children. If
 * you define a ref for the element, it is important to pass the ref to this
 * hook, which the hook in turn will pass to the component through the props it
 * returns. Optionally, you can also pass any other props through this hook, and
 * they will be merged and returned.
 *
 * @param {Object} props   Optional. Props to pass to the element. Must contain
 *                         the ref if one is defined.
 * @param {Object} options Optional. Inner blocks options.
 *
 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/inner-blocks/README.md
 */
function useInnerBlocksProps(props = {}, options = {}) {
  const {
    __unstableDisableLayoutClassNames,
    __unstableDisableDropZone,
    dropZoneElement
  } = options;
  const {
    clientId,
    layout = null,
    __unstableLayoutClassNames: layoutClassNames = ''
  } = (0, _context.useBlockEditContext)();
  const selected = (0, _data.useSelect)(select => {
    const {
      getBlockName,
      isBlockSelected,
      hasSelectedInnerBlock,
      __unstableGetEditorMode,
      getTemplateLock,
      getBlockRootClientId,
      getBlockEditingMode,
      getBlockSettings,
      isDragging,
      getSectionRootClientId,
      isZoomOutMode: isZoomOut
    } = (0, _lockUnlock.unlock)(select(_store.store));
    if (!clientId) {
      const sectionRootClientId = getSectionRootClientId();
      // Disable the root drop zone when zoomed out and the section root client id
      // is not the root block list (represented by an empty string).
      // This avoids drag handling bugs caused by having two block lists acting as
      // drop zones - the actual 'root' block list and the section root.
      return {
        isDropZoneDisabled: isZoomOut() && sectionRootClientId !== ''
      };
    }
    const {
      hasBlockSupport,
      getBlockType
    } = select(_blocks.store);
    const blockName = getBlockName(clientId);
    const enableClickThrough = __unstableGetEditorMode() === 'navigation';
    const blockEditingMode = getBlockEditingMode(clientId);
    const parentClientId = getBlockRootClientId(clientId);
    const [defaultLayout] = getBlockSettings(clientId, 'layout');
    let _isDropZoneDisabled = blockEditingMode === 'disabled';
    if (__unstableGetEditorMode() === 'zoom-out') {
      // In zoom out mode, we want to disable the drop zone for the sections.
      // The inner blocks belonging to the section drop zone is
      // already disabled by the blocks themselves being disabled.
      const sectionRootClientId = getSectionRootClientId();
      _isDropZoneDisabled = clientId !== sectionRootClientId;
    }
    return {
      __experimentalCaptureToolbars: hasBlockSupport(blockName, '__experimentalExposeControlsToChildren', false),
      hasOverlay: blockName !== 'core/template' && !isBlockSelected(clientId) && !hasSelectedInnerBlock(clientId, true) && enableClickThrough && !isDragging(),
      name: blockName,
      blockType: getBlockType(blockName),
      parentLock: getTemplateLock(parentClientId),
      parentClientId,
      isDropZoneDisabled: _isDropZoneDisabled,
      defaultLayout
    };
  }, [clientId]);
  const {
    __experimentalCaptureToolbars,
    hasOverlay,
    name,
    blockType,
    parentLock,
    parentClientId,
    isDropZoneDisabled,
    defaultLayout
  } = selected;
  const blockDropZoneRef = (0, _useBlockDropZone.default)({
    dropZoneElement,
    rootClientId: clientId,
    parentClientId
  });
  const ref = (0, _compose.useMergeRefs)([props.ref, __unstableDisableDropZone || isDropZoneDisabled || layout?.isManualPlacement && window.__experimentalEnableGridInteractivity ? null : blockDropZoneRef]);
  const innerBlocksProps = {
    __experimentalCaptureToolbars,
    layout,
    name,
    blockType,
    parentLock,
    defaultLayout,
    ...options
  };
  const InnerBlocks = innerBlocksProps.value && innerBlocksProps.onChange ? ControlledInnerBlocks : UncontrolledInnerBlocks;
  return {
    ...props,
    ref,
    className: (0, _clsx.default)(props.className, 'block-editor-block-list__layout', __unstableDisableLayoutClassNames ? '' : layoutClassNames, {
      'has-overlay': hasOverlay
    }),
    children: clientId ? /*#__PURE__*/(0, _jsxRuntime.jsx)(InnerBlocks, {
      ...innerBlocksProps,
      clientId: clientId
    }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockList.BlockListItems, {
      ...options
    })
  };
}
useInnerBlocksProps.save = _blocks.__unstableGetInnerBlocksProps;

// Expose default appender placeholders as components.
ForwardedInnerBlocks.DefaultBlockAppender = _defaultBlockAppender.default;
ForwardedInnerBlocks.ButtonBlockAppender = _buttonBlockAppender.default;
ForwardedInnerBlocks.Content = () => useInnerBlocksProps.save().children;

/**
 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/inner-blocks/README.md
 */
var _default = exports.default = ForwardedInnerBlocks;
//# sourceMappingURL=index.js.map