From 269b5d1951575ad0a54d9025e64676ee4fbed071 Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Thu, 19 Aug 2021 16:23:35 +1000 Subject: [PATCH 1/3] Wrap block support slots in ToolsPanel for dimensions support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Greg Ziółkowski --- .../src/components/block-inspector/index.js | 5 + .../block-support-tools-panel.js | 58 ++++++++++ .../components/inspector-controls/groups.js | 4 + .../src/components/inspector-controls/slot.js | 10 ++ packages/block-editor/src/hooks/dimensions.js | 108 ++++++++---------- .../components/sidebar/dimensions-panel.js | 6 +- 6 files changed, 127 insertions(+), 64 deletions(-) create mode 100644 packages/block-editor/src/components/inspector-controls/block-support-tools-panel.js diff --git a/packages/block-editor/src/components/block-inspector/index.js b/packages/block-editor/src/components/block-inspector/index.js index 0ef6a790d1688..0b15ae17665ee 100644 --- a/packages/block-editor/src/components/block-inspector/index.js +++ b/packages/block-editor/src/components/block-inspector/index.js @@ -129,6 +129,11 @@ const BlockInspectorSingleBlock = ( { ) } +
diff --git a/packages/block-editor/src/components/inspector-controls/block-support-tools-panel.js b/packages/block-editor/src/components/inspector-controls/block-support-tools-panel.js new file mode 100644 index 0000000000000..450a8351de8e3 --- /dev/null +++ b/packages/block-editor/src/components/inspector-controls/block-support-tools-panel.js @@ -0,0 +1,58 @@ +/** + * WordPress dependencies + */ +import { __experimentalToolsPanel as ToolsPanel } from '@wordpress/components'; +import { useDispatch, useSelect } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import { store as blockEditorStore } from '../../store'; +import { cleanEmptyObject } from '../../hooks/utils'; + +export default function BlockSupportToolsPanel( { children, label, header } ) { + const { clientId, attributes } = useSelect( ( select ) => { + const { getBlockAttributes, getSelectedBlockClientId } = select( + blockEditorStore + ); + const selectedBlockClientId = getSelectedBlockClientId(); + + return { + clientId: selectedBlockClientId, + attributes: getBlockAttributes( selectedBlockClientId ), + }; + } ); + const { updateBlockAttributes } = useDispatch( blockEditorStore ); + + const resetAll = ( resetFilters = [] ) => { + const { style } = attributes; + let newAttributes = { style }; + + resetFilters.forEach( ( resetFilter ) => { + newAttributes = { + ...newAttributes, + ...resetFilter( newAttributes ), + }; + } ); + + // Enforce a cleaned style object. + newAttributes = { + ...newAttributes, + style: cleanEmptyObject( newAttributes.style ), + }; + + updateBlockAttributes( clientId, newAttributes ); + }; + + return ( + + { children } + + ); +} diff --git a/packages/block-editor/src/components/inspector-controls/groups.js b/packages/block-editor/src/components/inspector-controls/groups.js index a989132afd4c7..4b039d35f2916 100644 --- a/packages/block-editor/src/components/inspector-controls/groups.js +++ b/packages/block-editor/src/components/inspector-controls/groups.js @@ -5,10 +5,14 @@ import { createSlotFill } from '@wordpress/components'; const InspectorControlsDefault = createSlotFill( 'InspectorControls' ); const InspectorControlsAdvanced = createSlotFill( 'InspectorAdvancedControls' ); +const InspectorControlsDimensions = createSlotFill( + 'InspectorControlsDimensions' +); const groups = { default: InspectorControlsDefault, advanced: InspectorControlsAdvanced, + dimensions: InspectorControlsDimensions, }; export default groups; diff --git a/packages/block-editor/src/components/inspector-controls/slot.js b/packages/block-editor/src/components/inspector-controls/slot.js index f17714cfe41b6..d9dfba0af06b9 100644 --- a/packages/block-editor/src/components/inspector-controls/slot.js +++ b/packages/block-editor/src/components/inspector-controls/slot.js @@ -7,11 +7,13 @@ import warning from '@wordpress/warning'; /** * Internal dependencies */ +import BlockSupportToolsPanel from './block-support-tools-panel'; import groups from './groups'; export default function InspectorControlsSlot( { __experimentalGroup: group = 'default', bubblesVirtually = true, + label, ...props } ) { const Slot = groups[ group ]?.Slot; @@ -26,5 +28,13 @@ export default function InspectorControlsSlot( { return null; } + if ( label ) { + return ( + + + + ); + } + return ; } diff --git a/packages/block-editor/src/hooks/dimensions.js b/packages/block-editor/src/hooks/dimensions.js index d85ce67104b39..9e38b6c6f0cab 100644 --- a/packages/block-editor/src/hooks/dimensions.js +++ b/packages/block-editor/src/hooks/dimensions.js @@ -1,10 +1,7 @@ /** * WordPress dependencies */ -import { - __experimentalToolsPanel as ToolsPanel, - __experimentalToolsPanelItem as ToolsPanelItem, -} from '@wordpress/components'; +import { __experimentalToolsPanelItem as ToolsPanelItem } from '@wordpress/components'; import { Platform } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { getBlockSupport } from '@wordpress/blocks'; @@ -34,7 +31,6 @@ import { resetPadding, useIsPaddingDisabled, } from './padding'; -import { cleanEmptyObject } from './utils'; export const SPACING_SUPPORT_KEY = 'spacing'; export const ALL_SIDES = [ 'top', 'right', 'bottom', 'left' ]; @@ -63,62 +59,56 @@ export function DimensionsPanel( props ) { '__experimentalDefaultControls', ] ); - // Callback to reset all block support attributes controlled via this panel. - const resetAll = () => { - const { style } = props.attributes; - - props.setAttributes( { - style: cleanEmptyObject( { - ...style, - spacing: { - ...style?.spacing, - blockGap: undefined, - margin: undefined, - padding: undefined, - }, - } ), - } ); - }; + const createResetAllFilter = ( attribute ) => ( newAttributes ) => ( { + ...newAttributes, + style: { + ...newAttributes.style, + spacing: { + ...newAttributes.style?.spacing, + [ attribute ]: undefined, + }, + }, + } ); return ( - - - { ! isPaddingDisabled && ( - hasPaddingValue( props ) } - label={ __( 'Padding' ) } - onDeselect={ () => resetPadding( props ) } - isShownByDefault={ defaultSpacingControls?.padding } - > - - - ) } - { ! isMarginDisabled && ( - hasMarginValue( props ) } - label={ __( 'Margin' ) } - onDeselect={ () => resetMargin( props ) } - isShownByDefault={ defaultSpacingControls?.margin } - > - - - ) } - { ! isGapDisabled && ( - hasGapValue( props ) } - label={ __( 'Block gap' ) } - onDeselect={ () => resetGap( props ) } - isShownByDefault={ defaultSpacingControls?.blockGap } - > - - - ) } - + + { ! isPaddingDisabled && ( + hasPaddingValue( props ) } + label={ __( 'Padding' ) } + onDeselect={ () => resetPadding( props ) } + resetAllFilter={ createResetAllFilter( 'padding' ) } + isShownByDefault={ defaultSpacingControls?.padding } + panelId={ props.clientId } + > + + + ) } + { ! isMarginDisabled && ( + hasMarginValue( props ) } + label={ __( 'Margin' ) } + onDeselect={ () => resetMargin( props ) } + resetAllFilter={ createResetAllFilter( 'margin' ) } + isShownByDefault={ defaultSpacingControls?.margin } + panelId={ props.clientId } + > + + + ) } + { ! isGapDisabled && ( + hasGapValue( props ) } + label={ __( 'Block gap' ) } + onDeselect={ () => resetGap( props ) } + resetAllFilter={ createResetAllFilter( 'blockGap' ) } + isShownByDefault={ defaultSpacingControls?.blockGap } + panelId={ props.clientId } + > + + + ) } ); } diff --git a/packages/edit-site/src/components/sidebar/dimensions-panel.js b/packages/edit-site/src/components/sidebar/dimensions-panel.js index 72059768b3018..23dc23599af5d 100644 --- a/packages/edit-site/src/components/sidebar/dimensions-panel.js +++ b/packages/edit-site/src/components/sidebar/dimensions-panel.js @@ -140,11 +140,7 @@ export default function DimensionsPanel( { context, getStyle, setStyle } ) { }; return ( - + { showPaddingControl && ( Date: Fri, 10 Sep 2021 13:07:43 +1000 Subject: [PATCH 2/3] Fix regression in ToolsPanel isResetting handling --- .../src/tools-panel/tools-panel/hook.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/components/src/tools-panel/tools-panel/hook.js b/packages/components/src/tools-panel/tools-panel/hook.js index 13adb434e4276..12f4d9322098e 100644 --- a/packages/components/src/tools-panel/tools-panel/hook.js +++ b/packages/components/src/tools-panel/tools-panel/hook.js @@ -22,6 +22,17 @@ export function useToolsPanel( props ) { }, [ className ] ); const isResetting = useRef( false ); + const wasResetting = isResetting.current; + + // `isResetting` is cleared via this hook to effectively batch together + // the resetAll task. Without this, the flag is cleared after the first + // control updates and forces a rerender with subsequent controls then + // believing they need to reset, unfortunately using stale data. + useEffect( () => { + if ( wasResetting ) { + isResetting.current = false; + } + }, wasResetting ); // Allow panel items to register themselves. const [ panelItems, setPanelItems ] = useState( [] ); @@ -104,12 +115,6 @@ export function useToolsPanel( props ) { isResetting: isResetting.current, }; - // Clean up isResetting after advising panel context we were resetting - // all controls. This lets panel items know to skip onDeselect callbacks. - if ( isResetting.current ) { - isResetting.current = false; - } - return { ...otherProps, panelContext, From abf5b6a65a33e76fd664eb90bfbfa5786f72fce7 Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Fri, 10 Sep 2021 13:12:31 +1000 Subject: [PATCH 3/3] Fix typo --- packages/components/src/tools-panel/tools-panel/hook.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/src/tools-panel/tools-panel/hook.js b/packages/components/src/tools-panel/tools-panel/hook.js index 12f4d9322098e..02e0d23f3f4a5 100644 --- a/packages/components/src/tools-panel/tools-panel/hook.js +++ b/packages/components/src/tools-panel/tools-panel/hook.js @@ -32,7 +32,7 @@ export function useToolsPanel( props ) { if ( wasResetting ) { isResetting.current = false; } - }, wasResetting ); + }, [ wasResetting ] ); // Allow panel items to register themselves. const [ panelItems, setPanelItems ] = useState( [] );