@@ -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