@wordpress/block-library
Version:
Block library for the WordPress editor.
120 lines (113 loc) • 4.63 kB
JavaScript
import { createElement, Fragment } from "@wordpress/element";
/**
* WordPress dependencies
*/
import { useInnerBlocksProps } from '@wordpress/block-editor';
import { Disabled, Spinner } from '@wordpress/components';
import { store as coreStore } from '@wordpress/core-data';
import { useSelect } from '@wordpress/data';
import { useContext, useEffect, useRef, useMemo } from '@wordpress/element';
/**
* Internal dependencies
*/
import useNavigationMenu from '../use-navigation-menu';
import useCreateNavigationMenu from './use-create-navigation-menu';
const EMPTY_OBJECT = {};
const DRAFT_MENU_PARAMS = ['postType', 'wp_navigation', {
status: 'draft',
per_page: -1
}];
const DEFAULT_BLOCK = {
name: 'core/navigation-link'
};
const ALLOWED_BLOCKS = ['core/navigation-link', 'core/search', 'core/social-links', 'core/page-list', 'core/spacer', 'core/home-link', 'core/site-title', 'core/site-logo', 'core/navigation-submenu'];
export default function UnsavedInnerBlocks(_ref) {
let {
blocks,
clientId,
hasSavedUnsavedInnerBlocks,
onSave,
hasSelection
} = _ref;
const originalBlocks = useRef();
useEffect(() => {
// Initially store the uncontrolled inner blocks for
// dirty state comparison.
if (!(originalBlocks !== null && originalBlocks !== void 0 && originalBlocks.current)) {
originalBlocks.current = blocks;
}
}, [blocks]); // If the current inner blocks object is different in any way
// from the original inner blocks from the post content then the
// user has made changes to the inner blocks. At this point the inner
// blocks can be considered "dirty".
// We also make sure the current innerBlocks had a chance to be set.
const innerBlocksAreDirty = !!originalBlocks.current && blocks !== originalBlocks.current;
const shouldDirectInsert = useMemo(() => blocks.every(_ref2 => {
let {
name
} = _ref2;
return name === 'core/navigation-link' || name === 'core/navigation-submenu' || name === 'core/page-list';
}), [blocks]); // The block will be disabled in a block preview, use this as a way of
// avoiding the side-effects of this component for block previews.
const isDisabled = useContext(Disabled.Context);
const savingLock = useRef(false);
const innerBlocksProps = useInnerBlocksProps({
className: 'wp-block-navigation__container'
}, {
renderAppender: hasSelection ? undefined : false,
allowedBlocks: ALLOWED_BLOCKS,
__experimentalDefaultBlock: DEFAULT_BLOCK,
__experimentalDirectInsert: shouldDirectInsert
});
const {
isSaving,
draftNavigationMenus,
hasResolvedDraftNavigationMenus
} = useSelect(select => {
if (isDisabled) {
return EMPTY_OBJECT;
}
const {
getEntityRecords,
hasFinishedResolution,
isSavingEntityRecord
} = select(coreStore);
return {
isSaving: isSavingEntityRecord('postType', 'wp_navigation'),
draftNavigationMenus: getEntityRecords(...DRAFT_MENU_PARAMS),
hasResolvedDraftNavigationMenus: hasFinishedResolution('getEntityRecords', DRAFT_MENU_PARAMS)
};
}, [isDisabled]);
const {
hasResolvedNavigationMenus,
navigationMenus
} = useNavigationMenu();
const {
create: createNavigationMenu
} = useCreateNavigationMenu(clientId); // Automatically save the uncontrolled blocks.
useEffect(() => {
// The block will be disabled when used in a BlockPreview.
// In this case avoid automatic creation of a wp_navigation post.
// Otherwise the user will be spammed with lots of menus!
//
// Also ensure other navigation menus have loaded so an
// accurate name can be created.
//
// Don't try saving when another save is already
// in progress.
//
// And finally only create the menu when the block is selected,
// which is an indication they want to start editing.
if (isDisabled || hasSavedUnsavedInnerBlocks || isSaving || savingLock.current || !hasResolvedDraftNavigationMenus || !hasResolvedNavigationMenus || !hasSelection || !innerBlocksAreDirty) {
return;
}
savingLock.current = true;
createNavigationMenu(null, blocks).then(menu => {
onSave(menu);
savingLock.current = false;
});
}, [isDisabled, isSaving, hasResolvedDraftNavigationMenus, hasResolvedNavigationMenus, draftNavigationMenus, navigationMenus, hasSelection, createNavigationMenu, blocks]);
const Wrapper = isSaving ? Disabled : 'div';
return createElement(Fragment, null, createElement(Wrapper, innerBlocksProps), isSaving && createElement(Spinner, null));
}
//# sourceMappingURL=unsaved-inner-blocks.js.map