From b17bc8b9dacf6bc429288aa6db1e4c40436e4c65 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Fri, 17 Sep 2021 17:41:11 +1000 Subject: [PATCH 01/11] Insert Links by default in Navigation block --- .../src/components/inner-blocks/index.js | 2 ++ .../inner-blocks/use-nested-settings-update.js | 8 ++++++++ .../src/components/inserter/index.js | 16 +++++++++++++--- packages/block-editor/src/store/selectors.js | 18 ++++++++++++++++++ packages/block-library/src/navigation/edit.js | 9 +++++++++ 5 files changed, 50 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/components/inner-blocks/index.js b/packages/block-editor/src/components/inner-blocks/index.js index dcf07e7391fc8..a88036e286d99 100644 --- a/packages/block-editor/src/components/inner-blocks/index.js +++ b/packages/block-editor/src/components/inner-blocks/index.js @@ -42,6 +42,7 @@ function UncontrolledInnerBlocks( props ) { const { clientId, allowedBlocks, + directInsert, template, templateLock, wrapperRef, @@ -57,6 +58,7 @@ function UncontrolledInnerBlocks( props ) { useNestedSettingsUpdate( clientId, allowedBlocks, + directInsert, templateLock, captureToolbars, orientation, diff --git a/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js b/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js index 8a276be0a69e4..b8360e5489ec4 100644 --- a/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js +++ b/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js @@ -21,6 +21,8 @@ import { getLayoutType } from '../../layouts'; * @param {string} clientId The client ID of the block to update. * @param {string[]} allowedBlocks An array of block names which are permitted * in inner blocks. + * @param {?string} directInsert A block name to be inserted directly by the + * appender. * @param {string} [templateLock] The template lock specified for the inner * blocks component. (e.g. "all") * @param {boolean} captureToolbars Whether or children toolbars should be shown @@ -33,6 +35,7 @@ import { getLayoutType } from '../../layouts'; export default function useNestedSettingsUpdate( clientId, allowedBlocks, + directInsert, templateLock, captureToolbars, orientation, @@ -83,6 +86,10 @@ export default function useNestedSettingsUpdate( newSettings.orientation = layoutType.getOrientation( layout ); } + if ( directInsert !== undefined ) { + newSettings.directInsert = directInsert; + } + if ( ! isShallowEqual( blockListSettings, newSettings ) ) { updateBlockListSettings( clientId, newSettings ); } @@ -90,6 +97,7 @@ export default function useNestedSettingsUpdate( clientId, blockListSettings, _allowedBlocks, + directInsert, templateLock, parentLock, captureToolbars, diff --git a/packages/block-editor/src/components/inserter/index.js b/packages/block-editor/src/components/inserter/index.js index c4231235f6035..6d9f99bf438b4 100644 --- a/packages/block-editor/src/components/inserter/index.js +++ b/packages/block-editor/src/components/inserter/index.js @@ -102,6 +102,7 @@ class Inserter extends Component { disabled, blockTitle, hasSingleBlockType, + directInsert, toggleProps, hasItems, renderToggle = defaultRenderToggle, @@ -113,6 +114,7 @@ class Inserter extends Component { disabled: disabled || ! hasItems, blockTitle, hasSingleBlockType, + directInsert, toggleProps, } ); } @@ -168,12 +170,13 @@ class Inserter extends Component { const { position, hasSingleBlockType, + directInsert, insertOnlyAllowedBlock, __experimentalIsQuick: isQuick, onSelectOrClose, } = this.props; - if ( hasSingleBlockType ) { + if ( hasSingleBlockType || directInsert ) { return this.renderToggle( { onToggle: insertOnlyAllowedBlock } ); } @@ -202,6 +205,7 @@ export default compose( [ getBlockRootClientId, hasInserterItems, __experimentalGetAllowedBlocks, + __experimentalGetDirectInsert, } = select( blockEditorStore ); const { getBlockVariations } = select( blocksStore ); @@ -210,6 +214,8 @@ export default compose( [ const allowedBlocks = __experimentalGetAllowedBlocks( rootClientId ); + const directInsert = __experimentalGetDirectInsert( rootClientId ); + const hasSingleBlockType = size( allowedBlocks ) === 1 && size( @@ -226,6 +232,7 @@ export default compose( [ hasSingleBlockType, blockTitle: allowedBlockType ? allowedBlockType.title : '', allowedBlockType, + directInsert, rootClientId, }; } ), @@ -238,10 +245,11 @@ export default compose( [ isAppender, hasSingleBlockType, allowedBlockType, + directInsert, onSelectOrClose, } = ownProps; - if ( ! hasSingleBlockType ) { + if ( ! hasSingleBlockType && ! directInsert ) { return; } @@ -274,7 +282,9 @@ export default compose( [ const { insertBlock } = dispatch( blockEditorStore ); - const blockToInsert = createBlock( allowedBlockType.name ); + const blockToInsert = directInsert + ? createBlock( directInsert ) + : createBlock( allowedBlockType.name ); insertBlock( blockToInsert, getInsertionIndex(), rootClientId ); diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 8e9f3792b0e0d..6369550342422 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -1792,6 +1792,24 @@ export const __experimentalGetAllowedBlocks = createSelector( ] ); +/** + * Returns the block to be directly inserted by the block appender. + * + * @param {Object} state Editor state. + * @param {?string} rootClientId Optional root client ID of block list. + * + * @return {string?} The block type to be directly inserted. + */ +export const __experimentalGetDirectInsert = createSelector( + ( state, rootClientId = null ) => { + if ( ! rootClientId ) { + return; + } + return state.blockListSettings[ rootClientId ].directInsert; + }, + ( state, rootClientId ) => state.blockListSettings[ rootClientId ] +); + const checkAllowListRecursive = ( blocks, allowedBlockTypes ) => { if ( isBoolean( allowedBlockTypes ) ) { return allowedBlockTypes; diff --git a/packages/block-library/src/navigation/edit.js b/packages/block-library/src/navigation/edit.js index b9e9fd8e53184..1e94051a264a9 100644 --- a/packages/block-library/src/navigation/edit.js +++ b/packages/block-library/src/navigation/edit.js @@ -50,6 +50,8 @@ const ALLOWED_BLOCKS = [ 'core/navigation-submenu', ]; +const DIRECT_INSERT = 'core/navigation-link'; + const LAYOUT = { type: 'default', alignments: [], @@ -90,6 +92,7 @@ function Navigation( { hasExistingNavItems, isImmediateParentOfSelectedBlock, isSelected, + onlyLinkInnerBlocks, updateInnerBlocks, className, backgroundColor, @@ -164,6 +167,7 @@ function Navigation( { }, { allowedBlocks: ALLOWED_BLOCKS, + directInsert: onlyLinkInnerBlocks ? DIRECT_INSERT : '', orientation: attributes.orientation, renderAppender: CustomAppender || appender, @@ -366,6 +370,10 @@ export default compose( [ selectedBlockId, ] )?.length; + const onlyLinkInnerBlocks = innerBlocks.every( + ( block ) => block.name === 'core/navigation-link' + ); + return { isImmediateParentOfSelectedBlock, selectedBlockHasDescendants, @@ -374,6 +382,7 @@ export default compose( [ // This prop is already available but computing it here ensures it's // fresh compared to isImmediateParentOfSelectedBlock isSelected: selectedBlockId === clientId, + onlyLinkInnerBlocks, }; } ), withDispatch( ( dispatch, { clientId } ) => { From 9c4f9c4490aa558c95db0f9697df1677a54043af Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Mon, 20 Sep 2021 15:04:00 +1000 Subject: [PATCH 02/11] Fix errors. --- packages/block-editor/src/store/selectors.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 6369550342422..c33116cf654c6 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -1805,9 +1805,9 @@ export const __experimentalGetDirectInsert = createSelector( if ( ! rootClientId ) { return; } - return state.blockListSettings[ rootClientId ].directInsert; + return state.blockListSettings[ rootClientId ]?.directInsert; }, - ( state, rootClientId ) => state.blockListSettings[ rootClientId ] + ( state, rootClientId ) => [ state.blockListSettings[ rootClientId ] ] ); const checkAllowListRecursive = ( blocks, allowedBlockTypes ) => { From ec29ec3da80f43d3665d25d23eb0c3368c06feab Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Mon, 20 Sep 2021 15:27:46 +1000 Subject: [PATCH 03/11] Open links by default with submenus --- packages/block-library/src/navigation-submenu/edit.js | 3 +++ packages/block-library/src/navigation/edit.js | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/navigation-submenu/edit.js b/packages/block-library/src/navigation-submenu/edit.js index 90e713893832e..1ce0982de2a93 100644 --- a/packages/block-library/src/navigation-submenu/edit.js +++ b/packages/block-library/src/navigation-submenu/edit.js @@ -50,6 +50,8 @@ import { name } from './block.json'; const ALLOWED_BLOCKS = [ 'core/navigation-link', 'core/navigation-submenu' ]; +const DIRECT_INSERT = 'core/navigation-link'; + const MAX_NESTING = 5; /** @@ -504,6 +506,7 @@ export default function NavigationSubmenuEdit( { }, { allowedBlocks: ALLOWED_BLOCKS, + directInsert: DIRECT_INSERT, renderAppender: isSelected || ( isImmediateParentOfSelectedBlock && diff --git a/packages/block-library/src/navigation/edit.js b/packages/block-library/src/navigation/edit.js index 1e94051a264a9..7f67e308d0190 100644 --- a/packages/block-library/src/navigation/edit.js +++ b/packages/block-library/src/navigation/edit.js @@ -371,7 +371,9 @@ export default compose( [ ] )?.length; const onlyLinkInnerBlocks = innerBlocks.every( - ( block ) => block.name === 'core/navigation-link' + ( block ) => + block.name === 'core/navigation-link' || + block.name === 'core/navigation-submenu' ); return { From 12fee339373bcafa84b468aa13c7f39e476631f2 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Tue, 21 Sep 2021 10:59:06 +1000 Subject: [PATCH 04/11] Insert page item by default. --- .../components/inner-blocks/use-nested-settings-update.js | 2 +- packages/block-editor/src/components/inserter/index.js | 8 ++++---- packages/block-library/src/navigation-submenu/edit.js | 5 ++++- packages/block-library/src/navigation/edit.js | 7 +++++-- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js b/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js index b8360e5489ec4..a9aef52162473 100644 --- a/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js +++ b/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js @@ -21,7 +21,7 @@ import { getLayoutType } from '../../layouts'; * @param {string} clientId The client ID of the block to update. * @param {string[]} allowedBlocks An array of block names which are permitted * in inner blocks. - * @param {?string} directInsert A block name to be inserted directly by the + * @param {?Array} directInsert A block name to be inserted directly by the * appender. * @param {string} [templateLock] The template lock specified for the inner * blocks component. (e.g. "all") diff --git a/packages/block-editor/src/components/inserter/index.js b/packages/block-editor/src/components/inserter/index.js index 6d9f99bf438b4..69fd23151f6b9 100644 --- a/packages/block-editor/src/components/inserter/index.js +++ b/packages/block-editor/src/components/inserter/index.js @@ -176,7 +176,7 @@ class Inserter extends Component { onSelectOrClose, } = this.props; - if ( hasSingleBlockType || directInsert ) { + if ( hasSingleBlockType || directInsert?.length ) { return this.renderToggle( { onToggle: insertOnlyAllowedBlock } ); } @@ -249,7 +249,7 @@ export default compose( [ onSelectOrClose, } = ownProps; - if ( ! hasSingleBlockType && ! directInsert ) { + if ( ! hasSingleBlockType && ! directInsert?.length ) { return; } @@ -282,8 +282,8 @@ export default compose( [ const { insertBlock } = dispatch( blockEditorStore ); - const blockToInsert = directInsert - ? createBlock( directInsert ) + const blockToInsert = directInsert?.length + ? createBlock( directInsert[ 0 ], directInsert[ 1 ] ) : createBlock( allowedBlockType.name ); insertBlock( blockToInsert, getInsertionIndex(), rootClientId ); diff --git a/packages/block-library/src/navigation-submenu/edit.js b/packages/block-library/src/navigation-submenu/edit.js index 1ce0982de2a93..30c9b84d82ea6 100644 --- a/packages/block-library/src/navigation-submenu/edit.js +++ b/packages/block-library/src/navigation-submenu/edit.js @@ -50,7 +50,10 @@ import { name } from './block.json'; const ALLOWED_BLOCKS = [ 'core/navigation-link', 'core/navigation-submenu' ]; -const DIRECT_INSERT = 'core/navigation-link'; +const DIRECT_INSERT = [ + 'core/navigation-link', + { type: 'page', kind: 'post-type' }, +]; const MAX_NESTING = 5; diff --git a/packages/block-library/src/navigation/edit.js b/packages/block-library/src/navigation/edit.js index 7f67e308d0190..74387327f0b7f 100644 --- a/packages/block-library/src/navigation/edit.js +++ b/packages/block-library/src/navigation/edit.js @@ -50,7 +50,10 @@ const ALLOWED_BLOCKS = [ 'core/navigation-submenu', ]; -const DIRECT_INSERT = 'core/navigation-link'; +const DIRECT_INSERT = [ + 'core/navigation-link', + { type: 'page', kind: 'post-type' }, +]; const LAYOUT = { type: 'default', @@ -167,7 +170,7 @@ function Navigation( { }, { allowedBlocks: ALLOWED_BLOCKS, - directInsert: onlyLinkInnerBlocks ? DIRECT_INSERT : '', + directInsert: onlyLinkInnerBlocks ? DIRECT_INSERT : [], orientation: attributes.orientation, renderAppender: CustomAppender || appender, From 8c5f2edacf0818ee831119554f5f4ee1dae2c295 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Tue, 21 Sep 2021 13:00:31 +1000 Subject: [PATCH 05/11] Fix re-rendering loop. --- packages/block-library/src/navigation/edit.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/block-library/src/navigation/edit.js b/packages/block-library/src/navigation/edit.js index 74387327f0b7f..72ccf0ce87c53 100644 --- a/packages/block-library/src/navigation/edit.js +++ b/packages/block-library/src/navigation/edit.js @@ -95,7 +95,7 @@ function Navigation( { hasExistingNavItems, isImmediateParentOfSelectedBlock, isSelected, - onlyLinkInnerBlocks, + innerBlocks, updateInnerBlocks, className, backgroundColor, @@ -164,6 +164,12 @@ function Navigation( { ? undefined : false; + const onlyLinkInnerBlocks = innerBlocks.every( + ( block ) => + block.name === 'core/navigation-link' || + block.name === 'core/navigation-submenu' + ); + const innerBlocksProps = useInnerBlocksProps( { className: 'wp-block-navigation__container', @@ -373,12 +379,6 @@ export default compose( [ selectedBlockId, ] )?.length; - const onlyLinkInnerBlocks = innerBlocks.every( - ( block ) => - block.name === 'core/navigation-link' || - block.name === 'core/navigation-submenu' - ); - return { isImmediateParentOfSelectedBlock, selectedBlockHasDescendants, @@ -387,7 +387,7 @@ export default compose( [ // This prop is already available but computing it here ensures it's // fresh compared to isImmediateParentOfSelectedBlock isSelected: selectedBlockId === clientId, - onlyLinkInnerBlocks, + innerBlocks, }; } ), withDispatch( ( dispatch, { clientId } ) => { From c7d29729159e5b7a8328bf66a022a298bd3457fe Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Tue, 21 Sep 2021 13:28:45 +1000 Subject: [PATCH 06/11] Actually fix re-rendering loop. --- packages/block-library/src/navigation/edit.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/block-library/src/navigation/edit.js b/packages/block-library/src/navigation/edit.js index 72ccf0ce87c53..d5b64272d4e6c 100644 --- a/packages/block-library/src/navigation/edit.js +++ b/packages/block-library/src/navigation/edit.js @@ -95,7 +95,7 @@ function Navigation( { hasExistingNavItems, isImmediateParentOfSelectedBlock, isSelected, - innerBlocks, + onlyLinkInnerBlocks, updateInnerBlocks, className, backgroundColor, @@ -164,10 +164,9 @@ function Navigation( { ? undefined : false; - const onlyLinkInnerBlocks = innerBlocks.every( - ( block ) => - block.name === 'core/navigation-link' || - block.name === 'core/navigation-submenu' + const directInsertValue = useMemo( + () => ( onlyLinkInnerBlocks ? DIRECT_INSERT : [] ), + [ onlyLinkInnerBlocks ] ); const innerBlocksProps = useInnerBlocksProps( @@ -176,7 +175,7 @@ function Navigation( { }, { allowedBlocks: ALLOWED_BLOCKS, - directInsert: onlyLinkInnerBlocks ? DIRECT_INSERT : [], + directInsert: directInsertValue, orientation: attributes.orientation, renderAppender: CustomAppender || appender, @@ -379,6 +378,12 @@ export default compose( [ selectedBlockId, ] )?.length; + const onlyLinkInnerBlocks = innerBlocks.every( + ( block ) => + block.name === 'core/navigation-link' || + block.name === 'core/navigation-submenu' + ); + return { isImmediateParentOfSelectedBlock, selectedBlockHasDescendants, @@ -387,7 +392,7 @@ export default compose( [ // This prop is already available but computing it here ensures it's // fresh compared to isImmediateParentOfSelectedBlock isSelected: selectedBlockId === clientId, - innerBlocks, + onlyLinkInnerBlocks, }; } ), withDispatch( ( dispatch, { clientId } ) => { From 7068be92e13b931e3c4c4b2fe200a0dcdd3dd564 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Wed, 22 Sep 2021 13:57:04 +1000 Subject: [PATCH 07/11] Switch back to inserting generic link. --- packages/block-library/src/navigation-submenu/edit.js | 5 +---- packages/block-library/src/navigation/edit.js | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/packages/block-library/src/navigation-submenu/edit.js b/packages/block-library/src/navigation-submenu/edit.js index 30c9b84d82ea6..3cc806963113e 100644 --- a/packages/block-library/src/navigation-submenu/edit.js +++ b/packages/block-library/src/navigation-submenu/edit.js @@ -50,10 +50,7 @@ import { name } from './block.json'; const ALLOWED_BLOCKS = [ 'core/navigation-link', 'core/navigation-submenu' ]; -const DIRECT_INSERT = [ - 'core/navigation-link', - { type: 'page', kind: 'post-type' }, -]; +const DIRECT_INSERT = [ 'core/navigation-link' ]; const MAX_NESTING = 5; diff --git a/packages/block-library/src/navigation/edit.js b/packages/block-library/src/navigation/edit.js index d5b64272d4e6c..3b612fc844eae 100644 --- a/packages/block-library/src/navigation/edit.js +++ b/packages/block-library/src/navigation/edit.js @@ -50,10 +50,7 @@ const ALLOWED_BLOCKS = [ 'core/navigation-submenu', ]; -const DIRECT_INSERT = [ - 'core/navigation-link', - { type: 'page', kind: 'post-type' }, -]; +const DIRECT_INSERT = [ 'core/navigation-link' ]; const LAYOUT = { type: 'default', From 7a54865a375cdf748d7b9f51f17f5abdfafa19a7 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Thu, 23 Sep 2021 15:27:46 +1000 Subject: [PATCH 08/11] Separate direct insert from default block props --- .../src/components/inner-blocks/index.js | 6 ++- .../use-nested-settings-update.js | 41 +++++++++++-------- .../src/components/inserter/index.js | 27 +++++++----- packages/block-editor/src/store/selectors.js | 13 ++++-- .../src/navigation-submenu/edit.js | 5 ++- packages/block-library/src/navigation/edit.js | 10 ++--- 6 files changed, 60 insertions(+), 42 deletions(-) diff --git a/packages/block-editor/src/components/inner-blocks/index.js b/packages/block-editor/src/components/inner-blocks/index.js index a88036e286d99..5a8bc95238fd5 100644 --- a/packages/block-editor/src/components/inner-blocks/index.js +++ b/packages/block-editor/src/components/inner-blocks/index.js @@ -42,7 +42,8 @@ function UncontrolledInnerBlocks( props ) { const { clientId, allowedBlocks, - directInsert, + __experimentalDefaultBlock, + __experimentalDirectInsert, template, templateLock, wrapperRef, @@ -58,7 +59,8 @@ function UncontrolledInnerBlocks( props ) { useNestedSettingsUpdate( clientId, allowedBlocks, - directInsert, + __experimentalDefaultBlock, + __experimentalDirectInsert, templateLock, captureToolbars, orientation, diff --git a/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js b/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js index a9aef52162473..aa86522b6501d 100644 --- a/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js +++ b/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js @@ -18,24 +18,26 @@ import { getLayoutType } from '../../layouts'; * the block-editor store, then the store is updated with the new settings which * came from props. * - * @param {string} clientId The client ID of the block to update. - * @param {string[]} allowedBlocks An array of block names which are permitted - * in inner blocks. - * @param {?Array} directInsert A block name to be inserted directly by the - * appender. - * @param {string} [templateLock] The template lock specified for the inner - * blocks component. (e.g. "all") - * @param {boolean} captureToolbars Whether or children toolbars should be shown - * in the inner blocks component rather than on - * the child block. - * @param {string} orientation The direction in which the block - * should face. - * @param {Object} layout The layout object for the block container. + * @param {string} clientId The client ID of the block to update. + * @param {string[]} allowedBlocks An array of block names which are permitted + * in inner blocks. + * @param {?Array} __experimentalDefaultBlock The default block to insert: [ blockName, { blockAttributes } ]. + * @param {boolean} __experimentalDirectInsert If a default block should be inserted directly by the + * appender. + * @param {string} [templateLock] The template lock specified for the inner + * blocks component. (e.g. "all") + * @param {boolean} captureToolbars Whether or children toolbars should be shown + * in the inner blocks component rather than on + * the child block. + * @param {string} orientation The direction in which the block + * should face. + * @param {Object} layout The layout object for the block container. */ export default function useNestedSettingsUpdate( clientId, allowedBlocks, - directInsert, + __experimentalDefaultBlock, + __experimentalDirectInsert, templateLock, captureToolbars, orientation, @@ -86,8 +88,12 @@ export default function useNestedSettingsUpdate( newSettings.orientation = layoutType.getOrientation( layout ); } - if ( directInsert !== undefined ) { - newSettings.directInsert = directInsert; + if ( __experimentalDefaultBlock !== undefined ) { + newSettings.__experimentalDefaultBlock = __experimentalDefaultBlock; + } + + if ( __experimentalDirectInsert !== undefined ) { + newSettings.__experimentalDirectInsert = __experimentalDirectInsert; } if ( ! isShallowEqual( blockListSettings, newSettings ) ) { @@ -97,7 +103,8 @@ export default function useNestedSettingsUpdate( clientId, blockListSettings, _allowedBlocks, - directInsert, + __experimentalDefaultBlock, + __experimentalDirectInsert, templateLock, parentLock, captureToolbars, diff --git a/packages/block-editor/src/components/inserter/index.js b/packages/block-editor/src/components/inserter/index.js index 69fd23151f6b9..2f8f14fa097c8 100644 --- a/packages/block-editor/src/components/inserter/index.js +++ b/packages/block-editor/src/components/inserter/index.js @@ -102,7 +102,7 @@ class Inserter extends Component { disabled, blockTitle, hasSingleBlockType, - directInsert, + directInsertBlock, toggleProps, hasItems, renderToggle = defaultRenderToggle, @@ -114,7 +114,7 @@ class Inserter extends Component { disabled: disabled || ! hasItems, blockTitle, hasSingleBlockType, - directInsert, + directInsertBlock, toggleProps, } ); } @@ -170,13 +170,13 @@ class Inserter extends Component { const { position, hasSingleBlockType, - directInsert, + directInsertBlock, insertOnlyAllowedBlock, __experimentalIsQuick: isQuick, onSelectOrClose, } = this.props; - if ( hasSingleBlockType || directInsert?.length ) { + if ( hasSingleBlockType || directInsertBlock?.length ) { return this.renderToggle( { onToggle: insertOnlyAllowedBlock } ); } @@ -205,7 +205,7 @@ export default compose( [ getBlockRootClientId, hasInserterItems, __experimentalGetAllowedBlocks, - __experimentalGetDirectInsert, + __experimentalGetDirectInsertBlock, } = select( blockEditorStore ); const { getBlockVariations } = select( blocksStore ); @@ -214,7 +214,9 @@ export default compose( [ const allowedBlocks = __experimentalGetAllowedBlocks( rootClientId ); - const directInsert = __experimentalGetDirectInsert( rootClientId ); + const directInsertBlock = __experimentalGetDirectInsertBlock( + rootClientId + ); const hasSingleBlockType = size( allowedBlocks ) === 1 && @@ -232,7 +234,7 @@ export default compose( [ hasSingleBlockType, blockTitle: allowedBlockType ? allowedBlockType.title : '', allowedBlockType, - directInsert, + directInsertBlock, rootClientId, }; } ), @@ -245,11 +247,11 @@ export default compose( [ isAppender, hasSingleBlockType, allowedBlockType, - directInsert, + directInsertBlock, onSelectOrClose, } = ownProps; - if ( ! hasSingleBlockType && ! directInsert?.length ) { + if ( ! hasSingleBlockType && ! directInsertBlock?.length ) { return; } @@ -282,8 +284,11 @@ export default compose( [ const { insertBlock } = dispatch( blockEditorStore ); - const blockToInsert = directInsert?.length - ? createBlock( directInsert[ 0 ], directInsert[ 1 ] ) + const blockToInsert = directInsertBlock?.length + ? createBlock( + directInsertBlock[ 0 ], + directInsertBlock[ 1 ] + ) : createBlock( allowedBlockType.name ); insertBlock( blockToInsert, getInsertionIndex(), rootClientId ); diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index c33116cf654c6..1f29e12ba2b22 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -1798,14 +1798,21 @@ export const __experimentalGetAllowedBlocks = createSelector( * @param {Object} state Editor state. * @param {?string} rootClientId Optional root client ID of block list. * - * @return {string?} The block type to be directly inserted. + * @return {?Array} The block type to be directly inserted. */ -export const __experimentalGetDirectInsert = createSelector( +export const __experimentalGetDirectInsertBlock = createSelector( ( state, rootClientId = null ) => { if ( ! rootClientId ) { return; } - return state.blockListSettings[ rootClientId ]?.directInsert; + const defaultBlock = + state.blockListSettings[ rootClientId ]?.__experimentalDefaultBlock; + const directInsert = + state.blockListSettings[ rootClientId ]?.__experimentalDirectInsert; + if ( ! defaultBlock?.length || ! directInsert ) { + return; + } + return defaultBlock; }, ( state, rootClientId ) => [ state.blockListSettings[ rootClientId ] ] ); diff --git a/packages/block-library/src/navigation-submenu/edit.js b/packages/block-library/src/navigation-submenu/edit.js index 3cc806963113e..7588cd6b579a8 100644 --- a/packages/block-library/src/navigation-submenu/edit.js +++ b/packages/block-library/src/navigation-submenu/edit.js @@ -50,7 +50,7 @@ import { name } from './block.json'; const ALLOWED_BLOCKS = [ 'core/navigation-link', 'core/navigation-submenu' ]; -const DIRECT_INSERT = [ 'core/navigation-link' ]; +const DEFAULT_BLOCK = [ 'core/navigation-link' ]; const MAX_NESTING = 5; @@ -506,7 +506,8 @@ export default function NavigationSubmenuEdit( { }, { allowedBlocks: ALLOWED_BLOCKS, - directInsert: DIRECT_INSERT, + __experimentalDefaultBlock: DEFAULT_BLOCK, + __experimentalDirectInsert: true, renderAppender: isSelected || ( isImmediateParentOfSelectedBlock && diff --git a/packages/block-library/src/navigation/edit.js b/packages/block-library/src/navigation/edit.js index 3b612fc844eae..51817356a8223 100644 --- a/packages/block-library/src/navigation/edit.js +++ b/packages/block-library/src/navigation/edit.js @@ -50,7 +50,7 @@ const ALLOWED_BLOCKS = [ 'core/navigation-submenu', ]; -const DIRECT_INSERT = [ 'core/navigation-link' ]; +const DEFAULT_BLOCK = [ 'core/navigation-link' ]; const LAYOUT = { type: 'default', @@ -161,18 +161,14 @@ function Navigation( { ? undefined : false; - const directInsertValue = useMemo( - () => ( onlyLinkInnerBlocks ? DIRECT_INSERT : [] ), - [ onlyLinkInnerBlocks ] - ); - const innerBlocksProps = useInnerBlocksProps( { className: 'wp-block-navigation__container', }, { allowedBlocks: ALLOWED_BLOCKS, - directInsert: directInsertValue, + __experimentalDefaultBlock: DEFAULT_BLOCK, + __experimentalDirectInsert: onlyLinkInnerBlocks, orientation: attributes.orientation, renderAppender: CustomAppender || appender, From b102fe4677d1878eedfcca4721ea531fbfdf5a70 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Tue, 28 Sep 2021 13:28:36 +1000 Subject: [PATCH 09/11] Syntactic embellishment --- packages/block-editor/src/components/inserter/index.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/block-editor/src/components/inserter/index.js b/packages/block-editor/src/components/inserter/index.js index 2f8f14fa097c8..d08ac5ff272a0 100644 --- a/packages/block-editor/src/components/inserter/index.js +++ b/packages/block-editor/src/components/inserter/index.js @@ -285,10 +285,7 @@ export default compose( [ const { insertBlock } = dispatch( blockEditorStore ); const blockToInsert = directInsertBlock?.length - ? createBlock( - directInsertBlock[ 0 ], - directInsertBlock[ 1 ] - ) + ? createBlock( ...directInsertBlock ) : createBlock( allowedBlockType.name ); insertBlock( blockToInsert, getInsertionIndex(), rootClientId ); From 3a69217d3591d2f0ce497ade5e47c8ff8cd648c4 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Tue, 28 Sep 2021 14:12:25 +1000 Subject: [PATCH 10/11] Update e2e tests and add a new test for Navigation block. --- .../__snapshots__/navigation.test.js.snap | 10 +++ .../experiments/blocks/navigation.test.js | 61 ++++++++++++++----- .../experiments/navigation-editor.test.js | 5 -- 3 files changed, 55 insertions(+), 21 deletions(-) diff --git a/packages/e2e-tests/specs/experiments/blocks/__snapshots__/navigation.test.js.snap b/packages/e2e-tests/specs/experiments/blocks/__snapshots__/navigation.test.js.snap index f067002d11dac..1614ace7f64a4 100644 --- a/packages/e2e-tests/specs/experiments/blocks/__snapshots__/navigation.test.js.snap +++ b/packages/e2e-tests/specs/experiments/blocks/__snapshots__/navigation.test.js.snap @@ -44,6 +44,16 @@ exports[`Navigation Creating from existing Pages allows a navigation block to be " `; +exports[`Navigation Shows the quick inserter when the block contains non-navigation specific blocks 1`] = ` +" + + + + + +" +`; + exports[`Navigation allows an empty navigation block to be created and manually populated using a mixture of internal and external links 1`] = ` " diff --git a/packages/e2e-tests/specs/experiments/blocks/navigation.test.js b/packages/e2e-tests/specs/experiments/blocks/navigation.test.js index 40449589463c6..48859634ee45c 100644 --- a/packages/e2e-tests/specs/experiments/blocks/navigation.test.js +++ b/packages/e2e-tests/specs/experiments/blocks/navigation.test.js @@ -246,17 +246,6 @@ async function createEmptyNavBlock() { await startEmptyButton.click(); } -async function addLinkBlock() { - // Using 'click' here checks for regressions of https://github.com/WordPress/gutenberg/issues/18329, - // an issue where the block appender requires two clicks. - await page.click( '.wp-block-navigation .block-list-appender' ); - - const [ linkButton ] = await page.$x( - "//*[contains(@class, 'block-editor-inserter__quick-inserter')]//*[text()='Custom Link']" - ); - await linkButton.click(); -} - async function toggleSidebar() { await page.click( '.edit-post-header__settings button[aria-label="Settings"]' @@ -414,7 +403,7 @@ describe( 'Navigation', () => { await createEmptyNavBlock(); - await addLinkBlock(); + await page.click( '.wp-block-navigation .block-list-appender' ); // Add a link to the Link block. await updateActiveNavigationLink( { @@ -425,7 +414,7 @@ describe( 'Navigation', () => { await showBlockToolbar(); - await addLinkBlock(); + await page.click( '.wp-block-navigation .block-list-appender' ); // After adding a new block, search input should be shown immediately. // Verify that Escape would close the popover. @@ -477,7 +466,7 @@ describe( 'Navigation', () => { await createEmptyNavBlock(); - await addLinkBlock(); + await page.click( '.wp-block-navigation .block-list-appender' ); // Add a link to the Link block. await updateActiveNavigationLink( { @@ -487,7 +476,7 @@ describe( 'Navigation', () => { await showBlockToolbar(); - await addLinkBlock(); + await page.click( '.wp-block-navigation .block-list-appender' ); // Wait for URL input to be focused await page.waitForSelector( @@ -548,7 +537,7 @@ describe( 'Navigation', () => { // Create an empty nav block. await createEmptyNavBlock(); - await addLinkBlock(); + await page.click( '.wp-block-navigation .block-list-appender' ); // Wait for URL input to be focused await page.waitForSelector( @@ -642,6 +631,46 @@ describe( 'Navigation', () => { expect( navSubmenusLength ).toEqual( navButtonTogglesLength ); } ); + it( 'Shows the quick inserter when the block contains non-navigation specific blocks', async () => { + // Add the navigation block. + await insertBlock( 'Navigation' ); + + // Create an empty nav block. + await page.waitForSelector( '.wp-block-navigation-placeholder' ); + + await createEmptyNavBlock(); + + // Add a Link block first. + await page.click( '.wp-block-navigation .block-list-appender' ); + + // Add a link to the Link block. + await updateActiveNavigationLink( { + url: 'https://wordpress.org', + label: 'WP', + type: 'url', + } ); + + // Now add a different block type. + await insertBlock( 'Site Title' ); + + // Now try inserting another Link block via the quick inserter. + await page.click( '.wp-block-navigation .block-list-appender' ); + + const [ linkButton ] = await page.$x( + "//*[contains(@class, 'block-editor-inserter__quick-inserter')]//*[text()='Custom Link']" + ); + await linkButton.click(); + + await updateActiveNavigationLink( { + url: 'https://wordpress.org/news/', + label: 'WP News', + type: 'url', + } ); + + // Expect a Navigation block with two links and a Site Title. + expect( await getEditedPostContent() ).toMatchSnapshot(); + } ); + // The following tests are unstable, roughly around when https://github.com/WordPress/wordpress-develop/pull/1412 // landed. The block manually tests well, so let's skip to unblock other PRs and immediately follow up. cc @vcanales it.skip( 'loads frontend code only if the block is present', async () => { diff --git a/packages/e2e-tests/specs/experiments/navigation-editor.test.js b/packages/e2e-tests/specs/experiments/navigation-editor.test.js index cfeadac5ea5b7..78349d25eeee6 100644 --- a/packages/e2e-tests/specs/experiments/navigation-editor.test.js +++ b/packages/e2e-tests/specs/experiments/navigation-editor.test.js @@ -380,11 +380,6 @@ describe( 'Navigation editor', () => { ); await appender.click(); - const linkInserterItem = await page.waitForXPath( - '//button[@role="option"]//span[.="Custom Link"]' - ); - await linkInserterItem.click(); - await page.waitForSelector( 'input[aria-label="URL"]' ); // The link suggestions should be searchable. From 4e8457ad1a25a659766a99cf734bd8cf651d8844 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Wed, 29 Sep 2021 09:50:46 +1000 Subject: [PATCH 11/11] Try direct insert as a match function. --- .../use-nested-settings-update.js | 28 +++++++++---------- packages/block-editor/src/store/selectors.js | 12 ++++++-- packages/block-library/src/navigation/edit.js | 18 ++++++------ 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js b/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js index aa86522b6501d..8412b221c9b53 100644 --- a/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js +++ b/packages/block-editor/src/components/inner-blocks/use-nested-settings-update.js @@ -18,20 +18,20 @@ import { getLayoutType } from '../../layouts'; * the block-editor store, then the store is updated with the new settings which * came from props. * - * @param {string} clientId The client ID of the block to update. - * @param {string[]} allowedBlocks An array of block names which are permitted - * in inner blocks. - * @param {?Array} __experimentalDefaultBlock The default block to insert: [ blockName, { blockAttributes } ]. - * @param {boolean} __experimentalDirectInsert If a default block should be inserted directly by the - * appender. - * @param {string} [templateLock] The template lock specified for the inner - * blocks component. (e.g. "all") - * @param {boolean} captureToolbars Whether or children toolbars should be shown - * in the inner blocks component rather than on - * the child block. - * @param {string} orientation The direction in which the block - * should face. - * @param {Object} layout The layout object for the block container. + * @param {string} clientId The client ID of the block to update. + * @param {string[]} allowedBlocks An array of block names which are permitted + * in inner blocks. + * @param {?Array} __experimentalDefaultBlock The default block to insert: [ blockName, { blockAttributes } ]. + * @param {?Function|boolean} __experimentalDirectInsert If a default block should be inserted directly by the + * appender. + * @param {string} [templateLock] The template lock specified for the inner + * blocks component. (e.g. "all") + * @param {boolean} captureToolbars Whether or children toolbars should be shown + * in the inner blocks component rather than on + * the child block. + * @param {string} orientation The direction in which the block + * should face. + * @param {Object} layout The layout object for the block container. */ export default function useNestedSettingsUpdate( clientId, diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 1f29e12ba2b22..69d63048403ca 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -1809,12 +1809,20 @@ export const __experimentalGetDirectInsertBlock = createSelector( state.blockListSettings[ rootClientId ]?.__experimentalDefaultBlock; const directInsert = state.blockListSettings[ rootClientId ]?.__experimentalDirectInsert; - if ( ! defaultBlock?.length || ! directInsert ) { + if ( ! defaultBlock || ! directInsert ) { return; } + if ( typeof directInsert === 'function' ) { + return directInsert( getBlock( state, rootClientId ) ) + ? defaultBlock + : null; + } return defaultBlock; }, - ( state, rootClientId ) => [ state.blockListSettings[ rootClientId ] ] + ( state, rootClientId ) => [ + state.blockListSettings[ rootClientId ], + state.blocks.tree[ rootClientId ], + ] ); const checkAllowListRecursive = ( blocks, allowedBlockTypes ) => { diff --git a/packages/block-library/src/navigation/edit.js b/packages/block-library/src/navigation/edit.js index 51817356a8223..d5ef92a4c894f 100644 --- a/packages/block-library/src/navigation/edit.js +++ b/packages/block-library/src/navigation/edit.js @@ -52,6 +52,14 @@ const ALLOWED_BLOCKS = [ const DEFAULT_BLOCK = [ 'core/navigation-link' ]; +const DIRECT_INSERT = ( block ) => { + return block.innerBlocks.every( + ( { name } ) => + name === 'core/navigation-link' || + name === 'core/navigation-submenu' + ); +}; + const LAYOUT = { type: 'default', alignments: [], @@ -92,7 +100,6 @@ function Navigation( { hasExistingNavItems, isImmediateParentOfSelectedBlock, isSelected, - onlyLinkInnerBlocks, updateInnerBlocks, className, backgroundColor, @@ -168,7 +175,7 @@ function Navigation( { { allowedBlocks: ALLOWED_BLOCKS, __experimentalDefaultBlock: DEFAULT_BLOCK, - __experimentalDirectInsert: onlyLinkInnerBlocks, + __experimentalDirectInsert: DIRECT_INSERT, orientation: attributes.orientation, renderAppender: CustomAppender || appender, @@ -371,12 +378,6 @@ export default compose( [ selectedBlockId, ] )?.length; - const onlyLinkInnerBlocks = innerBlocks.every( - ( block ) => - block.name === 'core/navigation-link' || - block.name === 'core/navigation-submenu' - ); - return { isImmediateParentOfSelectedBlock, selectedBlockHasDescendants, @@ -385,7 +386,6 @@ export default compose( [ // This prop is already available but computing it here ensures it's // fresh compared to isImmediateParentOfSelectedBlock isSelected: selectedBlockId === clientId, - onlyLinkInnerBlocks, }; } ), withDispatch( ( dispatch, { clientId } ) => {