@@ -160,108 +160,154 @@ export function checkColumnPopupPosition(gridElement, selector) {
160
160
161
161
export function enableColumnResizing ( gridElement ) {
162
162
const columns = [ ] ;
163
- let min = 75 ;
164
- let headerBeingResized ;
165
- let resizeHandle ;
166
-
167
163
const headers = gridElement . querySelectorAll ( '.column-header.resizable' ) ;
168
164
169
165
if ( headers . length === 0 ) {
170
166
return ;
171
167
}
172
168
173
- headers . forEach ( header => {
169
+ const isRTL = getComputedStyle ( gridElement ) . direction === 'rtl' ;
170
+ const isGrid = gridElement . classList . contains ( 'grid' )
171
+
172
+ let tableHeight = gridElement . offsetHeight ;
173
+ // rows have not been loaded yet, so we need to calculate the height
174
+ if ( tableHeight < 70 ) {
175
+ // by getting the aria rowcount attribute
176
+ const rowCount = gridElement . getAttribute ( 'aria-rowcount' ) ;
177
+ if ( rowCount ) {
178
+ const rowHeight = gridElement . querySelector ( 'thead tr th' ) . offsetHeight ;
179
+ // and multiply by the itemsize (== height of the header cells)
180
+ tableHeight = rowCount * rowHeight ;
181
+ }
182
+ }
183
+
184
+ headers . forEach ( ( header ) => {
174
185
columns . push ( {
175
186
header,
176
- size : `minmax( ${ minWidth } px,auto) ` ,
187
+ size : `${ header . clientWidth } px` ,
177
188
} ) ;
178
189
179
- const onPointerMove = ( e ) => requestAnimationFrame ( ( ) => {
180
- if ( ! headerBeingResized ) {
181
- return ;
182
- }
183
- gridElement . style . tableLayout = "fixed" ;
190
+ const div = createDiv ( tableHeight , isRTL ) ;
191
+ header . appendChild ( div ) ;
192
+ header . style . position = 'relative' ;
193
+ setListeners ( div , isRTL ) ;
194
+ } ) ;
184
195
185
- const horizontalScrollOffset = document . documentElement . scrollLeft ;
186
- let width ;
196
+ let initialWidths ;
197
+ if ( gridElement . style . gridTemplateColumns ) {
198
+ initialWidths = gridElement . style . gridTemplateColumns ;
199
+ } else {
200
+ initialWidths = columns . map ( ( { size } ) => size ) . join ( ' ' ) ;
187
201
188
- if ( document . body . dir === '' || document . body . dir === 'ltr' ) {
189
- width = ( horizontalScrollOffset + e . clientX ) - headerBeingResized . getClientRects ( ) [ 0 ] . x ;
190
- }
191
- else {
192
- width = headerBeingResized . getClientRects ( ) [ 0 ] . x + headerBeingResized . clientWidth - ( horizontalScrollOffset + e . clientX ) ;
193
- }
202
+ if ( isGrid ) {
203
+ gridElement . style . gridTemplateColumns = initialWidths ;
204
+ }
205
+ }
194
206
195
- const column = columns . find ( ( { header } ) => header === headerBeingResized ) ;
196
- column . size = Math . max ( minWidth , width ) + 'px' ;
207
+ const id = gridElement . id ;
208
+ grids . push ( {
209
+ id,
210
+ columns,
211
+ initialWidths,
212
+ } ) ;
197
213
198
- columns . forEach ( ( column ) => {
199
- if ( column . size . startsWith ( 'minmax' ) ) {
200
- column . size = parseInt ( column . header . clientWidth , 10 ) + 'px' ;
201
- }
202
- } ) ;
214
+ function setListeners ( div , isRTL ) {
215
+ let pageX , curCol , curColWidth ;
216
+
217
+ div . addEventListener ( 'pointerdown' , function ( e ) {
218
+ curCol = e . target . parentElement ;
219
+ pageX = e . pageX ;
220
+
221
+ const padding = paddingDiff ( curCol ) ;
203
222
204
- gridElement . style . gridTemplateColumns = columns
205
- . map ( ( { size } ) => size )
206
- . join ( ' ' ) ;
223
+ curColWidth = curCol . offsetWidth - padding ;
207
224
} ) ;
208
225
209
- const onPointerUp = ( e ) => {
226
+ div . addEventListener ( 'pointerover' , function ( e ) {
227
+ e . target . style . borderInlineEnd = '2px solid var(--neutral-stroke-focus)' ;
228
+ } ) ;
210
229
211
- window . removeEventListener ( 'pointermove' , onPointerMove ) ;
212
- window . removeEventListener ( 'pointerup' , onPointerUp ) ;
213
- window . removeEventListener ( 'pointercancel' , onPointerUp ) ;
214
- window . removeEventListener ( 'pointerleave' , onPointerUp ) ;
230
+ div . addEventListener ( 'pointerup' , removeBorder ) ;
231
+ div . addEventListener ( 'pointercancel' , removeBorder ) ;
232
+ div . addEventListener ( 'pointerleave' , removeBorder ) ;
215
233
216
- headerBeingResized . classList . remove ( 'header-being-resized' ) ;
217
- headerBeingResized = null ;
234
+ document . addEventListener ( 'pointermove' , ( e ) =>
235
+ requestAnimationFrame ( ( ) => {
236
+ gridElement . style . tableLayout = 'fixed' ;
218
237
219
- if ( e . target . hasPointerCapture ( e . pointerId ) ) {
220
- e . target . releasePointerCapture ( e . pointerId ) ;
221
- }
222
- } ;
238
+ if ( curCol ) {
239
+ const diffX = isRTL ? pageX - e . pageX : e . pageX - pageX ;
240
+ const column = columns . find ( ( { header } ) => header === curCol ) ;
223
241
224
- const initResize = ( { target, pointerId } ) => {
225
- headerBeingResized = target . parentNode ;
226
- headerBeingResized . classList . add ( 'header-being-resized' ) ;
242
+ column . size = parseInt ( Math . max ( minWidth , curColWidth + diffX ) , 10 ) + 'px' ;
227
243
244
+ columns . forEach ( ( col ) => {
245
+ if ( col . size . startsWith ( 'minmax' ) ) {
246
+ col . size = parseInt ( col . header . clientWidth , 10 ) + 'px' ;
247
+ }
248
+ } ) ;
228
249
229
- window . addEventListener ( 'pointermove' , onPointerMove ) ;
230
- window . addEventListener ( 'pointerup' , onPointerUp ) ;
231
- window . addEventListener ( 'pointercancel' , onPointerUp ) ;
232
- window . addEventListener ( 'pointerleave' , onPointerUp ) ;
250
+ if ( isGrid ) {
251
+ gridElement . style . gridTemplateColumns = columns
252
+ . map ( ( { size } ) => size )
253
+ . join ( ' ' ) ;
254
+ }
255
+ else {
256
+ curCol . style . width = column . size ;
257
+ }
258
+ }
259
+ } )
260
+ ) ;
233
261
234
- if ( resizeHandle ) {
235
- resizeHandle . setPointerCapture ( pointerId ) ;
236
- }
237
- } ;
262
+ document . addEventListener ( 'pointerup' , function ( ) {
263
+ curCol = undefined ;
264
+ curColWidth = undefined ;
265
+ pageX = undefined ;
266
+ } ) ;
267
+ }
238
268
239
- header . querySelector ( '.resize-handle' ) . addEventListener ( 'pointerdown' , initResize ) ;
269
+ function createDiv ( height , isRTL ) {
270
+ const div = document . createElement ( 'div' ) ;
271
+ div . style . top = '5px' ;
272
+ div . style . position = 'absolute' ;
273
+ div . style . cursor = 'col-resize' ;
274
+ div . style . userSelect = 'none' ;
275
+ div . style . height = height + 'px' ;
276
+ div . style . width = '5px' ;
277
+
278
+ if ( isRTL ) {
279
+ div . style . left = '0px' ;
280
+ div . style . right = 'unset' ;
281
+ } else {
282
+ div . style . left = 'unset' ;
283
+ div . style . right = '0px' ;
284
+ }
285
+ return div ;
286
+ }
240
287
241
- } ) ;
288
+ function paddingDiff ( col ) {
289
+ if ( getStyleVal ( col , 'box-sizing' ) === 'border-box' ) {
290
+ return 0 ;
291
+ }
242
292
243
- let initialWidths ;
244
- if ( gridElement . style . gridTemplateColumns ) {
245
- initialWidths = gridElement . style . gridTemplateColumns ;
293
+ const padLeft = getStyleVal ( col , 'padding-left' ) ;
294
+ const padRight = getStyleVal ( col , 'padding-right' ) ;
295
+ return parseInt ( padLeft ) + parseInt ( padRight ) ;
246
296
}
247
- else {
248
- initialWidths = columns
249
- . map ( ( { header, size } ) => size )
250
- . join ( ' ' ) ;
251
297
252
- gridElement . style . gridTemplateColumns = initialWidths ;
298
+ function getStyleVal ( elm , css ) {
299
+ return window . getComputedStyle ( elm , null ) . getPropertyValue ( css ) ;
253
300
}
254
301
255
- let id = gridElement . id ;
256
- grids . push ( {
257
- id,
258
- columns,
259
- initialWidths
260
- } ) ;
302
+ function removeBorder ( e ) {
303
+ e . target . style . borderInlineEnd = '' ;
304
+ }
261
305
}
262
306
263
- export function resetColumnWidths ( gridElement ) {
264
307
308
+
309
+ export function resetColumnWidths ( gridElement ) {
310
+ const isGrid = gridElement . classList . contains ( 'grid' ) ;
265
311
const grid = grids . find ( ( { id } ) => id === gridElement . id ) ;
266
312
if ( ! grid ) {
267
313
return ;
@@ -270,11 +316,19 @@ export function resetColumnWidths(gridElement) {
270
316
const columnsWidths = grid . initialWidths . split ( ' ' ) ;
271
317
272
318
grid . columns . forEach ( ( column , index ) => {
273
- column . size = columnsWidths [ index ] ;
319
+ if ( isGrid ) {
320
+ column . size = columnsWidths [ index ] ;
321
+ } else {
322
+ column . header . style . width = columnsWidths [ index ] ;
323
+ }
274
324
} ) ;
275
325
276
- gridElement . style . gridTemplateColumns = grid . initialWidths ;
277
- gridElement . dispatchEvent ( new CustomEvent ( 'closecolumnresize' , { bubbles : true } ) ) ;
326
+ if ( isGrid ) {
327
+ gridElement . style . gridTemplateColumns = grid . initialWidths ;
328
+ }
329
+ gridElement . dispatchEvent (
330
+ new CustomEvent ( 'closecolumnresize' , { bubbles : true } )
331
+ ) ;
278
332
gridElement . focus ( ) ;
279
333
}
280
334
@@ -308,7 +362,7 @@ export function resizeColumnDiscrete(gridElement, column, change) {
308
362
}
309
363
else {
310
364
if ( column . size . startsWith ( 'minmax' ) ) {
311
- column . size = parseInt ( column . header . clientWidth , 10 ) + 'px' ;
365
+ column . size = parseInt ( column . header . clientWidth , 10 ) + 'px' ;
312
366
}
313
367
}
314
368
columns . push ( column . size ) ;
0 commit comments