From 3b1f0f579bd434563d35ffe7bfcd4796e7b48905 Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Fri, 11 Sep 2020 18:21:50 +0300 Subject: [PATCH 1/2] wrap navigation editing features with filters --- packages/block-library/src/navigation/edit.js | 422 +++++++++++------- packages/edit-navigation/src/index.js | 22 +- 2 files changed, 273 insertions(+), 171 deletions(-) diff --git a/packages/block-library/src/navigation/edit.js b/packages/block-library/src/navigation/edit.js index 6dbf24663abab9..41de15f590cfc0 100644 --- a/packages/block-library/src/navigation/edit.js +++ b/packages/block-library/src/navigation/edit.js @@ -7,7 +7,8 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { useRef, useState } from '@wordpress/element'; +import { useState, createRef } from '@wordpress/element'; +import { addFilter } from '@wordpress/hooks'; import { InnerBlocks, InspectorControls, @@ -17,12 +18,12 @@ import { } from '@wordpress/block-editor'; import { useDispatch, withSelect, withDispatch } from '@wordpress/data'; import { + withFilters, PanelBody, ToggleControl, - Toolbar, ToolbarGroup, } from '@wordpress/components'; -import { compose } from '@wordpress/compose'; +import { compose, createHigherOrderComponent } from '@wordpress/compose'; import { __ } from '@wordpress/i18n'; /** @@ -33,6 +34,8 @@ import BlockColorsStyleSelector from './block-colors-selector'; import * as navIcons from './icons'; import NavigationPlaceholder from './placeholder'; +const ref = createRef(); + function Navigation( { selectedBlockHasDescendants, attributes, @@ -40,14 +43,12 @@ function Navigation( { hasExistingNavItems, isImmediateParentOfSelectedBlock, isSelected, - setAttributes, updateInnerBlocks, className, } ) { // // HOOKS // - const ref = useRef(); const [ isPlaceholderShown, setIsPlaceholderShown ] = useState( ! hasExistingNavItems @@ -56,43 +57,6 @@ function Navigation( { const { selectBlock } = useDispatch( 'core/block-editor' ); const blockProps = useBlockWrapperProps(); - - const { TextColor, BackgroundColor, ColorPanel } = __experimentalUseColors( - [ - { name: 'textColor', property: 'color' }, - { name: 'backgroundColor', className: 'has-background' }, - ], - { - contrastCheckers: [ - { - backgroundColor: true, - textColor: true, - }, - ], - colorDetector: { targetRef: ref }, - colorPanelProps: { - initialOpen: true, - }, - } - ); - - const { navigatorToolbarButton, navigatorModal } = useBlockNavigator( - clientId - ); - - // - // HANDLERS - // - function handleItemsAlignment( align ) { - return () => { - const itemsJustification = - attributes.itemsJustification === align ? undefined : align; - setAttributes( { - itemsJustification, - } ); - }; - } - // // RENDER // @@ -121,139 +85,257 @@ function Navigation( { return ( <> - - + - { navigatorToolbarButton } - - { ColorPanel } - - - { navigatorModal } - - - { - setAttributes( { showSubmenuIcon: value } ); - } } - label={ __( 'Show submenu indicator icons' ) } - /> - - - - - - - + ); } -export default compose( [ - withSelect( ( select, { clientId } ) => { - const innerBlocks = select( 'core/block-editor' ).getBlocks( clientId ); +export const withInspectorControls = createHigherOrderComponent( + ( BlockEdit ) => ( props ) => { + return ( + <> + + + + { + props.setAttributes( { + showSubmenuIcon: value, + } ); + } } + label={ __( 'Show submenu indicator icons' ) } + /> + + + + ); + }, + 'withInspectorControls' +); + +addFilter( + 'navigation.BlockEdit', + 'core/block-library/navigation/with-inspector-controls', + withInspectorControls +); + +export const withBlockControls = createHigherOrderComponent( + ( BlockEdit ) => ( props ) => { + const { attributes, setAttributes } = props; + // + // HANDLERS + // + function handleItemsAlignment( align ) { + return () => { + const itemsJustification = + attributes.itemsJustification === align ? undefined : align; + setAttributes( { + itemsJustification, + } ); + }; + } + return ( + <> + + + + + + ); + }, + 'withBlockControls' +); + +addFilter( + 'navigation.BlockEdit', + 'core/block-library/navigation/with-block-controls', + withBlockControls +); + +export const withListView = createHigherOrderComponent( + ( BlockEdit ) => ( props ) => { + const { clientId } = props; + const { navigatorToolbarButton, navigatorModal } = useBlockNavigator( + clientId + ); + + return ( + <> + + + { navigatorToolbarButton } + + { navigatorModal } + + ); + }, + 'withListView' +); + +addFilter( + 'navigation.BlockEdit', + 'core/block-library/navigation/with-list-view', + withListView +); + +export const withFormattingControls = createHigherOrderComponent( + ( BlockEdit ) => ( props ) => { const { - getClientIdsOfDescendants, - hasSelectedInnerBlock, - getSelectedBlockClientId, - } = select( 'core/block-editor' ); - const isImmediateParentOfSelectedBlock = hasSelectedInnerBlock( - clientId, - false + TextColor, + BackgroundColor, + ColorPanel, + } = __experimentalUseColors( + [ + { name: 'textColor', property: 'color' }, + { name: 'backgroundColor', className: 'has-background' }, + ], + { + contrastCheckers: [ + { + backgroundColor: true, + textColor: true, + }, + ], + colorDetector: { targetRef: ref }, + colorPanelProps: { + initialOpen: true, + }, + } + ); + return ( + <> + + + + + + + + { ColorPanel } + + + ); - const selectedBlockId = getSelectedBlockClientId(); - const selectedBlockHasDescendants = !! getClientIdsOfDescendants( [ - selectedBlockId, - ] )?.length; - return { - isImmediateParentOfSelectedBlock, - selectedBlockHasDescendants, - hasExistingNavItems: !! innerBlocks.length, - }; - } ), - withDispatch( ( dispatch, { clientId } ) => { - return { - updateInnerBlocks( blocks ) { - if ( blocks?.length === 0 ) { - return false; - } - dispatch( 'core/block-editor' ).replaceInnerBlocks( - clientId, - blocks - ); - }, - }; - } ), -] )( Navigation ); + }, + 'withFormattingControls' +); + +addFilter( + 'navigation.BlockEdit', + 'core/block-library/navigation/with-formatting-controls', + withFormattingControls +); + +export default withFilters( 'navigation.BlockEdit' )( + compose( [ + withSelect( ( select, { clientId } ) => { + const innerBlocks = select( 'core/block-editor' ).getBlocks( + clientId + ); + const { + getClientIdsOfDescendants, + hasSelectedInnerBlock, + getSelectedBlockClientId, + } = select( 'core/block-editor' ); + const isImmediateParentOfSelectedBlock = hasSelectedInnerBlock( + clientId, + false + ); + const selectedBlockId = getSelectedBlockClientId(); + const selectedBlockHasDescendants = !! getClientIdsOfDescendants( [ + selectedBlockId, + ] )?.length; + return { + isImmediateParentOfSelectedBlock, + selectedBlockHasDescendants, + hasExistingNavItems: !! innerBlocks.length, + }; + } ), + withDispatch( ( dispatch, { clientId } ) => { + return { + updateInnerBlocks( blocks ) { + if ( blocks?.length === 0 ) { + return false; + } + dispatch( 'core/block-editor' ).replaceInnerBlocks( + clientId, + blocks + ); + }, + }; + } ), + ] )( Navigation ) +); diff --git a/packages/edit-navigation/src/index.js b/packages/edit-navigation/src/index.js index bc858e2e964a67..ccd294c6e2c9de 100644 --- a/packages/edit-navigation/src/index.js +++ b/packages/edit-navigation/src/index.js @@ -16,7 +16,7 @@ import { __ } from '@wordpress/i18n'; import apiFetch from '@wordpress/api-fetch'; import { addQueryArgs } from '@wordpress/url'; import { decodeEntities } from '@wordpress/html-entities'; -import { addFilter } from '@wordpress/hooks'; +import { addFilter, removeFilter } from '@wordpress/hooks'; /** * Internal dependencies @@ -106,6 +106,26 @@ const fetchLinkSuggestions = ( } ); }; +removeFilter( + 'navigation.BlockEdit', + 'core/block-library/navigation/with-inspector-controls' +); + +removeFilter( + 'navigation.BlockEdit', + 'core/block-library/navigation/with-block-controls' +); + +removeFilter( + 'navigation.BlockEdit', + 'core/block-library/navigation/with-list-view' +); + +removeFilter( + 'navigation.BlockEdit', + 'core/block-library/navigation/with-formatting-controls' +); + export function initialize( id, settings ) { if ( ! settings.blockNavMenus ) { addFilter( From e9670ccf356359d0db690d99c75e83a73e8acaff Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Fri, 18 Sep 2020 13:16:26 +0800 Subject: [PATCH 2/2] Switch to using BlockEdit filter Change navigation block to use __experimentalColor support option, and disable feature on navigation screen Remove unused ref Refactor to use feature flags injected as props to BlockEdit Also remove font size support Remove CSS Class and anchor support on navigation screen --- .../src/navigation/block-colors-selector.js | 92 ----- .../block-library/src/navigation/block.json | 11 +- packages/block-library/src/navigation/edit.js | 348 ++++++------------ packages/edit-navigation/src/index.js | 74 ++-- 4 files changed, 174 insertions(+), 351 deletions(-) delete mode 100644 packages/block-library/src/navigation/block-colors-selector.js diff --git a/packages/block-library/src/navigation/block-colors-selector.js b/packages/block-library/src/navigation/block-colors-selector.js deleted file mode 100644 index 802aa03225a15e..00000000000000 --- a/packages/block-library/src/navigation/block-colors-selector.js +++ /dev/null @@ -1,92 +0,0 @@ -/** - * WordPress dependencies - */ -import { - ToolbarButton, - Dropdown, - ToolbarGroup, - SVG, - Path, -} from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; -import { DOWN } from '@wordpress/keycodes'; - -const ColorSelectorSVGIcon = () => ( - - - -); - -/** - * Color Selector Icon component. - * - * @param {Object} props Component properties. - * @param {Object} props.style Style object. - * @param {string} props.className Class name for component. - * - * @return {*} React Icon component. - */ -const ColorSelectorIcon = ( { style, className } ) => { - return ( -
-
- -
-
- ); -}; - -/** - * Renders the Colors Selector Toolbar with the icon button. - * - * @param {Object} props Component properties. - * @param {Object} props.TextColor Text color component that wraps icon. - * @param {Object} props.BackgroundColor Background color component that wraps icon. - * - * @return {*} React toggle button component. - */ -const renderToggleComponent = ( { TextColor, BackgroundColor } ) => ( { - onToggle, - isOpen, -} ) => { - const openOnArrowDown = ( event ) => { - if ( ! isOpen && event.keyCode === DOWN ) { - event.preventDefault(); - event.stopPropagation(); - onToggle(); - } - }; - - return ( - - - - - - - } - /> - - ); -}; - -const BlockColorsStyleSelector = ( { children, ...other } ) => ( - children } - /> -); - -export default BlockColorsStyleSelector; diff --git a/packages/block-library/src/navigation/block.json b/packages/block-library/src/navigation/block.json index bd93c30bc91010..d12d267cf26a1b 100644 --- a/packages/block-library/src/navigation/block.json +++ b/packages/block-library/src/navigation/block.json @@ -41,11 +41,18 @@ "showSubmenuIcon": "showSubmenuIcon" }, "supports": { - "align": [ "wide", "full" ], + "align": [ + "wide", + "full" + ], "anchor": true, "html": false, "inserter": true, "lightBlockWrapper": true, - "__experimentalFontSize": true + "__experimentalFontSize": true, + "__experimentalColor": { + "textColor": true, + "backgroundColor": true + } } } diff --git a/packages/block-library/src/navigation/edit.js b/packages/block-library/src/navigation/edit.js index 41de15f590cfc0..71f854c63f0ca4 100644 --- a/packages/block-library/src/navigation/edit.js +++ b/packages/block-library/src/navigation/edit.js @@ -7,49 +7,39 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { useState, createRef } from '@wordpress/element'; -import { addFilter } from '@wordpress/hooks'; +import { useState } from '@wordpress/element'; import { InnerBlocks, InspectorControls, BlockControls, - __experimentalUseColors, __experimentalUseBlockWrapperProps as useBlockWrapperProps, } from '@wordpress/block-editor'; import { useDispatch, withSelect, withDispatch } from '@wordpress/data'; -import { - withFilters, - PanelBody, - ToggleControl, - ToolbarGroup, -} from '@wordpress/components'; -import { compose, createHigherOrderComponent } from '@wordpress/compose'; +import { PanelBody, ToggleControl, ToolbarGroup } from '@wordpress/components'; +import { compose } from '@wordpress/compose'; import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ import useBlockNavigator from './use-block-navigator'; -import BlockColorsStyleSelector from './block-colors-selector'; import * as navIcons from './icons'; import NavigationPlaceholder from './placeholder'; -const ref = createRef(); - function Navigation( { selectedBlockHasDescendants, attributes, + setAttributes, clientId, hasExistingNavItems, isImmediateParentOfSelectedBlock, isSelected, updateInnerBlocks, className, + hasSubmenuIndicatorSetting = true, + hasItemJustificationControls = true, + hasListViewModal = true, } ) { - // - // HOOKS - // - const [ isPlaceholderShown, setIsPlaceholderShown ] = useState( ! hasExistingNavItems ); @@ -57,15 +47,14 @@ function Navigation( { const { selectBlock } = useDispatch( 'core/block-editor' ); const blockProps = useBlockWrapperProps(); - // - // RENDER - // + const { navigatorToolbarButton, navigatorModal } = useBlockNavigator( + clientId + ); if ( isPlaceholderShown ) { return (
{ setIsPlaceholderShown( false ); updateInnerBlocks( blocks ); @@ -78,6 +67,16 @@ function Navigation( { ); } + function handleItemsAlignment( align ) { + return () => { + const itemsJustification = + attributes.itemsJustification === align ? undefined : align; + setAttributes( { + itemsJustification, + } ); + }; + } + const blockClassNames = classnames( className, { [ `items-justified-${ attributes.itemsJustification }` ]: attributes.itemsJustification, 'is-vertical': attributes.orientation === 'vertical', @@ -85,94 +84,8 @@ function Navigation( { return ( <> - - - ); -} - -export const withInspectorControls = createHigherOrderComponent( - ( BlockEdit ) => ( props ) => { - return ( - <> - - - - { - props.setAttributes( { - showSubmenuIcon: value, - } ); - } } - label={ __( 'Show submenu indicator icons' ) } - /> - - - - ); - }, - 'withInspectorControls' -); - -addFilter( - 'navigation.BlockEdit', - 'core/block-library/navigation/with-inspector-controls', - withInspectorControls -); - -export const withBlockControls = createHigherOrderComponent( - ( BlockEdit ) => ( props ) => { - const { attributes, setAttributes } = props; - // - // HANDLERS - // - function handleItemsAlignment( align ) { - return () => { - const itemsJustification = - attributes.itemsJustification === align ? undefined : align; - setAttributes( { - itemsJustification, - } ); - }; - } - return ( - <> - - + + { hasItemJustificationControls && ( - - - ); - }, - 'withBlockControls' -); - -addFilter( - 'navigation.BlockEdit', - 'core/block-library/navigation/with-block-controls', - withBlockControls -); - -export const withListView = createHigherOrderComponent( - ( BlockEdit ) => ( props ) => { - const { clientId } = props; - const { navigatorToolbarButton, navigatorModal } = useBlockNavigator( - clientId - ); - - return ( - <> - - + ) } + { hasListViewModal && ( { navigatorToolbarButton } - - { navigatorModal } - - ); - }, - 'withListView' -); - -addFilter( - 'navigation.BlockEdit', - 'core/block-library/navigation/with-list-view', - withListView -); + ) } + + { hasListViewModal && navigatorModal } + + { hasSubmenuIndicatorSetting && ( + + { + setAttributes( { + showSubmenuIcon: value, + } ); + } } + label={ __( 'Show submenu indicator icons' ) } + /> + + ) } + + + + ); +} -export const withFormattingControls = createHigherOrderComponent( - ( BlockEdit ) => ( props ) => { +export default compose( [ + withSelect( ( select, { clientId } ) => { + const innerBlocks = select( 'core/block-editor' ).getBlocks( clientId ); const { - TextColor, - BackgroundColor, - ColorPanel, - } = __experimentalUseColors( - [ - { name: 'textColor', property: 'color' }, - { name: 'backgroundColor', className: 'has-background' }, - ], - { - contrastCheckers: [ - { - backgroundColor: true, - textColor: true, - }, - ], - colorDetector: { targetRef: ref }, - colorPanelProps: { - initialOpen: true, - }, - } - ); - return ( - <> - - - - - - - - { ColorPanel } - - - + getClientIdsOfDescendants, + hasSelectedInnerBlock, + getSelectedBlockClientId, + } = select( 'core/block-editor' ); + const isImmediateParentOfSelectedBlock = hasSelectedInnerBlock( + clientId, + false ); - }, - 'withFormattingControls' -); - -addFilter( - 'navigation.BlockEdit', - 'core/block-library/navigation/with-formatting-controls', - withFormattingControls -); - -export default withFilters( 'navigation.BlockEdit' )( - compose( [ - withSelect( ( select, { clientId } ) => { - const innerBlocks = select( 'core/block-editor' ).getBlocks( - clientId - ); - const { - getClientIdsOfDescendants, - hasSelectedInnerBlock, - getSelectedBlockClientId, - } = select( 'core/block-editor' ); - const isImmediateParentOfSelectedBlock = hasSelectedInnerBlock( - clientId, - false - ); - const selectedBlockId = getSelectedBlockClientId(); - const selectedBlockHasDescendants = !! getClientIdsOfDescendants( [ - selectedBlockId, - ] )?.length; - return { - isImmediateParentOfSelectedBlock, - selectedBlockHasDescendants, - hasExistingNavItems: !! innerBlocks.length, - }; - } ), - withDispatch( ( dispatch, { clientId } ) => { - return { - updateInnerBlocks( blocks ) { - if ( blocks?.length === 0 ) { - return false; - } - dispatch( 'core/block-editor' ).replaceInnerBlocks( - clientId, - blocks - ); - }, - }; - } ), - ] )( Navigation ) -); + const selectedBlockId = getSelectedBlockClientId(); + const selectedBlockHasDescendants = !! getClientIdsOfDescendants( [ + selectedBlockId, + ] )?.length; + return { + isImmediateParentOfSelectedBlock, + selectedBlockHasDescendants, + hasExistingNavItems: !! innerBlocks.length, + }; + } ), + withDispatch( ( dispatch, { clientId } ) => { + return { + updateInnerBlocks( blocks ) { + if ( blocks?.length === 0 ) { + return false; + } + dispatch( 'core/block-editor' ).replaceInnerBlocks( + clientId, + blocks + ); + }, + }; + } ), +] )( Navigation ); diff --git a/packages/edit-navigation/src/index.js b/packages/edit-navigation/src/index.js index ccd294c6e2c9de..db23acc1945f9c 100644 --- a/packages/edit-navigation/src/index.js +++ b/packages/edit-navigation/src/index.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { map, set, flatten, partialRight } from 'lodash'; +import { map, set, flatten, omit, partialRight } from 'lodash'; /** * WordPress dependencies @@ -12,11 +12,12 @@ import { __experimentalRegisterExperimentalCoreBlocks, } from '@wordpress/block-library'; import { render } from '@wordpress/element'; +import { createHigherOrderComponent } from '@wordpress/compose'; import { __ } from '@wordpress/i18n'; import apiFetch from '@wordpress/api-fetch'; import { addQueryArgs } from '@wordpress/url'; import { decodeEntities } from '@wordpress/html-entities'; -import { addFilter, removeFilter } from '@wordpress/hooks'; +import { addFilter } from '@wordpress/hooks'; /** * Internal dependencies @@ -31,6 +32,43 @@ function disableInsertingNonNavigationBlocks( settings, name ) { return settings; } +function removeNavigationBlockSettingsUnsupportedFeatures( settings, name ) { + if ( name !== 'core/navigation' ) { + return settings; + } + + return { + ...settings, + supports: { + ...omit( settings.supports, [ + 'anchor', + 'customClassName', + '__experimentalColor', + '__experimentalFontSize', + ] ), + customClassName: false, + }, + }; +} + +const removeNavigationBlockEditUnsupportedFeatures = createHigherOrderComponent( + ( BlockEdit ) => ( props ) => { + if ( props.name !== 'core/navigation' ) { + return ; + } + + return ( + + ); + }, + 'removeNavigationBlockEditUnsupportedFeatures' +); + /** * Fetches link suggestions from the API. This function is an exact copy of a function found at: * @@ -106,26 +144,6 @@ const fetchLinkSuggestions = ( } ); }; -removeFilter( - 'navigation.BlockEdit', - 'core/block-library/navigation/with-inspector-controls' -); - -removeFilter( - 'navigation.BlockEdit', - 'core/block-library/navigation/with-block-controls' -); - -removeFilter( - 'navigation.BlockEdit', - 'core/block-library/navigation/with-list-view' -); - -removeFilter( - 'navigation.BlockEdit', - 'core/block-library/navigation/with-formatting-controls' -); - export function initialize( id, settings ) { if ( ! settings.blockNavMenus ) { addFilter( @@ -135,6 +153,18 @@ export function initialize( id, settings ) { ); } + addFilter( + 'blocks.registerBlockType', + 'core/edit-navigation/remove-navigation-block-settings-unsupported-features', + removeNavigationBlockSettingsUnsupportedFeatures + ); + + addFilter( + 'editor.BlockEdit', + 'core/edit-navigation/remove-navigation-block-edit-unsupported-features', + removeNavigationBlockEditUnsupportedFeatures + ); + registerCoreBlocks(); if ( process.env.GUTENBERG_PHASE === 2 ) {