Skip to content

Commit

Permalink
WIP: Avoid over-selecting in ManualGridVisualizer by setting occupied…
Browse files Browse the repository at this point in the history
…Rects in getGridInfo
  • Loading branch information
noisysocks committed Aug 9, 2024
1 parent b11bdc0 commit 1e19e46
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 98 deletions.
103 changes: 71 additions & 32 deletions packages/block-editor/src/components/grid/grid-visualizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import clsx from 'clsx';
/**
* WordPress dependencies
*/
import { useState, useEffect, forwardRef, useMemo } from '@wordpress/element';
import { useState, useEffect, forwardRef } from '@wordpress/element';
import { useSelect, useDispatch } from '@wordpress/data';
import { __experimentalUseDropZone as useDropZone } from '@wordpress/compose';

Expand All @@ -15,11 +15,79 @@ import { __experimentalUseDropZone as useDropZone } from '@wordpress/compose';
*/
import { useBlockElement } from '../block-list/use-block-props/use-block-refs';
import BlockPopoverCover from '../block-popover/cover';
import { range, GridRect, getGridInfo } from './utils';
import { GridRect, getComputedCSS } from './utils';
import { store as blockEditorStore } from '../../store';
import { useGetNumberOfBlocksBeforeCell } from './use-get-number-of-blocks-before-cell';
import ButtonBlockAppender from '../button-block-appender';

function range( start, length ) {
return Array.from( { length }, ( _, i ) => start + i );
}

function getGridInfo( gridElement ) {
const gridTemplateColumns = getComputedCSS(
gridElement,
'grid-template-columns'
);
const gridTemplateRows = getComputedCSS(
gridElement,
'grid-template-rows'
);
const numColumns = gridTemplateColumns.split( ' ' ).length;
const numRows = gridTemplateRows.split( ' ' ).length;
const numItems = numColumns * numRows;
const occupiedRects = Array.from( gridElement.children ).map(
( gridItemElement ) => {
const parseAndCheckNaN = ( value ) => {
const parsed = parseInt( value, 10 );
return isNaN( parsed ) ? undefined : parsed;
};
const parseSpan = ( value ) => {
if ( value.startsWith( 'span ' ) ) {
return parseAndCheckNaN( value.split( ' ' )[ 1 ] );
}
return parseAndCheckNaN( value );
};
const columnStart = parseAndCheckNaN(
getComputedCSS( gridItemElement, 'grid-column-start' )
);
const rowStart = parseAndCheckNaN(
getComputedCSS( gridItemElement, 'grid-row-start' )
);
const columnEnd = parseSpan(
getComputedCSS( gridItemElement, 'grid-column-end' )
);
const rowEnd = parseSpan(
getComputedCSS( gridItemElement, 'grid-row-end' )
);
return new GridRect( {
columnStart,
rowStart,
// clean this up... we should just pass span if it's a span
columnEnd:
columnEnd !== undefined
? columnStart + columnEnd - 1
: undefined,
rowEnd:
rowEnd !== undefined ? rowStart + rowEnd - 1 : undefined,
} );
}
);
return {
numColumns,
numRows,
numItems,
currentColor: getComputedCSS( gridElement, 'color' ),
style: {
gridTemplateColumns,
gridTemplateRows,
gap: getComputedCSS( gridElement, 'gap' ),
padding: getComputedCSS( gridElement, 'padding' ),
},
occupiedRects,
};
}

export function GridVisualizer( { clientId, contentRef, parentLayout } ) {
const isDistractionFree = useSelect(
( select ) =>
Expand Down Expand Up @@ -117,38 +185,9 @@ const GridVisualizerGrid = forwardRef(

function ManualGridVisualizer( { gridClientId, gridInfo } ) {
const [ highlightedRect, setHighlightedRect ] = useState( null );

const gridItems = useSelect(
( select ) => select( blockEditorStore ).getBlocks( gridClientId ),
[ gridClientId ]
);
const occupiedRects = useMemo( () => {
const rects = [];
for ( const block of gridItems ) {
const {
columnStart,
rowStart,
columnSpan = 1,
rowSpan = 1,
} = block.attributes.style?.layout || {};
if ( ! columnStart || ! rowStart ) {
continue;
}
rects.push(
new GridRect( {
columnStart,
rowStart,
columnSpan,
rowSpan,
} )
);
}
return rects;
}, [ gridItems ] );

return range( 1, gridInfo.numRows ).map( ( row ) =>
range( 1, gridInfo.numColumns ).map( ( column ) => {
const isCellOccupied = occupiedRects.some( ( rect ) =>
const isCellOccupied = gridInfo.occupiedRects.some( ( rect ) =>
rect.contains( column, row )
);
const isHighlighted =
Expand Down
66 changes: 0 additions & 66 deletions packages/block-editor/src/components/grid/utils.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
export function range( start, length ) {
return Array.from( { length }, ( _, i ) => start + i );
}

export class GridRect {
constructor( {
columnStart,
Expand Down Expand Up @@ -114,65 +110,3 @@ export function getClosestTrack( tracks, position, edge = 'start' ) {
0
);
}

export function getGridRect( gridElement, rect ) {
const columnGap = parseFloat( getComputedCSS( gridElement, 'column-gap' ) );
const rowGap = parseFloat( getComputedCSS( gridElement, 'row-gap' ) );
const gridColumnTracks = getGridTracks(
getComputedCSS( gridElement, 'grid-template-columns' ),
columnGap
);
const gridRowTracks = getGridTracks(
getComputedCSS( gridElement, 'grid-template-rows' ),
rowGap
);
const columnStart = getClosestTrack( gridColumnTracks, rect.left ) + 1;
const rowStart = getClosestTrack( gridRowTracks, rect.top ) + 1;
const columnEnd =
getClosestTrack( gridColumnTracks, rect.right, 'end' ) + 1;
const rowEnd = getClosestTrack( gridRowTracks, rect.bottom, 'end' ) + 1;
return new GridRect( {
columnStart,
columnEnd,
rowStart,
rowEnd,
} );
}

export function getGridItemRect( gridItemElement ) {
return getGridRect(
gridItemElement.parentElement,
new window.DOMRect(
gridItemElement.offsetLeft,
gridItemElement.offsetTop,
gridItemElement.offsetWidth,
gridItemElement.offsetHeight
)
);
}

export function getGridInfo( gridElement ) {
const gridTemplateColumns = getComputedCSS(
gridElement,
'grid-template-columns'
);
const gridTemplateRows = getComputedCSS(
gridElement,
'grid-template-rows'
);
const numColumns = gridTemplateColumns.split( ' ' ).length;
const numRows = gridTemplateRows.split( ' ' ).length;
const numItems = numColumns * numRows;
return {
numColumns,
numRows,
numItems,
currentColor: getComputedCSS( gridElement, 'color' ),
style: {
gridTemplateColumns,
gridTemplateRows,
gap: getComputedCSS( gridElement, 'gap' ),
padding: getComputedCSS( gridElement, 'padding' ),
},
};
}

0 comments on commit 1e19e46

Please sign in to comment.