From 956b6760e0211ba074788f994c7408377d499154 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Mon, 12 Feb 2024 09:46:50 +1100 Subject: [PATCH 01/17] Add grid visualization --- packages/block-editor/src/hooks/layout.js | 8 ++- packages/block-editor/src/hooks/layout.scss | 13 +++++ packages/block-editor/src/layouts/grid.js | 58 ++++++++++++++++++++- 3 files changed, 76 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js index a83d07398d54a..d39f30c47f16f 100644 --- a/packages/block-editor/src/hooks/layout.js +++ b/packages/block-editor/src/hooks/layout.js @@ -135,7 +135,12 @@ export function useLayoutStyles( blockAttributes = {}, blockName, selector ) { return css; } -function LayoutPanelPure( { layout, setAttributes, name: blockName } ) { +function LayoutPanelPure( { + layout, + setAttributes, + clientId, + name: blockName, +} ) { const settings = useBlockSettings( blockName ); // Block settings come from theme.json under settings.[blockName]. const { layout: layoutSettings } = settings; @@ -282,6 +287,7 @@ function LayoutPanelPure( { layout, setAttributes, name: blockName } ) { layout={ usedLayout } onChange={ onChangeLayout } layoutBlockSupport={ layoutBlockSupport } + clientId={ clientId } /> ) } diff --git a/packages/block-editor/src/hooks/layout.scss b/packages/block-editor/src/hooks/layout.scss index 83a044e3cdca7..13ec30bdeaf15 100644 --- a/packages/block-editor/src/hooks/layout.scss +++ b/packages/block-editor/src/hooks/layout.scss @@ -39,3 +39,16 @@ .block-editor-hooks__toggle-control.block-editor-hooks__toggle-control { margin-bottom: $grid-unit-20; } + +.block-editor-grid-visualizer .components-popover__content * { + pointer-events: none !important; +} + +.block-editor-grid-visualizer__grid { + display: grid; +} + +.block-editor-grid-visualizer__item { + border: 1px dashed $gray-300; + border-radius: 2px; +} diff --git a/packages/block-editor/src/layouts/grid.js b/packages/block-editor/src/layouts/grid.js index 790998472fd26..5b19cea702a0d 100644 --- a/packages/block-editor/src/layouts/grid.js +++ b/packages/block-editor/src/layouts/grid.js @@ -19,6 +19,8 @@ import { appendSelectors, getBlockGapCSS } from './utils'; import { getGapCSSValue } from '../hooks/gap'; import { shouldSkipSerialization } from '../hooks/utils'; import { LAYOUT_DEFINITIONS } from './definitions'; +import BlockPopover from '../components/block-popover'; +import { __unstableUseBlockElement as useBlockElement } from '../components/block-list/use-block-props/use-block-refs'; const RANGE_CONTROL_MAX_VALUES = { px: 600, @@ -73,8 +75,8 @@ export default { /> ); }, - toolBarControls: function DefaultLayoutToolbarControls() { - return null; + toolBarControls: function GridLayoutToolbarControls( { clientId } ) { + return ; }, getLayoutStyle: function getLayoutStyle( { selector, @@ -221,3 +223,55 @@ function GridLayoutColumnsControl( { layout, onChange } ) { /> ); } + +// TODO: +// - Make the grid visualizer appear when a child item is selected as well +// - Add ResizeBox stuff so that can resize children + +function GridVisualizer( { clientId } ) { + const blockElement = useBlockElement( clientId ); + const gridTemplateColumns = getComputedCSS( + blockElement, + 'grid-template-columns' + ); + const gridTemplateRows = getComputedCSS( + blockElement, + 'grid-template-rows' + ); + const gridGap = getComputedCSS( blockElement, 'grid-gap' ); + const numColumns = gridTemplateColumns.split( ' ' ).length; + const numRows = gridTemplateRows.split( ' ' ).length; + const numItems = numColumns * numRows; + return ( + +
+ { Array.from( { length: numItems }, ( _, i ) => ( +
+ ) ) } +
+ + ); +} + +function getComputedCSS( element, property ) { + return element.ownerDocument.defaultView + .getComputedStyle( element ) + .getPropertyValue( property ); +} From c7f6986a824e9abc9168ba144120e83b02a88e58 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Wed, 14 Feb 2024 14:25:18 +1100 Subject: [PATCH 02/17] Show grid visualization when child is selected --- .../src/components/grid-visualizer/index.js | 56 +++++++++++++ packages/block-editor/src/hooks/index.js | 1 + .../block-editor/src/hooks/layout-child.js | 17 ++++ packages/block-editor/src/hooks/layout.js | 7 +- packages/block-editor/src/layouts/grid.js | 82 +++++-------------- 5 files changed, 99 insertions(+), 64 deletions(-) create mode 100644 packages/block-editor/src/components/grid-visualizer/index.js diff --git a/packages/block-editor/src/components/grid-visualizer/index.js b/packages/block-editor/src/components/grid-visualizer/index.js new file mode 100644 index 0000000000000..0fec4a61da1b6 --- /dev/null +++ b/packages/block-editor/src/components/grid-visualizer/index.js @@ -0,0 +1,56 @@ +/** + * Internal dependencies + */ +import { __unstableUseBlockElement as useBlockElement } from '../block-list/use-block-props/use-block-refs'; +import BlockPopover from '../block-popover'; + +export default function GridVisualizer( { clientId } ) { + const blockElement = useBlockElement( clientId ); + if ( ! blockElement ) { + return null; + } + const gridTemplateColumns = getComputedCSS( + blockElement, + 'grid-template-columns' + ); + const gridTemplateRows = getComputedCSS( + blockElement, + 'grid-template-rows' + ); + const gridGap = getComputedCSS( blockElement, 'grid-gap' ); + const numColumns = gridTemplateColumns.split( ' ' ).length; + const numRows = gridTemplateRows.split( ' ' ).length; + const numItems = numColumns * numRows; + return ( + +
+ { Array.from( { length: numItems }, ( _, i ) => ( +
+ ) ) } +
+ + ); +} + +function getComputedCSS( element, property ) { + return element.ownerDocument.defaultView + .getComputedStyle( element ) + .getPropertyValue( property ); +} diff --git a/packages/block-editor/src/hooks/index.js b/packages/block-editor/src/hooks/index.js index e6227ea2b03e2..36efe3dcf409b 100644 --- a/packages/block-editor/src/hooks/index.js +++ b/packages/block-editor/src/hooks/index.js @@ -42,6 +42,7 @@ createBlockEditFilter( contentLockUI, blockHooks, blockRenaming, + childLayout, ].filter( Boolean ) ); createBlockListBlockFilter( [ diff --git a/packages/block-editor/src/hooks/layout-child.js b/packages/block-editor/src/hooks/layout-child.js index d3219d8dfc563..6c775fc9d6d69 100644 --- a/packages/block-editor/src/hooks/layout-child.js +++ b/packages/block-editor/src/hooks/layout-child.js @@ -9,6 +9,8 @@ import { useSelect } from '@wordpress/data'; */ import { store as blockEditorStore } from '../store'; import { useStyleOverride } from './utils'; +import { useLayout } from '../components/block-list/layout'; +import GridVisualizer from '../components/grid-visualizer'; function useBlockPropsChildLayoutStyles( { style } ) { const shouldRenderChildLayoutStyles = useSelect( ( select ) => { @@ -93,8 +95,23 @@ function useBlockPropsChildLayoutStyles( { style } ) { return { className: `wp-container-content-${ id }` }; } +function ChildLayoutControlsPure( { clientId } ) { + const parentLayout = useLayout() || {}; + const rootClientId = useSelect( + ( select ) => { + return select( blockEditorStore ).getBlockRootClientId( clientId ); + }, + [ clientId ] + ); + if ( parentLayout.type !== 'grid' ) { + return null; + } + return ; +} + export default { useBlockProps: useBlockPropsChildLayoutStyles, + edit: ChildLayoutControlsPure, attributeKeys: [ 'style' ], hasSupport() { return true; diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js index d39f30c47f16f..76a5557850a60 100644 --- a/packages/block-editor/src/hooks/layout.js +++ b/packages/block-editor/src/hooks/layout.js @@ -138,8 +138,8 @@ export function useLayoutStyles( blockAttributes = {}, blockName, selector ) { function LayoutPanelPure( { layout, setAttributes, - clientId, name: blockName, + clientId, } ) { const settings = useBlockSettings( blockName ); // Block settings come from theme.json under settings.[blockName]. @@ -271,6 +271,8 @@ function LayoutPanelPure( { layout={ usedLayout } onChange={ onChangeLayout } layoutBlockSupport={ blockSupportAndThemeSettings } + name={ blockName } + clientId={ clientId } /> ) } { constrainedType && displayControlsForLegacyLayouts && ( @@ -278,6 +280,8 @@ function LayoutPanelPure( { layout={ usedLayout } onChange={ onChangeLayout } layoutBlockSupport={ blockSupportAndThemeSettings } + name={ blockName } + clientId={ clientId } /> ) } @@ -287,6 +291,7 @@ function LayoutPanelPure( { layout={ usedLayout } onChange={ onChangeLayout } layoutBlockSupport={ layoutBlockSupport } + name={ blockName } clientId={ clientId } /> ) } diff --git a/packages/block-editor/src/layouts/grid.js b/packages/block-editor/src/layouts/grid.js index 5b19cea702a0d..609235cd2a66f 100644 --- a/packages/block-editor/src/layouts/grid.js +++ b/packages/block-editor/src/layouts/grid.js @@ -19,8 +19,7 @@ import { appendSelectors, getBlockGapCSS } from './utils'; import { getGapCSSValue } from '../hooks/gap'; import { shouldSkipSerialization } from '../hooks/utils'; import { LAYOUT_DEFINITIONS } from './definitions'; -import BlockPopover from '../components/block-popover'; -import { __unstableUseBlockElement as useBlockElement } from '../components/block-list/use-block-props/use-block-refs'; +import GridVisualizer from '../components/grid-visualizer'; const RANGE_CONTROL_MAX_VALUES = { px: 600, @@ -65,18 +64,27 @@ export default { inspectorControls: function GridLayoutInspectorControls( { layout = {}, onChange, + clientId, } ) { - return layout?.columnCount ? ( - - ) : ( - + return ( + <> + { layout?.columnCount ? ( + + ) : ( + + ) } + + ); }, - toolBarControls: function GridLayoutToolbarControls( { clientId } ) { - return ; + toolBarControls: function GridLayoutToolbarControls() { + return null; }, getLayoutStyle: function getLayoutStyle( { selector, @@ -223,55 +231,3 @@ function GridLayoutColumnsControl( { layout, onChange } ) { /> ); } - -// TODO: -// - Make the grid visualizer appear when a child item is selected as well -// - Add ResizeBox stuff so that can resize children - -function GridVisualizer( { clientId } ) { - const blockElement = useBlockElement( clientId ); - const gridTemplateColumns = getComputedCSS( - blockElement, - 'grid-template-columns' - ); - const gridTemplateRows = getComputedCSS( - blockElement, - 'grid-template-rows' - ); - const gridGap = getComputedCSS( blockElement, 'grid-gap' ); - const numColumns = gridTemplateColumns.split( ' ' ).length; - const numRows = gridTemplateRows.split( ' ' ).length; - const numItems = numColumns * numRows; - return ( - -
- { Array.from( { length: numItems }, ( _, i ) => ( -
- ) ) } -
- - ); -} - -function getComputedCSS( element, property ) { - return element.ownerDocument.defaultView - .getComputedStyle( element ) - .getPropertyValue( property ); -} From 185dc1a02c8e6da528a8dc5949a4fa8a96409adc Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Thu, 15 Feb 2024 09:57:36 +1100 Subject: [PATCH 03/17] Allow dragging to set column and row span --- .../grid-visualizer/grid-item-resizer.js | 109 ++++++++++++++++++ .../grid-visualizer/grid-visualizer.js | 50 ++++++++ .../src/components/grid-visualizer/index.js | 58 +--------- .../src/components/grid-visualizer/utils.js | 5 + .../block-editor/src/hooks/layout-child.js | 25 +++- packages/block-editor/src/layouts/grid.js | 2 +- 6 files changed, 189 insertions(+), 60 deletions(-) create mode 100644 packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js create mode 100644 packages/block-editor/src/components/grid-visualizer/grid-visualizer.js create mode 100644 packages/block-editor/src/components/grid-visualizer/utils.js diff --git a/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js b/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js new file mode 100644 index 0000000000000..e77201acdab90 --- /dev/null +++ b/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js @@ -0,0 +1,109 @@ +/** + * WordPress dependencies + */ +import { ResizableBox } from '@wordpress/components'; +import { useRef } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { __unstableUseBlockElement as useBlockElement } from '../block-list/use-block-props/use-block-refs'; +import BlockPopover from '../block-popover'; +import { getComputedCSS } from './utils'; + +export function GridItemResizer( { clientId, onChange } ) { + const popoverRef = useRef(); + const resizableRef = useRef(); + const blockElement = useBlockElement( clientId ); + if ( ! blockElement ) { + return null; + } + return ( + + { + const boxWidth = element.offsetWidth; + const boxHeight = element.offsetHeight; + const { columnGap, rowGap, itemWidth, itemHeight } = + getGridDimensions( blockElement.parentElement ); + const columnSpan = Math.round( + ( columnGap + boxWidth ) / ( columnGap + itemWidth ) + ); + const rowSpan = Math.round( + ( rowGap + boxHeight ) / ( rowGap + itemHeight ) + ); + const newBoxWidth = + columnSpan * itemWidth + ( columnSpan - 1 ) * columnGap; + const newBoxHeight = + rowSpan * itemHeight + ( rowSpan - 1 ) * rowGap; + onChange( { + columnSpan, + rowSpan, + } ); + resizableRef.current.updateSize( { + width: newBoxWidth, + height: newBoxHeight, + } ); + } } + > +
+ + + ); +} + +function getGridDimensions( element ) { + const width = element.clientWidth; + const height = element.clientHeight; + const paddingX = + parseFloat( getComputedCSS( element, 'padding-left' ) ) + + parseFloat( getComputedCSS( element, 'padding-right' ) ); + const paddingY = + parseFloat( getComputedCSS( element, 'padding-top' ) ) + + parseFloat( getComputedCSS( element, 'padding-bottom' ) ); + const gridTemplateColumns = getComputedCSS( + element, + 'grid-template-columns' + ); + const gridTemplateRows = getComputedCSS( element, 'grid-template-rows' ); + const numColumns = gridTemplateColumns.split( ' ' ).length; + const numRows = gridTemplateRows.split( ' ' ).length; + const columnGap = parseFloat( getComputedCSS( element, 'column-gap' ) ); + const rowGap = parseFloat( getComputedCSS( element, 'row-gap' ) ); + const totalColumnGap = columnGap * ( numColumns - 1 ); + const totalRowGap = rowGap * ( numRows - 1 ); + const itemWidth = ( width - paddingX - totalColumnGap ) / numColumns; + const itemHeight = ( height - paddingY - totalRowGap ) / numRows; + return { + columnGap, + rowGap, + itemWidth, + itemHeight, + }; +} diff --git a/packages/block-editor/src/components/grid-visualizer/grid-visualizer.js b/packages/block-editor/src/components/grid-visualizer/grid-visualizer.js new file mode 100644 index 0000000000000..e7b86e3a3de97 --- /dev/null +++ b/packages/block-editor/src/components/grid-visualizer/grid-visualizer.js @@ -0,0 +1,50 @@ +/** + * Internal dependencies + */ +import { __unstableUseBlockElement as useBlockElement } from '../block-list/use-block-props/use-block-refs'; +import BlockPopover from '../block-popover'; +import { getComputedCSS } from './utils'; + +export function GridVisualizer( { clientId } ) { + const blockElement = useBlockElement( clientId ); + if ( ! blockElement ) { + return null; + } + const gridTemplateColumns = getComputedCSS( + blockElement, + 'grid-template-columns' + ); + const gridTemplateRows = getComputedCSS( + blockElement, + 'grid-template-rows' + ); + const numColumns = gridTemplateColumns.split( ' ' ).length; + const numRows = gridTemplateRows.split( ' ' ).length; + const numItems = numColumns * numRows; + return ( + +
+ { Array.from( { length: numItems }, ( _, i ) => ( +
+ ) ) } +
+ + ); +} diff --git a/packages/block-editor/src/components/grid-visualizer/index.js b/packages/block-editor/src/components/grid-visualizer/index.js index 0fec4a61da1b6..add845d702203 100644 --- a/packages/block-editor/src/components/grid-visualizer/index.js +++ b/packages/block-editor/src/components/grid-visualizer/index.js @@ -1,56 +1,2 @@ -/** - * Internal dependencies - */ -import { __unstableUseBlockElement as useBlockElement } from '../block-list/use-block-props/use-block-refs'; -import BlockPopover from '../block-popover'; - -export default function GridVisualizer( { clientId } ) { - const blockElement = useBlockElement( clientId ); - if ( ! blockElement ) { - return null; - } - const gridTemplateColumns = getComputedCSS( - blockElement, - 'grid-template-columns' - ); - const gridTemplateRows = getComputedCSS( - blockElement, - 'grid-template-rows' - ); - const gridGap = getComputedCSS( blockElement, 'grid-gap' ); - const numColumns = gridTemplateColumns.split( ' ' ).length; - const numRows = gridTemplateRows.split( ' ' ).length; - const numItems = numColumns * numRows; - return ( - -
- { Array.from( { length: numItems }, ( _, i ) => ( -
- ) ) } -
- - ); -} - -function getComputedCSS( element, property ) { - return element.ownerDocument.defaultView - .getComputedStyle( element ) - .getPropertyValue( property ); -} +export { GridVisualizer } from './grid-visualizer'; +export { GridItemResizer } from './grid-item-resizer'; diff --git a/packages/block-editor/src/components/grid-visualizer/utils.js b/packages/block-editor/src/components/grid-visualizer/utils.js new file mode 100644 index 0000000000000..a100e596a4e24 --- /dev/null +++ b/packages/block-editor/src/components/grid-visualizer/utils.js @@ -0,0 +1,5 @@ +export function getComputedCSS( element, property ) { + return element.ownerDocument.defaultView + .getComputedStyle( element ) + .getPropertyValue( property ); +} diff --git a/packages/block-editor/src/hooks/layout-child.js b/packages/block-editor/src/hooks/layout-child.js index 6c775fc9d6d69..8c6cc75ab7fd6 100644 --- a/packages/block-editor/src/hooks/layout-child.js +++ b/packages/block-editor/src/hooks/layout-child.js @@ -10,7 +10,7 @@ import { useSelect } from '@wordpress/data'; import { store as blockEditorStore } from '../store'; import { useStyleOverride } from './utils'; import { useLayout } from '../components/block-list/layout'; -import GridVisualizer from '../components/grid-visualizer'; +import { GridVisualizer, GridItemResizer } from '../components/grid-visualizer'; function useBlockPropsChildLayoutStyles( { style } ) { const shouldRenderChildLayoutStyles = useSelect( ( select ) => { @@ -95,7 +95,7 @@ function useBlockPropsChildLayoutStyles( { style } ) { return { className: `wp-container-content-${ id }` }; } -function ChildLayoutControlsPure( { clientId } ) { +function ChildLayoutControlsPure( { clientId, style, setAttributes } ) { const parentLayout = useLayout() || {}; const rootClientId = useSelect( ( select ) => { @@ -106,7 +106,26 @@ function ChildLayoutControlsPure( { clientId } ) { if ( parentLayout.type !== 'grid' ) { return null; } - return ; + return ( + <> + + { + setAttributes( { + style: { + ...style, + layout: { + ...style?.layout, + rowSpan, + columnSpan, + }, + }, + } ); + } } + /> + + ); } export default { diff --git a/packages/block-editor/src/layouts/grid.js b/packages/block-editor/src/layouts/grid.js index 609235cd2a66f..a7698f2fc2289 100644 --- a/packages/block-editor/src/layouts/grid.js +++ b/packages/block-editor/src/layouts/grid.js @@ -19,7 +19,7 @@ import { appendSelectors, getBlockGapCSS } from './utils'; import { getGapCSSValue } from '../hooks/gap'; import { shouldSkipSerialization } from '../hooks/utils'; import { LAYOUT_DEFINITIONS } from './definitions'; -import GridVisualizer from '../components/grid-visualizer'; +import { GridVisualizer } from '../components/grid-visualizer'; const RANGE_CONTROL_MAX_VALUES = { px: 600, From 3ce2c39c68b8ea414be43d2877ba9a9feb21a702 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Thu, 15 Feb 2024 10:04:35 +1100 Subject: [PATCH 04/17] Don't need this ref --- .../src/components/grid-visualizer/grid-item-resizer.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js b/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js index e77201acdab90..ff514517af3e6 100644 --- a/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js +++ b/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js @@ -12,7 +12,6 @@ import BlockPopover from '../block-popover'; import { getComputedCSS } from './utils'; export function GridItemResizer( { clientId, onChange } ) { - const popoverRef = useRef(); const resizableRef = useRef(); const blockElement = useBlockElement( clientId ); if ( ! blockElement ) { @@ -20,7 +19,6 @@ export function GridItemResizer( { clientId, onChange } ) { } return ( Date: Thu, 15 Feb 2024 16:03:05 +1100 Subject: [PATCH 05/17] Just disable left/top resizing for now --- .../src/components/grid-visualizer/grid-item-resizer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js b/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js index ff514517af3e6..9ada2ea9d0809 100644 --- a/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js +++ b/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js @@ -33,9 +33,9 @@ export function GridItemResizer( { clientId, onChange } ) { bottom: true, bottomLeft: false, bottomRight: false, - left: true, + left: false, right: true, - top: true, + top: false, topLeft: false, topRight: false, } } From 088cf0f0a5edfd381d9dc532336ddc916da044a6 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Thu, 15 Feb 2024 16:39:12 +1100 Subject: [PATCH 06/17] Clean up CSS --- packages/base-styles/_z-index.scss | 3 ++ .../grid-visualizer/grid-item-resizer.js | 12 ++------ .../grid-visualizer/grid-visualizer.js | 1 - .../src/components/grid-visualizer/style.scss | 29 +++++++++++++++++++ packages/block-editor/src/hooks/layout.scss | 13 --------- packages/block-editor/src/style.scss | 1 + 6 files changed, 36 insertions(+), 23 deletions(-) create mode 100644 packages/block-editor/src/components/grid-visualizer/style.scss diff --git a/packages/base-styles/_z-index.scss b/packages/base-styles/_z-index.scss index ff21d1d8df8f3..762508f921a00 100644 --- a/packages/base-styles/_z-index.scss +++ b/packages/base-styles/_z-index.scss @@ -108,6 +108,9 @@ $z-layers: ( // Above the block list and the header. ".block-editor-block-popover": 31, + // Below the block toolbar. + ".block-editor-grid-visualizer": 30, + // Show snackbars above everything (similar to popovers) ".components-snackbar-list": 100000, diff --git a/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js b/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js index 9ada2ea9d0809..98f36496a1d7e 100644 --- a/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js +++ b/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js @@ -19,12 +19,14 @@ export function GridItemResizer( { clientId, onChange } ) { } return ( -
- + /> ); } diff --git a/packages/block-editor/src/components/grid-visualizer/grid-visualizer.js b/packages/block-editor/src/components/grid-visualizer/grid-visualizer.js index e7b86e3a3de97..1b0c9ec697849 100644 --- a/packages/block-editor/src/components/grid-visualizer/grid-visualizer.js +++ b/packages/block-editor/src/components/grid-visualizer/grid-visualizer.js @@ -31,7 +31,6 @@ export function GridVisualizer( { clientId } ) {
Date: Mon, 19 Feb 2024 13:18:04 +1100 Subject: [PATCH 07/17] Add shift=false to popovers --- .../src/components/grid-visualizer/grid-item-resizer.js | 1 + .../src/components/grid-visualizer/grid-visualizer.js | 1 + .../block-editor/src/components/grid-visualizer/style.scss | 4 ++++ 3 files changed, 6 insertions(+) diff --git a/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js b/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js index 98f36496a1d7e..c05ed40c43816 100644 --- a/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js +++ b/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js @@ -23,6 +23,7 @@ export function GridItemResizer( { clientId, onChange } ) { clientId={ clientId } __unstableCoverTarget __unstablePopoverSlot="block-toolbar" + shift={ false } >
Date: Mon, 19 Feb 2024 15:28:14 +1100 Subject: [PATCH 08/17] Accommodate variably sized columns/rows by using grid-template to calculate span --- .../grid-visualizer/grid-item-resizer.js | 115 ++++++++++-------- 1 file changed, 67 insertions(+), 48 deletions(-) diff --git a/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js b/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js index c05ed40c43816..afe825f88ebd8 100644 --- a/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js +++ b/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js @@ -42,61 +42,80 @@ export function GridItemResizer( { clientId, onChange } ) { topLeft: false, topRight: false, } } - onResizeStop={ ( event, direction, element ) => { - const boxWidth = element.offsetWidth; - const boxHeight = element.offsetHeight; - const { columnGap, rowGap, itemWidth, itemHeight } = - getGridDimensions( blockElement.parentElement ); - const columnSpan = Math.round( - ( columnGap + boxWidth ) / ( columnGap + itemWidth ) + onResizeStop={ ( event, direction, boxElement ) => { + const gridElement = blockElement.parentElement; + const columnGap = parseFloat( + getComputedCSS( gridElement, 'column-gap' ) ); - const rowSpan = Math.round( - ( rowGap + boxHeight ) / ( rowGap + itemHeight ) + const rowGap = parseFloat( + getComputedCSS( gridElement, 'row-gap' ) ); - const newBoxWidth = - columnSpan * itemWidth + ( columnSpan - 1 ) * columnGap; - const newBoxHeight = - rowSpan * itemHeight + ( rowSpan - 1 ) * rowGap; - onChange( { - columnSpan, - rowSpan, - } ); - resizableRef.current.updateSize( { - width: newBoxWidth, - height: newBoxHeight, - } ); + const gridColumnLines = getGridLines( + getComputedCSS( gridElement, 'grid-template-columns' ), + columnGap + ); + const gridRowLines = getGridLines( + getComputedCSS( gridElement, 'grid-template-rows' ), + rowGap + ); + const columnStart = getClosestLine( + gridColumnLines, + blockElement.offsetLeft + ); + const rowStart = getClosestLine( + gridRowLines, + blockElement.offsetTop + ); + const columnEnd = getClosestLine( + gridColumnLines, + blockElement.offsetLeft + boxElement.offsetWidth + ); + const rowEnd = getClosestLine( + gridRowLines, + blockElement.offsetTop + boxElement.offsetHeight + ); + const columnSpan = Math.max( columnEnd - columnStart, 1 ); + const rowSpan = Math.max( rowEnd - rowStart, 1 ); + const width = + gridColumnLines[ columnStart + columnSpan ] - + gridColumnLines[ columnStart ] - + columnGap; + const height = + gridRowLines[ rowStart + rowSpan ] - + gridRowLines[ rowStart ] - + rowGap; + onChange( { columnSpan, rowSpan } ); + resizableRef.current.updateSize( { width, height } ); } } /> ); } -function getGridDimensions( element ) { - const width = element.clientWidth; - const height = element.clientHeight; - const paddingX = - parseFloat( getComputedCSS( element, 'padding-left' ) ) + - parseFloat( getComputedCSS( element, 'padding-right' ) ); - const paddingY = - parseFloat( getComputedCSS( element, 'padding-top' ) ) + - parseFloat( getComputedCSS( element, 'padding-bottom' ) ); - const gridTemplateColumns = getComputedCSS( - element, - 'grid-template-columns' +/** + * @param {string} template + * @param {number} gap + */ +function getGridLines( template, gap ) { + const lines = [ 0 ]; + for ( const size of template.split( ' ' ) ) { + const line = parseFloat( size ); + lines.push( lines[ lines.length - 1 ] + line + gap ); + } + return lines; +} + +/** + * @param {number[]} lines + * @param {number} position + */ +function getClosestLine( lines, position ) { + return lines.reduce( + ( closest, line, index ) => + Math.abs( line - position ) < + Math.abs( lines[ closest ] - position ) + ? index + : closest, + 0 ); - const gridTemplateRows = getComputedCSS( element, 'grid-template-rows' ); - const numColumns = gridTemplateColumns.split( ' ' ).length; - const numRows = gridTemplateRows.split( ' ' ).length; - const columnGap = parseFloat( getComputedCSS( element, 'column-gap' ) ); - const rowGap = parseFloat( getComputedCSS( element, 'row-gap' ) ); - const totalColumnGap = columnGap * ( numColumns - 1 ); - const totalRowGap = rowGap * ( numRows - 1 ); - const itemWidth = ( width - paddingX - totalColumnGap ) / numColumns; - const itemHeight = ( height - paddingY - totalRowGap ) / numRows; - return { - columnGap, - rowGap, - itemWidth, - itemHeight, - }; } From 4db7ab0892d92c7d5e6a86c6c33888e6c7a657c1 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Mon, 19 Feb 2024 16:29:07 +1100 Subject: [PATCH 09/17] BlockPopover: Use ResizeObserver to match size of covered block --- .../src/components/block-popover/index.js | 25 ++++++++++++++-- .../grid-visualizer/grid-item-resizer.js | 29 ++++--------------- .../block-editor/src/hooks/layout-child.js | 4 +-- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/packages/block-editor/src/components/block-popover/index.js b/packages/block-editor/src/components/block-popover/index.js index 13e6ba4d9e7f8..f23466b98e620 100644 --- a/packages/block-editor/src/components/block-popover/index.js +++ b/packages/block-editor/src/components/block-popover/index.js @@ -13,6 +13,7 @@ import { useMemo, useReducer, useLayoutEffect, + useState, } from '@wordpress/element'; /** @@ -75,6 +76,23 @@ function BlockPopover( }; }, [ selectedElement ] ); + const [ selectedElementWidth, setSelectedElementWidth ] = useState( + selectedElement.offsetWidth + ); + const [ selectedElementHeight, setSelectedElementHeight ] = useState( + selectedElement.offsetHeight + ); + useLayoutEffect( () => { + if ( ! selectedElement ) { + return; + } + const observer = new window.ResizeObserver( () => { + setSelectedElementWidth( selectedElement.offsetWidth ); + setSelectedElementHeight( selectedElement.offsetHeight ); + } ); + observer.observe( selectedElement ); + return () => observer.disconnect(); + } ); const style = useMemo( () => { if ( // popoverDimensionsRecomputeCounter is by definition always equal or greater @@ -86,17 +104,18 @@ function BlockPopover( ) { return {}; } - return { position: 'absolute', - width: selectedElement.offsetWidth, - height: selectedElement.offsetHeight, + width: selectedElementWidth, + height: selectedElementHeight, }; }, [ selectedElement, lastSelectedElement, __unstableRefreshSize, popoverDimensionsRecomputeCounter, + selectedElementWidth, + selectedElementHeight, ] ); const popoverAnchor = useMemo( () => { diff --git a/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js b/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js index afe825f88ebd8..19e079e8a737f 100644 --- a/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js +++ b/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js @@ -2,7 +2,6 @@ * WordPress dependencies */ import { ResizableBox } from '@wordpress/components'; -import { useRef } from '@wordpress/element'; /** * Internal dependencies @@ -12,7 +11,6 @@ import BlockPopover from '../block-popover'; import { getComputedCSS } from './utils'; export function GridItemResizer( { clientId, onChange } ) { - const resizableRef = useRef(); const blockElement = useBlockElement( clientId ); if ( ! blockElement ) { return null; @@ -26,9 +24,8 @@ export function GridItemResizer( { clientId, onChange } ) { shift={ false } > ); } -/** - * @param {string} template - * @param {number} gap - */ function getGridLines( template, gap ) { const lines = [ 0 ]; for ( const size of template.split( ' ' ) ) { @@ -105,10 +90,6 @@ function getGridLines( template, gap ) { return lines; } -/** - * @param {number[]} lines - * @param {number} position - */ function getClosestLine( lines, position ) { return lines.reduce( ( closest, line, index ) => diff --git a/packages/block-editor/src/hooks/layout-child.js b/packages/block-editor/src/hooks/layout-child.js index 42abca9383bca..17cc328fdefcf 100644 --- a/packages/block-editor/src/hooks/layout-child.js +++ b/packages/block-editor/src/hooks/layout-child.js @@ -113,14 +113,14 @@ function ChildLayoutControlsPure( { clientId, style, setAttributes } ) { { + onChange={ ( { columnSpan, rowSpan } ) => { setAttributes( { style: { ...style, layout: { ...style?.layout, - rowSpan, columnSpan, + rowSpan, }, }, } ); From e6567abd311a7cdaa06004f9211155bc0c17b808 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Tue, 20 Feb 2024 14:05:39 +1100 Subject: [PATCH 10/17] Fix error due to undefined selectedElement --- packages/block-editor/src/components/block-popover/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/block-popover/index.js b/packages/block-editor/src/components/block-popover/index.js index f23466b98e620..ffb4266d30a9a 100644 --- a/packages/block-editor/src/components/block-popover/index.js +++ b/packages/block-editor/src/components/block-popover/index.js @@ -77,10 +77,10 @@ function BlockPopover( }, [ selectedElement ] ); const [ selectedElementWidth, setSelectedElementWidth ] = useState( - selectedElement.offsetWidth + selectedElement?.offsetWidth ); const [ selectedElementHeight, setSelectedElementHeight ] = useState( - selectedElement.offsetHeight + selectedElement?.offsetHeight ); useLayoutEffect( () => { if ( ! selectedElement ) { From a03661413c0dd4134cb58311c1e734ed24fa3450 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Wed, 21 Feb 2024 10:09:30 +1100 Subject: [PATCH 11/17] Update GridVisualizer when grid or its children resize --- .../grid-visualizer/grid-visualizer.js | 85 +++++++++++++------ 1 file changed, 59 insertions(+), 26 deletions(-) diff --git a/packages/block-editor/src/components/grid-visualizer/grid-visualizer.js b/packages/block-editor/src/components/grid-visualizer/grid-visualizer.js index d4bfd9f4a50af..8bc2f13c27653 100644 --- a/packages/block-editor/src/components/grid-visualizer/grid-visualizer.js +++ b/packages/block-editor/src/components/grid-visualizer/grid-visualizer.js @@ -1,3 +1,8 @@ +/** + * WordPress dependencies + */ +import { useState, useEffect } from '@wordpress/element'; + /** * Internal dependencies */ @@ -10,6 +15,51 @@ export function GridVisualizer( { clientId } ) { if ( ! blockElement ) { return null; } + return ( + + + + ); +} + +function GridVisualizerGrid( { blockElement } ) { + const [ gridInfo, setGridInfo ] = useState( () => + getGridInfo( blockElement ) + ); + useEffect( () => { + const observers = []; + for ( const element of [ blockElement, ...blockElement.children ] ) { + const observer = new window.ResizeObserver( () => { + setGridInfo( getGridInfo( blockElement ) ); + } ); + observer.observe( element ); + observers.push( observer ); + } + return () => { + for ( const observer of observers ) { + observer.disconnect(); + } + }; + }, [ blockElement ] ); + return ( +
+ { Array.from( { length: gridInfo.numItems }, ( _, i ) => ( +
+ ) ) } +
+ ); +} + +function getGridInfo( blockElement ) { const gridTemplateColumns = getComputedCSS( blockElement, 'grid-template-columns' @@ -21,30 +71,13 @@ export function GridVisualizer( { clientId } ) { const numColumns = gridTemplateColumns.split( ' ' ).length; const numRows = gridTemplateRows.split( ' ' ).length; const numItems = numColumns * numRows; - return ( - -
- { Array.from( { length: numItems }, ( _, i ) => ( -
- ) ) } -
- - ); + return { + numItems, + style: { + gridTemplateColumns, + gridTemplateRows, + gap: getComputedCSS( blockElement, 'gap' ), + padding: getComputedCSS( blockElement, 'padding' ), + }, + }; } From df65b366654109428d02761efe26d7cc647049d2 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Wed, 21 Feb 2024 10:40:40 +1100 Subject: [PATCH 12/17] Add experimental flag --- lib/experimental/editor-settings.php | 3 +++ lib/experiments-page.php | 14 ++++++++++++++ packages/block-editor/src/hooks/layout-child.js | 3 +++ packages/block-editor/src/layouts/grid.js | 4 +++- 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/experimental/editor-settings.php b/lib/experimental/editor-settings.php index b97cb649bb0bc..15f0f25a68b10 100644 --- a/lib/experimental/editor-settings.php +++ b/lib/experimental/editor-settings.php @@ -22,6 +22,9 @@ function gutenberg_enable_experiments() { if ( $gutenberg_experiments && array_key_exists( 'gutenberg-color-randomizer', $gutenberg_experiments ) ) { wp_add_inline_script( 'wp-block-editor', 'window.__experimentalEnableColorRandomizer = true', 'before' ); } + if ( $gutenberg_experiments && array_key_exists( 'gutenberg-grid-interactivity', $gutenberg_experiments ) ) { + wp_add_inline_script( 'wp-block-editor', 'window.__experimentalEnableGridInteractivity = true', 'before' ); + } if ( gutenberg_is_experiment_enabled( 'gutenberg-no-tinymce' ) ) { wp_add_inline_script( 'wp-block-library', 'window.__experimentalDisableTinymce = true', 'before' ); } diff --git a/lib/experiments-page.php b/lib/experiments-page.php index 6608fbb138c58..a7286d9884728 100644 --- a/lib/experiments-page.php +++ b/lib/experiments-page.php @@ -90,6 +90,7 @@ function gutenberg_initialize_experiments_settings() { 'id' => 'gutenberg-color-randomizer', ) ); + add_settings_field( 'gutenberg-form-blocks', __( 'Form and input blocks ', 'gutenberg' ), @@ -101,6 +102,19 @@ function gutenberg_initialize_experiments_settings() { 'id' => 'gutenberg-form-blocks', ) ); + + add_settings_field( + 'gutenberg-grid-interactivity', + __( 'Grid interactivty ', 'gutenberg' ), + 'gutenberg_display_experiment_field', + 'gutenberg-experiments', + 'gutenberg_experiments_section', + array( + 'label' => __( 'Test enhancements to the Grid block that let you move and resize items in the editor canvas.', 'gutenberg' ), + 'id' => 'gutenberg-grid-interactivity', + ) + ); + add_settings_field( 'gutenberg-no-tinymce', __( 'Disable TinyMCE and Classic block', 'gutenberg' ), diff --git a/packages/block-editor/src/hooks/layout-child.js b/packages/block-editor/src/hooks/layout-child.js index 17cc328fdefcf..d8333e8e0e830 100644 --- a/packages/block-editor/src/hooks/layout-child.js +++ b/packages/block-editor/src/hooks/layout-child.js @@ -108,6 +108,9 @@ function ChildLayoutControlsPure( { clientId, style, setAttributes } ) { if ( parentLayout.type !== 'grid' ) { return null; } + if ( ! window.__experimentalEnableGridInteractivity ) { + return null; + } return ( <> diff --git a/packages/block-editor/src/layouts/grid.js b/packages/block-editor/src/layouts/grid.js index f6c3ee5989ce1..771ad7debad06 100644 --- a/packages/block-editor/src/layouts/grid.js +++ b/packages/block-editor/src/layouts/grid.js @@ -86,7 +86,9 @@ export default { onChange={ onChange } /> ) } - + { window.__experimentalEnableGridInteractivity && ( + + ) } ); }, From cbc5b501ef71c99bd8a2c0c5b177b3b5e11707c2 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Wed, 21 Feb 2024 11:25:12 +1100 Subject: [PATCH 13/17] Fix formatting --- lib/experiments-page.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/experiments-page.php b/lib/experiments-page.php index a7286d9884728..f66e093219263 100644 --- a/lib/experiments-page.php +++ b/lib/experiments-page.php @@ -104,16 +104,16 @@ function gutenberg_initialize_experiments_settings() { ); add_settings_field( - 'gutenberg-grid-interactivity', - __( 'Grid interactivty ', 'gutenberg' ), - 'gutenberg_display_experiment_field', - 'gutenberg-experiments', - 'gutenberg_experiments_section', - array( - 'label' => __( 'Test enhancements to the Grid block that let you move and resize items in the editor canvas.', 'gutenberg' ), - 'id' => 'gutenberg-grid-interactivity', - ) - ); + 'gutenberg-grid-interactivity', + __( 'Grid interactivty ', 'gutenberg' ), + 'gutenberg_display_experiment_field', + 'gutenberg-experiments', + 'gutenberg_experiments_section', + array( + 'label' => __( 'Test enhancements to the Grid block that let you move and resize items in the editor canvas.', 'gutenberg' ), + 'id' => 'gutenberg-grid-interactivity', + ) + ); add_settings_field( 'gutenberg-no-tinymce', From e1c2c92d2f63d3c84ac1c9714d8d6614a2bb2163 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Wed, 21 Feb 2024 11:27:47 +1100 Subject: [PATCH 14/17] Go away spaces --- lib/experimental/editor-settings.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/experimental/editor-settings.php b/lib/experimental/editor-settings.php index 15f0f25a68b10..f5d40ae8a2110 100644 --- a/lib/experimental/editor-settings.php +++ b/lib/experimental/editor-settings.php @@ -23,8 +23,8 @@ function gutenberg_enable_experiments() { wp_add_inline_script( 'wp-block-editor', 'window.__experimentalEnableColorRandomizer = true', 'before' ); } if ( $gutenberg_experiments && array_key_exists( 'gutenberg-grid-interactivity', $gutenberg_experiments ) ) { - wp_add_inline_script( 'wp-block-editor', 'window.__experimentalEnableGridInteractivity = true', 'before' ); - } + wp_add_inline_script( 'wp-block-editor', 'window.__experimentalEnableGridInteractivity = true', 'before' ); + } if ( gutenberg_is_experiment_enabled( 'gutenberg-no-tinymce' ) ) { wp_add_inline_script( 'wp-block-library', 'window.__experimentalDisableTinymce = true', 'before' ); } From f0c111ae3dcae65b932d9d256f923e190a0ca37b Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Wed, 21 Feb 2024 15:25:57 +1100 Subject: [PATCH 15/17] BlockPopover: Remove __unstableRefreshSize prop and improve how __unstableCoverTarget works --- .../src/components/block-popover/index.js | 62 +++++++++++-------- packages/block-editor/src/hooks/margin.js | 1 - packages/block-editor/src/hooks/padding.js | 1 - .../src/cover/edit/resizable-cover-popover.js | 7 +-- 4 files changed, 36 insertions(+), 35 deletions(-) diff --git a/packages/block-editor/src/components/block-popover/index.js b/packages/block-editor/src/components/block-popover/index.js index 13e6ba4d9e7f8..9cbee1b372bc3 100644 --- a/packages/block-editor/src/components/block-popover/index.js +++ b/packages/block-editor/src/components/block-popover/index.js @@ -13,6 +13,7 @@ import { useMemo, useReducer, useLayoutEffect, + useState, } from '@wordpress/element'; /** @@ -28,7 +29,6 @@ function BlockPopover( clientId, bottomClientId, children, - __unstableRefreshSize, __unstableCoverTarget = false, __unstablePopoverSlot, __unstableContentRef, @@ -75,30 +75,6 @@ function BlockPopover( }; }, [ selectedElement ] ); - const style = useMemo( () => { - if ( - // popoverDimensionsRecomputeCounter is by definition always equal or greater - // than 0. This check is only there to satisfy the correctness of the - // exhaustive-deps rule for the `useMemo` hook. - popoverDimensionsRecomputeCounter < 0 || - ! selectedElement || - lastSelectedElement !== selectedElement - ) { - return {}; - } - - return { - position: 'absolute', - width: selectedElement.offsetWidth, - height: selectedElement.offsetHeight, - }; - }, [ - selectedElement, - lastSelectedElement, - __unstableRefreshSize, - popoverDimensionsRecomputeCounter, - ] ); - const popoverAnchor = useMemo( () => { if ( // popoverDimensionsRecomputeCounter is by definition always equal or greater @@ -155,6 +131,9 @@ function BlockPopover( return null; } + const shouldCoverTarget = + __unstableCoverTarget && lastSelectedElement === selectedElement; + return ( - { __unstableCoverTarget &&
{ children }
} - { ! __unstableCoverTarget && children } + { shouldCoverTarget ? ( + + { children } + + ) : ( + children + ) }
); } +function CoverTargetContainer( { selectedElement, children } ) { + const [ width, setWidth ] = useState( selectedElement.offsetWidth ); + const [ height, setHeight ] = useState( selectedElement.offsetHeight ); + + useLayoutEffect( () => { + const observer = new window.ResizeObserver( () => { + setWidth( selectedElement.offsetWidth ); + setHeight( selectedElement.offsetHeight ); + } ); + observer.observe( selectedElement, { box: 'border-box' } ); + return () => observer.disconnect(); + }, [ selectedElement ] ); + + const style = useMemo( () => { + return { + position: 'absolute', + width, + height, + }; + }, [ width, height ] ); + + return
{ children }
; +} + export default forwardRef( BlockPopover ); diff --git a/packages/block-editor/src/hooks/margin.js b/packages/block-editor/src/hooks/margin.js index 8f723b3f8c97d..d81dcf86a0148 100644 --- a/packages/block-editor/src/hooks/margin.js +++ b/packages/block-editor/src/hooks/margin.js @@ -81,7 +81,6 @@ export function MarginVisualizer( { clientId, attributes, forceShow } ) { diff --git a/packages/block-editor/src/hooks/padding.js b/packages/block-editor/src/hooks/padding.js index ca4436153d122..10085e5ae6291 100644 --- a/packages/block-editor/src/hooks/padding.js +++ b/packages/block-editor/src/hooks/padding.js @@ -72,7 +72,6 @@ export function PaddingVisualizer( { clientId, value, forceShow } ) { diff --git a/packages/block-library/src/cover/edit/resizable-cover-popover.js b/packages/block-library/src/cover/edit/resizable-cover-popover.js index 7db8b0cc50b88..64d1bf106c3bc 100644 --- a/packages/block-library/src/cover/edit/resizable-cover-popover.js +++ b/packages/block-library/src/cover/edit/resizable-cover-popover.js @@ -6,7 +6,7 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { useMemo, useState } from '@wordpress/element'; +import { useState } from '@wordpress/element'; import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor'; /** @@ -40,10 +40,6 @@ export default function ResizableCoverPopover( { ...props } ) { const [ isResizing, setIsResizing ] = useState( false ); - const dimensions = useMemo( - () => ( { height, minHeight, width } ), - [ minHeight, height, width ] - ); const resizableBoxProps = { className: classnames( className, { 'is-resizing': isResizing } ), @@ -75,7 +71,6 @@ export default function ResizableCoverPopover( { return ( From 4e508486e37b853630dc290619ccbce922e0d20f Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Wed, 21 Feb 2024 16:03:15 +1100 Subject: [PATCH 16/17] BlockPopover: Remove __unstableCoverTarget in favour of BlockPopoverCover --- .../src/components/block-popover/cover.js | 63 +++++++++++++++++++ .../src/components/block-popover/drop-zone.js | 7 +-- .../src/components/block-popover/index.js | 37 +---------- .../block-tools/empty-block-inserter.js | 9 +-- .../components/resizable-box-popover/index.js | 8 +-- packages/block-editor/src/hooks/margin.js | 8 +-- packages/block-editor/src/hooks/padding.js | 8 +-- 7 files changed, 79 insertions(+), 61 deletions(-) create mode 100644 packages/block-editor/src/components/block-popover/cover.js diff --git a/packages/block-editor/src/components/block-popover/cover.js b/packages/block-editor/src/components/block-popover/cover.js new file mode 100644 index 0000000000000..6d2d5b8ce1ac0 --- /dev/null +++ b/packages/block-editor/src/components/block-popover/cover.js @@ -0,0 +1,63 @@ +/** + * WordPress dependencies + */ +import { useEffect, useState, useMemo, forwardRef } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { __unstableUseBlockElement as useBlockElement } from '../block-list/use-block-props/use-block-refs'; +import BlockPopover from '.'; + +function BlockPopoverCover( + { clientId, bottomClientId, children, shift = false, ...props }, + ref +) { + bottomClientId ??= clientId; + + const selectedElement = useBlockElement( clientId ); + + return ( + + { selectedElement && clientId === bottomClientId ? ( + + { children } + + ) : ( + children + ) } + + ); +} + +function CoverContainer( { selectedElement, children } ) { + const [ width, setWidth ] = useState( selectedElement.offsetWidth ); + const [ height, setHeight ] = useState( selectedElement.offsetHeight ); + + useEffect( () => { + const observer = new window.ResizeObserver( () => { + setWidth( selectedElement.offsetWidth ); + setHeight( selectedElement.offsetHeight ); + } ); + observer.observe( selectedElement, { box: 'border-box' } ); + return () => observer.disconnect(); + }, [ selectedElement ] ); + + const style = useMemo( () => { + return { + position: 'absolute', + width, + height, + }; + }, [ width, height ] ); + + return
{ children }
; +} + +export default forwardRef( BlockPopoverCover ); diff --git a/packages/block-editor/src/components/block-popover/drop-zone.js b/packages/block-editor/src/components/block-popover/drop-zone.js index c26f28127022d..1174c619cb3f4 100644 --- a/packages/block-editor/src/components/block-popover/drop-zone.js +++ b/packages/block-editor/src/components/block-popover/drop-zone.js @@ -9,7 +9,7 @@ import { __unstableMotion as motion } from '@wordpress/components'; * Internal dependencies */ import { store as blockEditorStore } from '../../store'; -import BlockPopover from './index'; +import BlockPopoverCover from './cover'; const animateVariants = { hide: { opacity: 0, scaleY: 0.75 }, @@ -38,9 +38,8 @@ function BlockDropZonePopover( { const reducedMotion = useReducedMotion(); return ( - - + ); } diff --git a/packages/block-editor/src/components/block-popover/index.js b/packages/block-editor/src/components/block-popover/index.js index 9cbee1b372bc3..d5ac90c68745e 100644 --- a/packages/block-editor/src/components/block-popover/index.js +++ b/packages/block-editor/src/components/block-popover/index.js @@ -13,7 +13,6 @@ import { useMemo, useReducer, useLayoutEffect, - useState, } from '@wordpress/element'; /** @@ -29,7 +28,6 @@ function BlockPopover( clientId, bottomClientId, children, - __unstableCoverTarget = false, __unstablePopoverSlot, __unstableContentRef, shift = true, @@ -131,9 +129,6 @@ function BlockPopover( return null; } - const shouldCoverTarget = - __unstableCoverTarget && lastSelectedElement === selectedElement; - return ( - { shouldCoverTarget ? ( - - { children } - - ) : ( - children - ) } + { children } ); } -function CoverTargetContainer( { selectedElement, children } ) { - const [ width, setWidth ] = useState( selectedElement.offsetWidth ); - const [ height, setHeight ] = useState( selectedElement.offsetHeight ); - - useLayoutEffect( () => { - const observer = new window.ResizeObserver( () => { - setWidth( selectedElement.offsetWidth ); - setHeight( selectedElement.offsetHeight ); - } ); - observer.observe( selectedElement, { box: 'border-box' } ); - return () => observer.disconnect(); - }, [ selectedElement ] ); - - const style = useMemo( () => { - return { - position: 'absolute', - width, - height, - }; - }, [ width, height ] ); - - return
{ children }
; -} - export default forwardRef( BlockPopover ); diff --git a/packages/block-editor/src/components/block-tools/empty-block-inserter.js b/packages/block-editor/src/components/block-tools/empty-block-inserter.js index 1d520ed72b1c6..bf708c686363f 100644 --- a/packages/block-editor/src/components/block-tools/empty-block-inserter.js +++ b/packages/block-editor/src/components/block-tools/empty-block-inserter.js @@ -6,7 +6,7 @@ import classnames from 'classnames'; /** * Internal dependencies */ -import BlockPopover from '../block-popover'; +import BlockPopoverCover from '../block-popover/cover'; import useBlockToolbarPopoverProps from './use-block-toolbar-popover-props'; import Inserter from '../inserter'; import useSelectedBlockToolProps from './use-selected-block-tool-props'; @@ -28,9 +28,8 @@ export default function EmptyBlockInserter( { } ); return ( -
@@ -51,6 +48,6 @@ export default function EmptyBlockInserter( { __experimentalIsQuick />
-
+ ); } diff --git a/packages/block-editor/src/components/resizable-box-popover/index.js b/packages/block-editor/src/components/resizable-box-popover/index.js index 12a61aceaaf38..8a49c1631287a 100644 --- a/packages/block-editor/src/components/resizable-box-popover/index.js +++ b/packages/block-editor/src/components/resizable-box-popover/index.js @@ -6,7 +6,7 @@ import { ResizableBox } from '@wordpress/components'; /** * Internal dependencies */ -import BlockPopover from '../block-popover'; +import BlockPopoverCover from '../block-popover/cover'; export default function ResizableBoxPopover( { clientId, @@ -14,14 +14,12 @@ export default function ResizableBoxPopover( { ...props } ) { return ( - - + ); } diff --git a/packages/block-editor/src/hooks/margin.js b/packages/block-editor/src/hooks/margin.js index d81dcf86a0148..7be1179d29510 100644 --- a/packages/block-editor/src/hooks/margin.js +++ b/packages/block-editor/src/hooks/margin.js @@ -7,7 +7,7 @@ import isShallowEqual from '@wordpress/is-shallow-equal'; /** * Internal dependencies */ -import BlockPopover from '../components/block-popover'; +import BlockPopoverCover from '../components/block-popover/cover'; import { __unstableUseBlockElement as useBlockElement } from '../components/block-list/use-block-props/use-block-refs'; function getComputedCSS( element, property ) { @@ -78,13 +78,11 @@ export function MarginVisualizer( { clientId, attributes, forceShow } ) { } return ( -
- + ); } diff --git a/packages/block-editor/src/hooks/padding.js b/packages/block-editor/src/hooks/padding.js index 10085e5ae6291..50eed7ac05d5e 100644 --- a/packages/block-editor/src/hooks/padding.js +++ b/packages/block-editor/src/hooks/padding.js @@ -7,7 +7,7 @@ import isShallowEqual from '@wordpress/is-shallow-equal'; /** * Internal dependencies */ -import BlockPopover from '../components/block-popover'; +import BlockPopoverCover from '../components/block-popover/cover'; import { __unstableUseBlockElement as useBlockElement } from '../components/block-list/use-block-props/use-block-refs'; function getComputedCSS( element, property ) { @@ -69,13 +69,11 @@ export function PaddingVisualizer( { clientId, value, forceShow } ) { } return ( -
- + ); } From fcdbc902f3f7f06feadc31d9a8c4a7019b46dabf Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Thu, 22 Feb 2024 15:32:39 +1100 Subject: [PATCH 17/17] Use BlockPopoverCover --- .../src/components/grid-visualizer/grid-item-resizer.js | 8 +++----- .../src/components/grid-visualizer/grid-visualizer.js | 8 +++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js b/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js index 19e079e8a737f..54683e48beeea 100644 --- a/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js +++ b/packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js @@ -7,7 +7,7 @@ import { ResizableBox } from '@wordpress/components'; * Internal dependencies */ import { __unstableUseBlockElement as useBlockElement } from '../block-list/use-block-props/use-block-refs'; -import BlockPopover from '../block-popover'; +import BlockPopoverCover from '../block-popover/cover'; import { getComputedCSS } from './utils'; export function GridItemResizer( { clientId, onChange } ) { @@ -16,12 +16,10 @@ export function GridItemResizer( { clientId, onChange } ) { return null; } return ( - - + ); } diff --git a/packages/block-editor/src/components/grid-visualizer/grid-visualizer.js b/packages/block-editor/src/components/grid-visualizer/grid-visualizer.js index 8bc2f13c27653..2ca65eb6722e4 100644 --- a/packages/block-editor/src/components/grid-visualizer/grid-visualizer.js +++ b/packages/block-editor/src/components/grid-visualizer/grid-visualizer.js @@ -7,7 +7,7 @@ import { useState, useEffect } from '@wordpress/element'; * Internal dependencies */ import { __unstableUseBlockElement as useBlockElement } from '../block-list/use-block-props/use-block-refs'; -import BlockPopover from '../block-popover'; +import BlockPopoverCover from '../block-popover/cover'; import { getComputedCSS } from './utils'; export function GridVisualizer( { clientId } ) { @@ -16,15 +16,13 @@ export function GridVisualizer( { clientId } ) { return null; } return ( - - + ); }