From b74481f6612884b02f50aa7e7e80f6c5e8e388f3 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Wed, 7 Aug 2024 16:39:52 +0800 Subject: [PATCH 01/25] Add support to root block list in `useBlockRefs` --- packages/block-editor/src/components/block-list/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/block-editor/src/components/block-list/index.js b/packages/block-editor/src/components/block-list/index.js index 37dba80511d92..b7575d760702e 100644 --- a/packages/block-editor/src/components/block-list/index.js +++ b/packages/block-editor/src/components/block-list/index.js @@ -40,6 +40,7 @@ import { } from '../block-edit/context'; import { useTypingObserver } from '../observe-typing'; import { unlock } from '../../lock-unlock'; +import { useBlockRefProvider } from './use-block-props/use-block-refs'; export const IntersectionObserver = createContext(); const pendingBlockVisibilityUpdatesPerRegistry = new WeakMap(); @@ -110,6 +111,7 @@ function Root( { className, ...settings } ) { useBlockSelectionClearer(), useInBetweenInserter(), useTypingObserver(), + useBlockRefProvider( '' ), ] ), className: clsx( 'is-root-container', className, { 'is-outline-mode': isOutlineMode, From 995d04d3ab03150b960c517de4546ae055ccf503 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Wed, 7 Aug 2024 16:40:10 +0800 Subject: [PATCH 02/25] Add basic underlay component --- .../src/components/grid/grid-underlay.js | 79 +++++++++++++++++++ .../src/components/grid/grid-visualizer.js | 7 +- 2 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 packages/block-editor/src/components/grid/grid-underlay.js diff --git a/packages/block-editor/src/components/grid/grid-underlay.js b/packages/block-editor/src/components/grid/grid-underlay.js new file mode 100644 index 0000000000000..83d722ce39b91 --- /dev/null +++ b/packages/block-editor/src/components/grid/grid-underlay.js @@ -0,0 +1,79 @@ +/** + * WordPress dependencies + */ +import { useSelect } from '@wordpress/data'; +import { useEffect, useState } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { store as blockEditorStore } from '../../store'; +import { useBlockElement } from '../block-list/use-block-props/use-block-refs'; + +/** @typedef {import('react').ReactNode} ReactNode */ + +/** + * Underlay is a bit like a Popover, but is inline so only requires half the code. + * + * @param {Object} props + * @param {string} props.clientId The client id of the block being interacted with. + * @param {string} props.className A classname to add to the grid underlay. + * @param {ReactNode} props.children Child elements. + */ +export default function Underlay( { clientId, className, children } ) { + const [ underlayStyle, setUnderlayStyle ] = useState( { display: 'none' } ); + const rootClientId = useSelect( + ( select ) => + select( blockEditorStore ).getBlockRootClientId( clientId ), + [ clientId ] + ); + const rootElement = useBlockElement( rootClientId ); + const gridElement = useBlockElement( clientId ); + + useEffect( () => { + if ( ! gridElement || ! rootElement ) { + return; + } + + const { ownerDocument } = gridElement; + const { defaultView } = ownerDocument; + + const update = () => { + const rootRect = rootElement.getBoundingClientRect(); + const gridRect = gridElement.getBoundingClientRect(); + + // The 'underlay' has the width and horizontal positioning of the root block list, + // and the height and vertical positioning of the edited block. + // Note: using the root block list is a naive implementation here, ideally the parent + // block that provides the layout should be used. + setUnderlayStyle( { + position: 'absolute', + left: Math.floor( gridRect.left - rootRect.left ), + top: Math.floor( gridRect.top - rootRect.top ), + width: Math.floor( gridRect.width ), + height: Math.floor( gridRect.height ), + margin: 0, + padding: 0, + zIndex: 0, + } ); + }; + + // Observe any resizes of both the layout and focused elements. + const resizeObserver = defaultView.ResizeObserver + ? new defaultView.ResizeObserver( update ) + : undefined; + resizeObserver?.observe( gridElement ); + resizeObserver?.observe( rootElement ); + update(); + + return () => { + resizeObserver?.disconnect(); + }; + }, [ gridElement, rootElement ] ); + + return ( +
+ { children } +
+ ); +} diff --git a/packages/block-editor/src/components/grid/grid-visualizer.js b/packages/block-editor/src/components/grid/grid-visualizer.js index e1d35f012b4d8..3ecaa7ee462fe 100644 --- a/packages/block-editor/src/components/grid/grid-visualizer.js +++ b/packages/block-editor/src/components/grid/grid-visualizer.js @@ -13,8 +13,8 @@ import { __experimentalUseDropZone as useDropZone } from '@wordpress/compose'; /** * Internal dependencies */ +import GridUnderlay from './grid-underlay'; import { useBlockElement } from '../block-list/use-block-props/use-block-refs'; -import BlockPopoverCover from '../block-popover/cover'; import { range, GridRect, getGridInfo } from './utils'; import { store as blockEditorStore } from '../../store'; import { useGetNumberOfBlocksBeforeCell } from './use-get-number-of-blocks-before-cell'; @@ -84,12 +84,11 @@ const GridVisualizerGrid = forwardRef( }, [] ); return ( -
- + ); } ); From c260c5fdad0043da66cc9af2f4f09fa984c70911 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Wed, 7 Aug 2024 17:03:48 +0800 Subject: [PATCH 03/25] Only render GridVisualizer above GridBlock and no longer on LayoutChild. Use context to provide resizer bounds --- .../block-editor/src/components/grid/utils.js | 1 + .../block-editor/src/hooks/grid-visualizer.js | 26 ++++++++++++++----- .../block-editor/src/hooks/layout-child.js | 17 +++--------- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/packages/block-editor/src/components/grid/utils.js b/packages/block-editor/src/components/grid/utils.js index fc012c645f091..4724ac0ad6440 100644 --- a/packages/block-editor/src/components/grid/utils.js +++ b/packages/block-editor/src/components/grid/utils.js @@ -173,6 +173,7 @@ export function getGridInfo( gridElement ) { gridTemplateRows, gap: getComputedCSS( gridElement, 'gap' ), padding: getComputedCSS( gridElement, 'padding' ), + display: 'grid', }, }; } diff --git a/packages/block-editor/src/hooks/grid-visualizer.js b/packages/block-editor/src/hooks/grid-visualizer.js index 44102208c4d1d..1b06cbbd7d3d0 100644 --- a/packages/block-editor/src/hooks/grid-visualizer.js +++ b/packages/block-editor/src/hooks/grid-visualizer.js @@ -4,6 +4,7 @@ import { createHigherOrderComponent } from '@wordpress/compose'; import { addFilter } from '@wordpress/hooks'; import { useSelect } from '@wordpress/data'; +import { createContext, useState } from '@wordpress/element'; /** * Internal dependencies @@ -11,28 +12,39 @@ import { useSelect } from '@wordpress/data'; import { GridVisualizer, useGridLayoutSync } from '../components/grid'; import { store as blockEditorStore } from '../store'; +export const GridResizerBoundsContext = createContext(); + function GridLayoutSync( props ) { useGridLayoutSync( props ); } function GridTools( { clientId, layout } ) { - const { isSelected, isDragging } = useSelect( ( select ) => { - const { isBlockSelected, isDraggingBlocks } = + const { hasSelection, isDragging } = useSelect( ( select ) => { + const { isBlockSelected, hasSelectedInnerBlock, isDraggingBlocks } = select( blockEditorStore ); return { - isSelected: isBlockSelected( clientId ), + hasSelection: + isBlockSelected( clientId ) || + hasSelectedInnerBlock( clientId ), isDragging: isDraggingBlocks(), }; } ); + // Use useState() instead of useRef() so that GridItemResizer updates when ref is set. + const [ resizerBounds, setResizerBounds ] = useState(); + return ( - <> + - { ( isSelected || isDragging ) && ( - + { ( hasSelection || isDragging ) && ( + ) } - + ); } diff --git a/packages/block-editor/src/hooks/layout-child.js b/packages/block-editor/src/hooks/layout-child.js index 8beb50c1b8284..19a33aaf48509 100644 --- a/packages/block-editor/src/hooks/layout-child.js +++ b/packages/block-editor/src/hooks/layout-child.js @@ -3,7 +3,7 @@ */ import { useInstanceId } from '@wordpress/compose'; import { useSelect } from '@wordpress/data'; -import { useState } from '@wordpress/element'; +import { useContext } from '@wordpress/element'; /** * Internal dependencies @@ -11,11 +11,8 @@ import { useState } from '@wordpress/element'; import { store as blockEditorStore } from '../store'; import { useStyleOverride } from './utils'; import { useLayout } from '../components/block-list/layout'; -import { - GridVisualizer, - GridItemResizer, - GridItemMovers, -} from '../components/grid'; +import { GridItemResizer, GridItemMovers } from '../components/grid'; +import { GridResizerBoundsContext } from './grid-visualizer'; function useBlockPropsChildLayoutStyles( { style } ) { const shouldRenderChildLayoutStyles = useSelect( ( select ) => { @@ -179,8 +176,7 @@ function ChildLayoutControlsPure( { clientId, style, setAttributes } ) { [ clientId ] ); - // Use useState() instead of useRef() so that GridItemResizer updates when ref is set. - const [ resizerBounds, setResizerBounds ] = useState(); + const resizerBounds = useContext( GridResizerBoundsContext ); if ( parentLayoutType !== 'grid' ) { return null; @@ -200,11 +196,6 @@ function ChildLayoutControlsPure( { clientId, style, setAttributes } ) { return ( <> - { allowSizingOnChildren && ( Date: Wed, 7 Aug 2024 17:08:34 +0800 Subject: [PATCH 04/25] Remove outdated comment --- packages/block-editor/src/components/grid/grid-underlay.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/block-editor/src/components/grid/grid-underlay.js b/packages/block-editor/src/components/grid/grid-underlay.js index 83d722ce39b91..f92ea14948809 100644 --- a/packages/block-editor/src/components/grid/grid-underlay.js +++ b/packages/block-editor/src/components/grid/grid-underlay.js @@ -42,10 +42,6 @@ export default function Underlay( { clientId, className, children } ) { const rootRect = rootElement.getBoundingClientRect(); const gridRect = gridElement.getBoundingClientRect(); - // The 'underlay' has the width and horizontal positioning of the root block list, - // and the height and vertical positioning of the edited block. - // Note: using the root block list is a naive implementation here, ideally the parent - // block that provides the layout should be used. setUnderlayStyle( { position: 'absolute', left: Math.floor( gridRect.left - rootRect.left ), @@ -64,10 +60,12 @@ export default function Underlay( { clientId, className, children } ) { : undefined; resizeObserver?.observe( gridElement ); resizeObserver?.observe( rootElement ); + // defaultView?.addEventListener( 'resize', update ); update(); return () => { resizeObserver?.disconnect(); + // defaultView?.removeEventListener( 'resize', update ); }; }, [ gridElement, rootElement ] ); From 210b233ae5781b3204683dcc75b9c8774641199a Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Wed, 7 Aug 2024 17:13:49 +0800 Subject: [PATCH 05/25] Move padding to underlay to ensure it refreshes --- .../block-editor/src/components/grid/grid-underlay.js | 10 +++++++--- packages/block-editor/src/components/grid/utils.js | 1 - 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/block-editor/src/components/grid/grid-underlay.js b/packages/block-editor/src/components/grid/grid-underlay.js index f92ea14948809..78d8040fd52c4 100644 --- a/packages/block-editor/src/components/grid/grid-underlay.js +++ b/packages/block-editor/src/components/grid/grid-underlay.js @@ -10,6 +10,12 @@ import { useEffect, useState } from '@wordpress/element'; import { store as blockEditorStore } from '../../store'; import { useBlockElement } from '../block-list/use-block-props/use-block-refs'; +export function getComputedCSS( element, property ) { + return element.ownerDocument.defaultView + .getComputedStyle( element ) + .getPropertyValue( property ); +} + /** @typedef {import('react').ReactNode} ReactNode */ /** @@ -49,7 +55,7 @@ export default function Underlay( { clientId, className, children } ) { width: Math.floor( gridRect.width ), height: Math.floor( gridRect.height ), margin: 0, - padding: 0, + padding: getComputedCSS( gridElement, 'padding' ), zIndex: 0, } ); }; @@ -60,12 +66,10 @@ export default function Underlay( { clientId, className, children } ) { : undefined; resizeObserver?.observe( gridElement ); resizeObserver?.observe( rootElement ); - // defaultView?.addEventListener( 'resize', update ); update(); return () => { resizeObserver?.disconnect(); - // defaultView?.removeEventListener( 'resize', update ); }; }, [ gridElement, rootElement ] ); diff --git a/packages/block-editor/src/components/grid/utils.js b/packages/block-editor/src/components/grid/utils.js index 4724ac0ad6440..40c08896bb839 100644 --- a/packages/block-editor/src/components/grid/utils.js +++ b/packages/block-editor/src/components/grid/utils.js @@ -172,7 +172,6 @@ export function getGridInfo( gridElement ) { gridTemplateColumns, gridTemplateRows, gap: getComputedCSS( gridElement, 'gap' ), - padding: getComputedCSS( gridElement, 'padding' ), display: 'grid', }, }; From 5f983355a0d149219c2f679007c8023fe6fc82d2 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Wed, 7 Aug 2024 17:35:39 +0800 Subject: [PATCH 06/25] Handle block moving --- .../src/components/grid/grid-underlay.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/grid/grid-underlay.js b/packages/block-editor/src/components/grid/grid-underlay.js index 78d8040fd52c4..5b57da72d9c74 100644 --- a/packages/block-editor/src/components/grid/grid-underlay.js +++ b/packages/block-editor/src/components/grid/grid-underlay.js @@ -2,7 +2,7 @@ * WordPress dependencies */ import { useSelect } from '@wordpress/data'; -import { useEffect, useState } from '@wordpress/element'; +import { useLayoutEffect, useState } from '@wordpress/element'; /** * Internal dependencies @@ -36,7 +36,7 @@ export default function Underlay( { clientId, className, children } ) { const rootElement = useBlockElement( rootClientId ); const gridElement = useBlockElement( clientId ); - useEffect( () => { + useLayoutEffect( () => { if ( ! gridElement || ! rootElement ) { return; } @@ -64,12 +64,21 @@ export default function Underlay( { clientId, className, children } ) { const resizeObserver = defaultView.ResizeObserver ? new defaultView.ResizeObserver( update ) : undefined; + const mutationObserver = defaultView.MutationObserver + ? new defaultView.MutationObserver( update ) + : undefined; + + // Monitor grid and parent block resizing. resizeObserver?.observe( gridElement ); resizeObserver?.observe( rootElement ); + + // Monitor block moving. + mutationObserver?.observe( gridElement, { attributes: true } ); update(); return () => { resizeObserver?.disconnect(); + mutationObserver?.disconnect(); }; }, [ gridElement, rootElement ] ); From ebcd38563c1371ef751121f40b08b1fc2d4c7a95 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Wed, 7 Aug 2024 17:50:24 +0800 Subject: [PATCH 07/25] Add a background for cells --- packages/block-editor/src/components/grid/grid-visualizer.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/block-editor/src/components/grid/grid-visualizer.js b/packages/block-editor/src/components/grid/grid-visualizer.js index 3ecaa7ee462fe..78e834513dbe5 100644 --- a/packages/block-editor/src/components/grid/grid-visualizer.js +++ b/packages/block-editor/src/components/grid/grid-visualizer.js @@ -191,6 +191,8 @@ function GridVisualizerCell( { color, children, className } ) { style={ { boxShadow: `inset 0 0 0 1px color-mix(in srgb, ${ color } 20%, #0000)`, color, + background: 'cornflowerblue', + opacity: 0.1, } } > { children } From 9e3b9aef0894b5a8bf638258fa04719a887c2f9f Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Thu, 8 Aug 2024 15:49:30 +0800 Subject: [PATCH 08/25] Use BlockPopoverCover with inline prop --- .../src/components/grid/grid-underlay.js | 90 ------------------- .../src/components/grid/grid-visualizer.js | 7 +- .../block-editor/src/components/grid/utils.js | 1 + 3 files changed, 5 insertions(+), 93 deletions(-) delete mode 100644 packages/block-editor/src/components/grid/grid-underlay.js diff --git a/packages/block-editor/src/components/grid/grid-underlay.js b/packages/block-editor/src/components/grid/grid-underlay.js deleted file mode 100644 index 5b57da72d9c74..0000000000000 --- a/packages/block-editor/src/components/grid/grid-underlay.js +++ /dev/null @@ -1,90 +0,0 @@ -/** - * WordPress dependencies - */ -import { useSelect } from '@wordpress/data'; -import { useLayoutEffect, useState } from '@wordpress/element'; - -/** - * Internal dependencies - */ -import { store as blockEditorStore } from '../../store'; -import { useBlockElement } from '../block-list/use-block-props/use-block-refs'; - -export function getComputedCSS( element, property ) { - return element.ownerDocument.defaultView - .getComputedStyle( element ) - .getPropertyValue( property ); -} - -/** @typedef {import('react').ReactNode} ReactNode */ - -/** - * Underlay is a bit like a Popover, but is inline so only requires half the code. - * - * @param {Object} props - * @param {string} props.clientId The client id of the block being interacted with. - * @param {string} props.className A classname to add to the grid underlay. - * @param {ReactNode} props.children Child elements. - */ -export default function Underlay( { clientId, className, children } ) { - const [ underlayStyle, setUnderlayStyle ] = useState( { display: 'none' } ); - const rootClientId = useSelect( - ( select ) => - select( blockEditorStore ).getBlockRootClientId( clientId ), - [ clientId ] - ); - const rootElement = useBlockElement( rootClientId ); - const gridElement = useBlockElement( clientId ); - - useLayoutEffect( () => { - if ( ! gridElement || ! rootElement ) { - return; - } - - const { ownerDocument } = gridElement; - const { defaultView } = ownerDocument; - - const update = () => { - const rootRect = rootElement.getBoundingClientRect(); - const gridRect = gridElement.getBoundingClientRect(); - - setUnderlayStyle( { - position: 'absolute', - left: Math.floor( gridRect.left - rootRect.left ), - top: Math.floor( gridRect.top - rootRect.top ), - width: Math.floor( gridRect.width ), - height: Math.floor( gridRect.height ), - margin: 0, - padding: getComputedCSS( gridElement, 'padding' ), - zIndex: 0, - } ); - }; - - // Observe any resizes of both the layout and focused elements. - const resizeObserver = defaultView.ResizeObserver - ? new defaultView.ResizeObserver( update ) - : undefined; - const mutationObserver = defaultView.MutationObserver - ? new defaultView.MutationObserver( update ) - : undefined; - - // Monitor grid and parent block resizing. - resizeObserver?.observe( gridElement ); - resizeObserver?.observe( rootElement ); - - // Monitor block moving. - mutationObserver?.observe( gridElement, { attributes: true } ); - update(); - - return () => { - resizeObserver?.disconnect(); - mutationObserver?.disconnect(); - }; - }, [ gridElement, rootElement ] ); - - return ( -
- { children } -
- ); -} diff --git a/packages/block-editor/src/components/grid/grid-visualizer.js b/packages/block-editor/src/components/grid/grid-visualizer.js index 78e834513dbe5..6296b5280e7f5 100644 --- a/packages/block-editor/src/components/grid/grid-visualizer.js +++ b/packages/block-editor/src/components/grid/grid-visualizer.js @@ -13,8 +13,8 @@ import { __experimentalUseDropZone as useDropZone } from '@wordpress/compose'; /** * Internal dependencies */ -import GridUnderlay from './grid-underlay'; import { useBlockElement } from '../block-list/use-block-props/use-block-refs'; +import BlockPopoverCover from '../block-popover/cover'; import { range, GridRect, getGridInfo } from './utils'; import { store as blockEditorStore } from '../../store'; import { useGetNumberOfBlocksBeforeCell } from './use-get-number-of-blocks-before-cell'; @@ -84,7 +84,8 @@ const GridVisualizerGrid = forwardRef( }, [] ); return ( - - + ); } ); diff --git a/packages/block-editor/src/components/grid/utils.js b/packages/block-editor/src/components/grid/utils.js index 40c08896bb839..117c8f92e9ba0 100644 --- a/packages/block-editor/src/components/grid/utils.js +++ b/packages/block-editor/src/components/grid/utils.js @@ -173,6 +173,7 @@ export function getGridInfo( gridElement ) { gridTemplateRows, gap: getComputedCSS( gridElement, 'gap' ), display: 'grid', + padding: getComputedCSS( gridElement, 'padding' ), }, }; } From 6c3b96a078d38d7a044f25964296abf446419775 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Thu, 8 Aug 2024 16:18:19 +0800 Subject: [PATCH 09/25] Allow margin reset on inline popover via inline styles --- .../block-editor/src/components/grid/grid-visualizer.js | 1 + packages/components/src/popover/index.tsx | 7 ++++++- packages/components/src/popover/types.ts | 7 +++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/grid/grid-visualizer.js b/packages/block-editor/src/components/grid/grid-visualizer.js index 6296b5280e7f5..25c274d39d466 100644 --- a/packages/block-editor/src/components/grid/grid-visualizer.js +++ b/packages/block-editor/src/components/grid/grid-visualizer.js @@ -90,6 +90,7 @@ const GridVisualizerGrid = forwardRef( 'is-dropping-allowed': isDroppingAllowed, } ) } clientId={ gridClientId } + contentStyle={ { margin: 0 } } >
= shouldAnimate ? { style: { + ...contentStyle, ...motionInlineStyles, ...style, }, @@ -378,7 +380,10 @@ const UnforwardedPopover = ( } : { animate: false, - style, + style: { + ...contentStyle, + ...style, + }, }; // When Floating UI has finished positioning and Framer Motion has finished animating diff --git a/packages/components/src/popover/types.ts b/packages/components/src/popover/types.ts index 427f4afb81bfb..c2ceb0450b73b 100644 --- a/packages/components/src/popover/types.ts +++ b/packages/components/src/popover/types.ts @@ -160,6 +160,13 @@ export type PopoverProps = { * @default false */ inline?: boolean; + /** + * Styles to apply to the main popover element. + * + * @default undefined + */ + contentStyle?: React.CSSProperties; + // Deprecated props /** * Prevent the popover from flipping and resizing when meeting the viewport From ca816ecda649035e60a669bd08bb41fade687a36 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Thu, 8 Aug 2024 16:25:56 +0800 Subject: [PATCH 10/25] Override popover default z index --- packages/block-editor/src/components/grid/grid-visualizer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/grid/grid-visualizer.js b/packages/block-editor/src/components/grid/grid-visualizer.js index 25c274d39d466..a230635e11e14 100644 --- a/packages/block-editor/src/components/grid/grid-visualizer.js +++ b/packages/block-editor/src/components/grid/grid-visualizer.js @@ -90,7 +90,7 @@ const GridVisualizerGrid = forwardRef( 'is-dropping-allowed': isDroppingAllowed, } ) } clientId={ gridClientId } - contentStyle={ { margin: 0 } } + contentStyle={ { margin: 0, zIndex: 0 } } >
Date: Thu, 8 Aug 2024 16:47:27 +0800 Subject: [PATCH 11/25] Render two "grid visualizers", one under the block and one over-the one over has all the interactive elements --- .../src/components/grid/grid-visualizer.js | 93 ++++++++++++------- 1 file changed, 58 insertions(+), 35 deletions(-) diff --git a/packages/block-editor/src/components/grid/grid-visualizer.js b/packages/block-editor/src/components/grid/grid-visualizer.js index a230635e11e14..680b7c1e57950 100644 --- a/packages/block-editor/src/components/grid/grid-visualizer.js +++ b/packages/block-editor/src/components/grid/grid-visualizer.js @@ -84,39 +84,57 @@ const GridVisualizerGrid = forwardRef( }, [] ); return ( - -
+ - { isManualGrid ? ( - - ) : ( - Array.from( { length: gridInfo.numItems }, ( _, i ) => ( - + { Array.from( + { length: gridInfo.numItems }, + ( _, i ) => ( + + ) + ) } +
+
+ { isManualGrid && ( + +
+ - ) ) - ) } -
-
+
+ + ) } + ); } ); -function ManualGridVisualizer( { gridClientId, gridInfo } ) { +function InteractiveManualGrid( { gridClientId, gridInfo } ) { const [ highlightedRect, setHighlightedRect ] = useState( null ); const gridItems = useSelect( @@ -154,10 +172,11 @@ function ManualGridVisualizer( { gridClientId, gridInfo } ) { ); const isHighlighted = highlightedRect?.contains( column, row ) ?? false; + return ( { isCellOccupied ? ( @@ -183,19 +202,23 @@ function ManualGridVisualizer( { gridClientId, gridInfo } ) { ); } -function GridVisualizerCell( { color, children, className } ) { +function GridVisualizerCell( { color, children, className, invisible } ) { + const style = invisible + ? undefined + : { + boxShadow: `inset 0 0 0 1px color-mix(in srgb, ${ color } 20%, #0000)`, + color, + background: 'cornflowerblue', + opacity: 0.1, + }; + return (
{ children }
From 8ff3a2269763289ca4b9a6b1ce3c4476edb09d0b Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Thu, 8 Aug 2024 16:53:41 +0800 Subject: [PATCH 12/25] Revert change to root block list --- packages/block-editor/src/components/block-list/index.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/block-editor/src/components/block-list/index.js b/packages/block-editor/src/components/block-list/index.js index b7575d760702e..37dba80511d92 100644 --- a/packages/block-editor/src/components/block-list/index.js +++ b/packages/block-editor/src/components/block-list/index.js @@ -40,7 +40,6 @@ import { } from '../block-edit/context'; import { useTypingObserver } from '../observe-typing'; import { unlock } from '../../lock-unlock'; -import { useBlockRefProvider } from './use-block-props/use-block-refs'; export const IntersectionObserver = createContext(); const pendingBlockVisibilityUpdatesPerRegistry = new WeakMap(); @@ -111,7 +110,6 @@ function Root( { className, ...settings } ) { useBlockSelectionClearer(), useInBetweenInserter(), useTypingObserver(), - useBlockRefProvider( '' ), ] ), className: clsx( 'is-root-container', className, { 'is-outline-mode': isOutlineMode, From 03c068e2321900370b0e85351111e54eb528406f Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Fri, 9 Aug 2024 11:14:24 +0800 Subject: [PATCH 13/25] Update grid styles --- .../src/components/grid/grid-visualizer.js | 36 +++++++++++++------ .../src/components/grid/style.scss | 4 --- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/packages/block-editor/src/components/grid/grid-visualizer.js b/packages/block-editor/src/components/grid/grid-visualizer.js index 680b7c1e57950..bbb73b3065269 100644 --- a/packages/block-editor/src/components/grid/grid-visualizer.js +++ b/packages/block-editor/src/components/grid/grid-visualizer.js @@ -104,6 +104,7 @@ const GridVisualizerGrid = forwardRef( ) ) } @@ -175,7 +176,6 @@ function InteractiveManualGrid( { gridClientId, gridInfo } ) { return ( @@ -202,15 +202,31 @@ function InteractiveManualGrid( { gridClientId, gridInfo } ) { ); } -function GridVisualizerCell( { color, children, className, invisible } ) { - const style = invisible - ? undefined - : { - boxShadow: `inset 0 0 0 1px color-mix(in srgb, ${ color } 20%, #0000)`, - color, - background: 'cornflowerblue', - opacity: 0.1, - }; +function GridVisualizerCell( { + color, + children, + className, + invisible, + isManualGrid, +} ) { + let style; + + if ( ! invisible ) { + style = isManualGrid + ? { + backgroundColor: `rgba(var(--wp-admin-theme-color--rgb), 0.2)`, + border: `1px dashed rgb(var(--wp-admin-theme-color--rgb))`, + borderRadius: '2px', + color, + opacity: 0.2, + } + : { + border: `1px dashed ${ color }`, + borderRadius: '2px', + color, + opacity: 0.2, + }; + } return (
Date: Fri, 9 Aug 2024 12:06:29 +0800 Subject: [PATCH 14/25] Update appender styles --- .../block-editor/src/components/grid/grid-visualizer.js | 5 +++-- packages/block-editor/src/components/grid/style.scss | 8 ++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/block-editor/src/components/grid/grid-visualizer.js b/packages/block-editor/src/components/grid/grid-visualizer.js index bbb73b3065269..644692a2e82f5 100644 --- a/packages/block-editor/src/components/grid/grid-visualizer.js +++ b/packages/block-editor/src/components/grid/grid-visualizer.js @@ -178,6 +178,7 @@ function InteractiveManualGrid( { gridClientId, gridInfo } ) { { isCellOccupied ? ( Date: Fri, 9 Aug 2024 12:23:52 +0800 Subject: [PATCH 15/25] Hide drop zone until active --- packages/block-editor/src/components/grid/style.scss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/block-editor/src/components/grid/style.scss b/packages/block-editor/src/components/grid/style.scss index 4d08934744afe..a8f9fa797b27d 100644 --- a/packages/block-editor/src/components/grid/style.scss +++ b/packages/block-editor/src/components/grid/style.scss @@ -44,10 +44,15 @@ } + .block-editor-grid-visualizer__drop-zone { + opacity: 0; + } + &.is-highlighted { .block-editor-inserter, .block-editor-grid-visualizer__drop-zone { background: var(--wp-admin-theme-color); + opacity: 0.4; } } From 43865085591f3aca4292e3fec2ddf11eabffed33 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Fri, 9 Aug 2024 15:45:01 +0800 Subject: [PATCH 16/25] Improve highlight style --- packages/block-editor/src/components/grid/style.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/grid/style.scss b/packages/block-editor/src/components/grid/style.scss index a8f9fa797b27d..4e3c18904e2da 100644 --- a/packages/block-editor/src/components/grid/style.scss +++ b/packages/block-editor/src/components/grid/style.scss @@ -51,8 +51,8 @@ &.is-highlighted { .block-editor-inserter, .block-editor-grid-visualizer__drop-zone { - background: var(--wp-admin-theme-color); - opacity: 0.4; + background: rgba(var(--wp-admin-theme-color--rgb), 0.25); + border: 1px solid var(--wp-admin-theme-color); } } From 37c4203ab69ec21c003e5a168a45add492884a29 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Fri, 9 Aug 2024 16:34:19 +0800 Subject: [PATCH 17/25] Refactor into separate GridPopunder / GridPopover components --- .../src/components/grid/grid-visualizer.js | 280 +++++++++--------- 1 file changed, 148 insertions(+), 132 deletions(-) diff --git a/packages/block-editor/src/components/grid/grid-visualizer.js b/packages/block-editor/src/components/grid/grid-visualizer.js index 644692a2e82f5..cf04cf7f41d29 100644 --- a/packages/block-editor/src/components/grid/grid-visualizer.js +++ b/packages/block-editor/src/components/grid/grid-visualizer.js @@ -50,7 +50,6 @@ const GridVisualizerGrid = forwardRef( const [ gridInfo, setGridInfo ] = useState( () => getGridInfo( gridElement ) ); - const [ isDroppingAllowed, setIsDroppingAllowed ] = useState( false ); useEffect( () => { const observers = []; @@ -68,80 +67,112 @@ const GridVisualizerGrid = forwardRef( }; }, [ gridElement ] ); - useEffect( () => { - function onGlobalDrag() { - setIsDroppingAllowed( true ); - } - function onGlobalDragEnd() { - setIsDroppingAllowed( false ); - } - document.addEventListener( 'drag', onGlobalDrag ); - document.addEventListener( 'dragend', onGlobalDragEnd ); - return () => { - document.removeEventListener( 'drag', onGlobalDrag ); - document.removeEventListener( 'dragend', onGlobalDragEnd ); - }; - }, [] ); - return ( <> - -
- { Array.from( - { length: gridInfo.numItems }, - ( _, i ) => ( - - ) - ) } -
-
+ { isManualGrid && ( - -
- -
-
+ ) } ); } ); -function InteractiveManualGrid( { gridClientId, gridInfo } ) { +/** + * A popover component that renders inline under the grid block. + * + * This provides non-interactive elements of the grid visualization and + * renders under the block so that the background colors are not atop + * the block content. + * + * @param {Object} props + * @param {string} props.gridClientId + * @param {Object} props.gridInfo + * @param {boolean} props.isManualGrid + */ +function GridPopunder( { gridClientId, gridInfo, isManualGrid } ) { + const color = gridInfo.currentColor; + const cellStyle = isManualGrid + ? { + backgroundColor: `rgba(var(--wp-admin-theme-color--rgb), 0.2)`, + border: `1px dashed rgb(var(--wp-admin-theme-color--rgb))`, + borderRadius: '2px', + color, + opacity: 0.2, + } + : { + border: `1px dashed ${ color }`, + borderRadius: '2px', + color, + opacity: 0.2, + }; + + return ( + +
+ { Array.from( { length: gridInfo.numItems }, ( _, i ) => ( +
+ ) ) } +
+
+ ); +} + +/** + * A popover component that renders in a slot over the grid block. + * + * This provides interactive elements of the grid visualization — + * block inserters and drop zones. + * + * @param {Object} props + * @param {string} props.gridClientId + * @param {Object} props.gridInfo + */ +const GridPopover = forwardRef( ( { gridClientId, gridInfo }, ref ) => { + const [ isDroppingAllowed, setIsDroppingAllowed ] = useState( false ); const [ highlightedRect, setHighlightedRect ] = useState( null ); const gridItems = useSelect( ( select ) => select( blockEditorStore ).getBlocks( gridClientId ), [ gridClientId ] ); + + useEffect( () => { + function onGlobalDrag() { + setIsDroppingAllowed( true ); + } + function onGlobalDragEnd() { + setIsDroppingAllowed( false ); + } + document.addEventListener( 'drag', onGlobalDrag ); + document.addEventListener( 'dragend', onGlobalDragEnd ); + return () => { + document.removeEventListener( 'drag', onGlobalDrag ); + document.removeEventListener( 'dragend', onGlobalDragEnd ); + }; + }, [] ); + const occupiedRects = useMemo( () => { const rects = []; for ( const block of gridItems ) { @@ -166,81 +197,66 @@ function InteractiveManualGrid( { gridClientId, gridInfo } ) { return rects; }, [ gridItems ] ); - return range( 1, gridInfo.numRows ).map( ( row ) => - range( 1, gridInfo.numColumns ).map( ( column ) => { - const isCellOccupied = occupiedRects.some( ( rect ) => - rect.contains( column, row ) - ); - const isHighlighted = - highlightedRect?.contains( column, row ) ?? false; - - return ( - - { isCellOccupied ? ( - - ) : ( - - ) } - - ); - } ) - ); -} - -function GridVisualizerCell( { - color, - children, - className, - isInvisible, - isManualGrid, -} ) { - let style; - - if ( ! isInvisible ) { - style = isManualGrid - ? { - backgroundColor: `rgba(var(--wp-admin-theme-color--rgb), 0.2)`, - border: `1px dashed rgb(var(--wp-admin-theme-color--rgb))`, - borderRadius: '2px', - color, - opacity: 0.2, - } - : { - border: `1px dashed ${ color }`, - borderRadius: '2px', - color, - opacity: 0.2, - }; - } - return ( -
- { children } -
+
+ { range( 1, gridInfo.numRows ).map( ( row ) => + range( 1, gridInfo.numColumns ).map( ( column ) => { + const isCellOccupied = occupiedRects.some( ( rect ) => + rect.contains( column, row ) + ); + const isHighlighted = + highlightedRect?.contains( column, row ) ?? false; + + return ( +
+ { isCellOccupied ? ( + + ) : ( + + ) } +
+ ); + } ) + ) } +
+ ); -} +} ); function useGridVisualizerDropZone( column, From 497eb0f246ea13c69c7283da9b11a81fd968a54c Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Fri, 9 Aug 2024 16:54:27 +0800 Subject: [PATCH 18/25] Fix resizer bounds --- .../block-editor/src/hooks/grid-visualizer.js | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/block-editor/src/hooks/grid-visualizer.js b/packages/block-editor/src/hooks/grid-visualizer.js index 1b06cbbd7d3d0..44cc28284539f 100644 --- a/packages/block-editor/src/hooks/grid-visualizer.js +++ b/packages/block-editor/src/hooks/grid-visualizer.js @@ -4,7 +4,7 @@ import { createHigherOrderComponent } from '@wordpress/compose'; import { addFilter } from '@wordpress/hooks'; import { useSelect } from '@wordpress/data'; -import { createContext, useState } from '@wordpress/element'; +import { createContext, forwardRef, useState } from '@wordpress/element'; /** * Internal dependencies @@ -18,7 +18,7 @@ function GridLayoutSync( props ) { useGridLayoutSync( props ); } -function GridTools( { clientId, layout } ) { +const GridTools = forwardRef( ( { clientId, layout }, ref ) => { const { hasSelection, isDragging } = useSelect( ( select ) => { const { isBlockSelected, hasSelectedInnerBlock, isDraggingBlocks } = select( blockEditorStore ); @@ -31,37 +31,38 @@ function GridTools( { clientId, layout } ) { }; } ); - // Use useState() instead of useRef() so that GridItemResizer updates when ref is set. - const [ resizerBounds, setResizerBounds ] = useState(); - return ( - + <> { ( hasSelection || isDragging ) && ( ) } - + ); -} +} ); const addGridVisualizerToBlockEdit = createHigherOrderComponent( ( BlockEdit ) => ( props ) => { + // Use useState() instead of useRef() so that GridItemResizer updates when ref is set. + const [ resizerBounds, setResizerBounds ] = useState(); + if ( props.attributes.layout?.type !== 'grid' ) { return ; } return ( - <> + - + ); }, 'addGridVisualizerToBlockEdit' From 3b4e9ae1a3e99b4c74631d374b4ca4e86dc717b6 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Fri, 9 Aug 2024 17:01:21 +0800 Subject: [PATCH 19/25] Try for a smaller diff --- .../src/components/grid/grid-visualizer.js | 106 +++++++++--------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/packages/block-editor/src/components/grid/grid-visualizer.js b/packages/block-editor/src/components/grid/grid-visualizer.js index cf04cf7f41d29..08189809672de 100644 --- a/packages/block-editor/src/components/grid/grid-visualizer.js +++ b/packages/block-editor/src/components/grid/grid-visualizer.js @@ -86,59 +86,6 @@ const GridVisualizerGrid = forwardRef( } ); -/** - * A popover component that renders inline under the grid block. - * - * This provides non-interactive elements of the grid visualization and - * renders under the block so that the background colors are not atop - * the block content. - * - * @param {Object} props - * @param {string} props.gridClientId - * @param {Object} props.gridInfo - * @param {boolean} props.isManualGrid - */ -function GridPopunder( { gridClientId, gridInfo, isManualGrid } ) { - const color = gridInfo.currentColor; - const cellStyle = isManualGrid - ? { - backgroundColor: `rgba(var(--wp-admin-theme-color--rgb), 0.2)`, - border: `1px dashed rgb(var(--wp-admin-theme-color--rgb))`, - borderRadius: '2px', - color, - opacity: 0.2, - } - : { - border: `1px dashed ${ color }`, - borderRadius: '2px', - color, - opacity: 0.2, - }; - - return ( - -
- { Array.from( { length: gridInfo.numItems }, ( _, i ) => ( -
- ) ) } -
-
- ); -} - /** * A popover component that renders in a slot over the grid block. * @@ -258,6 +205,59 @@ const GridPopover = forwardRef( ( { gridClientId, gridInfo }, ref ) => { ); } ); +/** + * A popover component that renders inline under the grid block. + * + * This provides non-interactive elements of the grid visualization and + * renders under the block so that the background colors are not atop + * the block content. + * + * @param {Object} props + * @param {string} props.gridClientId + * @param {Object} props.gridInfo + * @param {boolean} props.isManualGrid + */ +function GridPopunder( { gridClientId, gridInfo, isManualGrid } ) { + const color = gridInfo.currentColor; + const cellStyle = isManualGrid + ? { + backgroundColor: `rgba(var(--wp-admin-theme-color--rgb), 0.2)`, + border: `1px dashed rgb(var(--wp-admin-theme-color--rgb))`, + borderRadius: '2px', + color, + opacity: 0.2, + } + : { + border: `1px dashed ${ color }`, + borderRadius: '2px', + color, + opacity: 0.2, + }; + + return ( + +
+ { Array.from( { length: gridInfo.numItems }, ( _, i ) => ( +
+ ) ) } +
+
+ ); +} + function useGridVisualizerDropZone( column, row, From 98cb5de0752b9818b4b9383524bf57a9c30f46df Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Mon, 12 Aug 2024 15:40:06 +1000 Subject: [PATCH 20/25] Rename GridVisualizerGrid, move occupiedRects --- .../src/components/grid/grid-visualizer.js | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/block-editor/src/components/grid/grid-visualizer.js b/packages/block-editor/src/components/grid/grid-visualizer.js index 08189809672de..b966a4614a80a 100644 --- a/packages/block-editor/src/components/grid/grid-visualizer.js +++ b/packages/block-editor/src/components/grid/grid-visualizer.js @@ -36,7 +36,7 @@ export function GridVisualizer( { clientId, contentRef, parentLayout } ) { parentLayout?.isManualPlacement && window.__experimentalEnableGridInteractivity; return ( - { const [ gridInfo, setGridInfo ] = useState( () => getGridInfo( gridElement ) @@ -105,21 +105,6 @@ const GridPopover = forwardRef( ( { gridClientId, gridInfo }, ref ) => { [ gridClientId ] ); - useEffect( () => { - function onGlobalDrag() { - setIsDroppingAllowed( true ); - } - function onGlobalDragEnd() { - setIsDroppingAllowed( false ); - } - document.addEventListener( 'drag', onGlobalDrag ); - document.addEventListener( 'dragend', onGlobalDragEnd ); - return () => { - document.removeEventListener( 'drag', onGlobalDrag ); - document.removeEventListener( 'dragend', onGlobalDragEnd ); - }; - }, [] ); - const occupiedRects = useMemo( () => { const rects = []; for ( const block of gridItems ) { @@ -144,6 +129,21 @@ const GridPopover = forwardRef( ( { gridClientId, gridInfo }, ref ) => { return rects; }, [ gridItems ] ); + useEffect( () => { + function onGlobalDrag() { + setIsDroppingAllowed( true ); + } + function onGlobalDragEnd() { + setIsDroppingAllowed( false ); + } + document.addEventListener( 'drag', onGlobalDrag ); + document.addEventListener( 'dragend', onGlobalDragEnd ); + return () => { + document.removeEventListener( 'drag', onGlobalDrag ); + document.removeEventListener( 'dragend', onGlobalDragEnd ); + }; + }, [] ); + return ( Date: Tue, 13 Aug 2024 17:10:54 +0800 Subject: [PATCH 21/25] Update grid css - Remove unused classnames - Update existing classnames to use BEM component convention --- packages/base-styles/_z-index.scss | 2 +- .../src/components/grid/grid-visualizer.js | 22 +++++-------------- .../src/components/grid/style.scss | 10 ++++----- 3 files changed, 11 insertions(+), 23 deletions(-) diff --git a/packages/base-styles/_z-index.scss b/packages/base-styles/_z-index.scss index 4d5f22e02fa7d..fa8e0a35ff86d 100644 --- a/packages/base-styles/_z-index.scss +++ b/packages/base-styles/_z-index.scss @@ -111,7 +111,7 @@ $z-layers: ( ".block-editor-block-popover": 31, // Below the block toolbar. - ".block-editor-grid-visualizer": 30, + ".block-editor-grid-visualizer-popover": 30, // Show snackbars above everything (similar to popovers) ".components-snackbar-list": 100000, diff --git a/packages/block-editor/src/components/grid/grid-visualizer.js b/packages/block-editor/src/components/grid/grid-visualizer.js index b966a4614a80a..e8533685ea2d3 100644 --- a/packages/block-editor/src/components/grid/grid-visualizer.js +++ b/packages/block-editor/src/components/grid/grid-visualizer.js @@ -147,16 +147,12 @@ const GridPopover = forwardRef( ( { gridClientId, gridInfo }, ref ) => { return ( -
+
{ range( 1, gridInfo.numRows ).map( ( row ) => range( 1, gridInfo.numColumns ).map( ( column ) => { const isCellOccupied = occupiedRects.some( ( rect ) => @@ -169,7 +165,7 @@ const GridPopover = forwardRef( ( { gridClientId, gridInfo }, ref ) => {
-
+
{ Array.from( { length: gridInfo.numItems }, ( _, i ) => ( -
+
) ) }
diff --git a/packages/block-editor/src/components/grid/style.scss b/packages/block-editor/src/components/grid/style.scss index 4e3c18904e2da..1f7ee6a2d6753 100644 --- a/packages/block-editor/src/components/grid/style.scss +++ b/packages/block-editor/src/components/grid/style.scss @@ -1,7 +1,7 @@ -.block-editor-grid-visualizer { +.block-editor-grid-visualizer-popover { // Specificity to override the z-index and pointer-events set by .components-popover. - &.block-editor-grid-visualizer.block-editor-grid-visualizer { - z-index: z-index(".block-editor-grid-visualizer"); + &.block-editor-grid-visualizer-popover.block-editor-grid-visualizer-popover { + z-index: z-index(".block-editor-grid-visualizer-popover"); .components-popover__content * { pointer-events: none; @@ -18,7 +18,7 @@ } } -.block-editor-grid-visualizer__cell { +.block-editor-grid-visualizer-popover__cell { display: grid; position: relative; @@ -82,7 +82,7 @@ .block-editor-grid-item-resizer { // Specificity to override the z-index and pointer-events set by .components-popover. &.block-editor-grid-item-resizer.block-editor-grid-item-resizer { - z-index: z-index(".block-editor-grid-visualizer"); + z-index: z-index(".block-editor-grid-visualizer-popover"); .components-popover__content * { pointer-events: none; From 613948875d301c053356dde04c32716c8f48c166 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Tue, 13 Aug 2024 17:20:36 +0800 Subject: [PATCH 22/25] Move GridResizerBoundsContext.Provider rendering to `GridTools` and make `GridTools` accept children. --- .../block-editor/src/hooks/grid-visualizer.js | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/packages/block-editor/src/hooks/grid-visualizer.js b/packages/block-editor/src/hooks/grid-visualizer.js index 44cc28284539f..c71ee410f1486 100644 --- a/packages/block-editor/src/hooks/grid-visualizer.js +++ b/packages/block-editor/src/hooks/grid-visualizer.js @@ -4,7 +4,7 @@ import { createHigherOrderComponent } from '@wordpress/compose'; import { addFilter } from '@wordpress/hooks'; import { useSelect } from '@wordpress/data'; -import { createContext, forwardRef, useState } from '@wordpress/element'; +import { createContext, useState } from '@wordpress/element'; /** * Internal dependencies @@ -18,7 +18,7 @@ function GridLayoutSync( props ) { useGridLayoutSync( props ); } -const GridTools = forwardRef( ( { clientId, layout }, ref ) => { +function GridTools( { clientId, layout, children } ) { const { hasSelection, isDragging } = useSelect( ( select ) => { const { isBlockSelected, hasSelectedInnerBlock, isDraggingBlocks } = select( blockEditorStore ); @@ -31,38 +31,37 @@ const GridTools = forwardRef( ( { clientId, layout }, ref ) => { }; } ); + // Use useState() instead of useRef() so that GridItemResizer updates when ref is set. + const [ resizerBounds, setResizerBounds ] = useState(); + return ( - <> + { ( hasSelection || isDragging ) && ( ) } - + { children } + ); -} ); +} const addGridVisualizerToBlockEdit = createHigherOrderComponent( ( BlockEdit ) => ( props ) => { - // Use useState() instead of useRef() so that GridItemResizer updates when ref is set. - const [ resizerBounds, setResizerBounds ] = useState(); - if ( props.attributes.layout?.type !== 'grid' ) { return ; } return ( - - + - + ); }, 'addGridVisualizerToBlockEdit' From e1343e7724a068d1d6a801dc4c287ddc6b73de90 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Tue, 13 Aug 2024 17:31:20 +0800 Subject: [PATCH 23/25] Use scss variables --- packages/block-editor/src/components/grid/style.scss | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/block-editor/src/components/grid/style.scss b/packages/block-editor/src/components/grid/style.scss index 1f7ee6a2d6753..a36573e0868f7 100644 --- a/packages/block-editor/src/components/grid/style.scss +++ b/packages/block-editor/src/components/grid/style.scss @@ -52,7 +52,7 @@ .block-editor-inserter, .block-editor-grid-visualizer__drop-zone { background: rgba(var(--wp-admin-theme-color--rgb), 0.25); - border: 1px solid var(--wp-admin-theme-color); + border: $border-width solid var(--wp-admin-theme-color); } } @@ -61,8 +61,8 @@ opacity: 1; box-shadow: none; background-color: rgba(var(--wp-admin-theme-color--rgb), 0.05); - border: 1px dashed; - border-radius: 2px; + border: $border-width dashed; + border-radius: $radius-small; color: var(--wp-admin-theme-color); } } @@ -122,7 +122,7 @@ content: ""; position: absolute; display: block; - border-radius: $radius-block-ui; + border-radius: $radius-small; height: $grid-unit-40; // Position the focus rectangle. From 4620f5e410a9a83a21ce79dee995d8447fbcb809 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Tue, 13 Aug 2024 17:43:26 +0800 Subject: [PATCH 24/25] Rename popover prop to `style` instead of `contentStyle` --- .../block-editor/src/components/grid/grid-visualizer.js | 2 +- packages/components/src/popover/index.tsx | 6 +++--- packages/components/src/popover/types.ts | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/block-editor/src/components/grid/grid-visualizer.js b/packages/block-editor/src/components/grid/grid-visualizer.js index e8533685ea2d3..3d32059924fa8 100644 --- a/packages/block-editor/src/components/grid/grid-visualizer.js +++ b/packages/block-editor/src/components/grid/grid-visualizer.js @@ -235,7 +235,7 @@ function GridPopunder( { gridClientId, gridInfo, isManualGrid } ) { inline clientId={ gridClientId } // Override layout margin and popover's zIndex. - contentStyle={ { margin: 0, zIndex: 0 } } + style={ { margin: 0, zIndex: 0 } } >
{ Array.from( { length: gridInfo.numItems }, ( _, i ) => ( diff --git a/packages/components/src/popover/index.tsx b/packages/components/src/popover/index.tsx index 144bbfb90f4d9..d80a0fac45b45 100644 --- a/packages/components/src/popover/index.tsx +++ b/packages/components/src/popover/index.tsx @@ -113,8 +113,8 @@ const UnforwardedPopover = ( WordPressComponentProps< PopoverProps, 'div', false >, // To avoid overlaps between the standard HTML attributes and the props // expected by `framer-motion`, omit all framer motion props from popover - // props (except for `animate` and `children`, which are re-defined in `PopoverProps`). - keyof Omit< MotionProps, 'animate' | 'children' > + // props (except for `animate`, `children` and `style`, which are re-defined in `PopoverProps`). + keyof Omit< MotionProps, 'animate' | 'children' | 'style' > >, forwardedRef: ForwardedRef< any > ) => { @@ -138,8 +138,8 @@ const UnforwardedPopover = ( resize = true, shift = false, inline = false, + style: contentStyle, variant, - contentStyle, // Deprecated props __unstableForcePosition, diff --git a/packages/components/src/popover/types.ts b/packages/components/src/popover/types.ts index c2ceb0450b73b..b862d1e5d935b 100644 --- a/packages/components/src/popover/types.ts +++ b/packages/components/src/popover/types.ts @@ -160,12 +160,13 @@ export type PopoverProps = { * @default false */ inline?: boolean; + /** * Styles to apply to the main popover element. * * @default undefined */ - contentStyle?: React.CSSProperties; + style?: React.CSSProperties; // Deprecated props /** From f73ca9f1fc1a1d517a900fe7c05bf5f117113aec Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Tue, 13 Aug 2024 18:08:37 +0800 Subject: [PATCH 25/25] Fix: Resizer bounds not working for auto grids --- .../src/components/grid/grid-visualizer.js | 164 +++++++++--------- 1 file changed, 85 insertions(+), 79 deletions(-) diff --git a/packages/block-editor/src/components/grid/grid-visualizer.js b/packages/block-editor/src/components/grid/grid-visualizer.js index 3d32059924fa8..a785fac1ee714 100644 --- a/packages/block-editor/src/components/grid/grid-visualizer.js +++ b/packages/block-editor/src/components/grid/grid-visualizer.js @@ -74,13 +74,12 @@ const GridVisualizerUI = forwardRef( gridInfo={ gridInfo } isManualGrid={ isManualGrid } /> - { isManualGrid && ( - - ) } + ); } @@ -96,10 +95,48 @@ const GridVisualizerUI = forwardRef( * @param {string} props.gridClientId * @param {Object} props.gridInfo */ -const GridPopover = forwardRef( ( { gridClientId, gridInfo }, ref ) => { - const [ isDroppingAllowed, setIsDroppingAllowed ] = useState( false ); - const [ highlightedRect, setHighlightedRect ] = useState( null ); +const GridPopover = forwardRef( + ( { gridClientId, gridInfo, isManualGrid }, ref ) => { + const [ isDroppingAllowed, setIsDroppingAllowed ] = useState( false ); + useEffect( () => { + function onGlobalDrag() { + setIsDroppingAllowed( true ); + } + function onGlobalDragEnd() { + setIsDroppingAllowed( false ); + } + document.addEventListener( 'drag', onGlobalDrag ); + document.addEventListener( 'dragend', onGlobalDragEnd ); + return () => { + document.removeEventListener( 'drag', onGlobalDrag ); + document.removeEventListener( 'dragend', onGlobalDragEnd ); + }; + }, [] ); + + return ( + +
+ { isManualGrid && ( + + ) } +
+
+ ); + } +); + +function ManualGridPopoverItems( { gridClientId, gridInfo } ) { + const [ highlightedRect, setHighlightedRect ] = useState( null ); const gridItems = useSelect( ( select ) => select( blockEditorStore ).getBlocks( gridClientId ), [ gridClientId ] @@ -129,77 +166,46 @@ const GridPopover = forwardRef( ( { gridClientId, gridInfo }, ref ) => { return rects; }, [ gridItems ] ); - useEffect( () => { - function onGlobalDrag() { - setIsDroppingAllowed( true ); - } - function onGlobalDragEnd() { - setIsDroppingAllowed( false ); - } - document.addEventListener( 'drag', onGlobalDrag ); - document.addEventListener( 'dragend', onGlobalDragEnd ); - return () => { - document.removeEventListener( 'drag', onGlobalDrag ); - document.removeEventListener( 'dragend', onGlobalDragEnd ); - }; - }, [] ); - - return ( - -
- { range( 1, gridInfo.numRows ).map( ( row ) => - range( 1, gridInfo.numColumns ).map( ( column ) => { - const isCellOccupied = occupiedRects.some( ( rect ) => - rect.contains( column, row ) - ); - const isHighlighted = - highlightedRect?.contains( column, row ) ?? false; + return range( 1, gridInfo.numRows ).map( ( row ) => + range( 1, gridInfo.numColumns ).map( ( column ) => { + const isCellOccupied = occupiedRects.some( ( rect ) => + rect.contains( column, row ) + ); + const isHighlighted = + highlightedRect?.contains( column, row ) ?? false; - return ( -
- { isCellOccupied ? ( - - ) : ( - - ) } -
- ); - } ) - ) } -
-
+ return ( +
+ { isCellOccupied ? ( + + ) : ( + + ) } +
+ ); + } ) ); -} ); +} /** * A popover component that renders inline under the grid block.