Skip to content

Commit 3386d35

Browse files
noisysocksandrewserongtellthemachines
authored
Grid interactivity: Improve how grid resizer handles 0-width and 0-height cells (#61423)
* Grid interactivity: Improve how grid resizer handles 0-width and 0-height cells * Add doc comments Co-authored-by: noisysocks <[email protected]> Co-authored-by: andrewserong <[email protected]> Co-authored-by: tellthemachines <[email protected]>
1 parent 15b8049 commit 3386d35

File tree

1 file changed

+66
-30
lines changed

1 file changed

+66
-30
lines changed

packages/block-editor/src/components/grid-visualizer/grid-item-resizer.js

Lines changed: 66 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -45,54 +45,90 @@ export function GridItemResizer( { clientId, onChange } ) {
4545
const rowGap = parseFloat(
4646
getComputedCSS( gridElement, 'row-gap' )
4747
);
48-
const gridColumnLines = getGridLines(
48+
const gridColumnTracks = getGridTracks(
4949
getComputedCSS( gridElement, 'grid-template-columns' ),
5050
columnGap
5151
);
52-
const gridRowLines = getGridLines(
52+
const gridRowTracks = getGridTracks(
5353
getComputedCSS( gridElement, 'grid-template-rows' ),
5454
rowGap
5555
);
56-
const columnStart = getClosestLine(
57-
gridColumnLines,
58-
blockElement.offsetLeft
59-
);
60-
const rowStart = getClosestLine(
61-
gridRowLines,
62-
blockElement.offsetTop
63-
);
64-
const columnEnd = getClosestLine(
65-
gridColumnLines,
66-
blockElement.offsetLeft + boxElement.offsetWidth
67-
);
68-
const rowEnd = getClosestLine(
69-
gridRowLines,
70-
blockElement.offsetTop + boxElement.offsetHeight
71-
);
56+
const columnStart =
57+
getClosestTrack(
58+
gridColumnTracks,
59+
blockElement.offsetLeft
60+
) + 1;
61+
const rowStart =
62+
getClosestTrack(
63+
gridRowTracks,
64+
blockElement.offsetTop
65+
) + 1;
66+
const columnEnd =
67+
getClosestTrack(
68+
gridColumnTracks,
69+
blockElement.offsetLeft + boxElement.offsetWidth,
70+
'end'
71+
) + 1;
72+
const rowEnd =
73+
getClosestTrack(
74+
gridRowTracks,
75+
blockElement.offsetTop + boxElement.offsetHeight,
76+
'end'
77+
) + 1;
7278
onChange( {
73-
columnSpan: Math.max( columnEnd - columnStart, 1 ),
74-
rowSpan: Math.max( rowEnd - rowStart, 1 ),
79+
columnSpan: columnEnd - columnStart + 1,
80+
rowSpan: rowEnd - rowStart + 1,
7581
} );
7682
} }
7783
/>
7884
</BlockPopoverCover>
7985
);
8086
}
8187

82-
function getGridLines( template, gap ) {
83-
const lines = [ 0 ];
88+
/**
89+
* Given a grid-template-columns or grid-template-rows CSS property value, gets the start and end
90+
* position in pixels of each grid track.
91+
*
92+
* https://css-tricks.com/snippets/css/complete-guide-grid/#aa-grid-track
93+
*
94+
* @param {string} template The grid-template-columns or grid-template-rows CSS property value.
95+
* Only supports fixed sizes in pixels.
96+
* @param {number} gap The gap between grid tracks in pixels.
97+
*
98+
* @return {Array<{start: number, end: number}>} An array of objects with the start and end
99+
* position in pixels of each grid track.
100+
*/
101+
function getGridTracks( template, gap ) {
102+
const tracks = [];
84103
for ( const size of template.split( ' ' ) ) {
85-
const line = parseFloat( size );
86-
lines.push( lines[ lines.length - 1 ] + line + gap );
104+
const previousTrack = tracks[ tracks.length - 1 ];
105+
const start = previousTrack ? previousTrack.end + gap : 0;
106+
const end = start + parseFloat( size );
107+
tracks.push( { start, end } );
87108
}
88-
return lines;
109+
return tracks;
89110
}
90111

91-
function getClosestLine( lines, position ) {
92-
return lines.reduce(
93-
( closest, line, index ) =>
94-
Math.abs( line - position ) <
95-
Math.abs( lines[ closest ] - position )
112+
/**
113+
* Given an array of grid tracks and a position in pixels, gets the index of the closest track to
114+
* that position.
115+
*
116+
* https://css-tricks.com/snippets/css/complete-guide-grid/#aa-grid-track
117+
*
118+
* @param {Array<{start: number, end: number}>} tracks An array of objects with the start and end
119+
* position in pixels of each grid track.
120+
* @param {number} position The position in pixels.
121+
* @param {string} edge The edge of the track to compare the
122+
* position to. Either 'start' or 'end'.
123+
*
124+
* @return {number} The index of the closest track to the position. 0-based, unlike CSS grid which
125+
* is 1-based.
126+
*/
127+
function getClosestTrack( tracks, position, edge = 'start' ) {
128+
return tracks.reduce(
129+
( closest, track, index ) =>
130+
Math.abs( track[ edge ] - position ) <
131+
Math.abs( tracks[ closest ][ edge ] - position )
96132
? index
97133
: closest,
98134
0

0 commit comments

Comments
 (0)