@@ -71,11 +71,12 @@ export default class IgcTileComponent extends EventEmitterMixin<
7171 private _initialPointerX : number | null = null ;
7272 private _initialPointerY : number | null = null ;
7373 private _cachedStyles : {
74- ghostBackground ?: string ;
75- ghostBorder ?: string ;
76- ghostBorderRadius ?: string ;
77- ghostMinWidth ?: string ;
78- ghostMinHeight ?: string ;
74+ columnCount ?: number ;
75+ minWidth ?: number ;
76+ minHeight ?: number ;
77+ background ?: string ;
78+ border ?: string ;
79+ borderRadius ?: string ;
7980 } = { } ;
8081 private _context = new ContextProvider ( this , {
8182 context : tileContext ,
@@ -343,16 +344,22 @@ export default class IgcTileComponent extends EventEmitterMixin<
343344 }
344345
345346 private cacheStyles ( ) {
346- const computedStyle = window . getComputedStyle ( this ) ;
347+ //use util
348+ const computedStyle = getComputedStyle ( this ) ;
347349
348350 this . _cachedStyles = {
349- ghostBackground : computedStyle . getPropertyValue (
350- '--placeholder-background'
351+ columnCount : Number . parseFloat (
352+ computedStyle . getPropertyValue ( '--ig-column-count' )
353+ ) ,
354+ background : computedStyle . getPropertyValue ( '--placeholder-background' ) ,
355+ border : computedStyle . getPropertyValue ( '--ghost-border' ) ,
356+ borderRadius : computedStyle . getPropertyValue ( '--border-radius' ) ,
357+ minWidth : Number . parseFloat (
358+ computedStyle . getPropertyValue ( '--ig-min-col-width' )
359+ ) ,
360+ minHeight : Number . parseFloat (
361+ computedStyle . getPropertyValue ( '--ig-min-row-height' )
351362 ) ,
352- ghostBorder : computedStyle . getPropertyValue ( '--ghost-border' ) ,
353- ghostBorderRadius : computedStyle . getPropertyValue ( '--border-radius' ) ,
354- ghostMinWidth : computedStyle . getPropertyValue ( '--ig-min-col-width' ) ,
355- ghostMinHeight : computedStyle . getPropertyValue ( '--ig-min-row-height' ) ,
356363 } ;
357364 }
358365
@@ -362,8 +369,8 @@ export default class IgcTileComponent extends EventEmitterMixin<
362369 this . _initialPointerY = event . detail . event . clientY ;
363370
364371 if ( ghostElement ) {
365- ghostElement . style . minWidth = this . _cachedStyles . ghostMinWidth ! ;
366- ghostElement . style . minHeight = this . _cachedStyles . ghostMinHeight ! ;
372+ ghostElement . style . minWidth = ` ${ this . _cachedStyles . minWidth ! } px` ;
373+ ghostElement . style . minHeight = ` ${ this . _cachedStyles . minHeight ! } px` ;
367374 }
368375 }
369376
@@ -375,10 +382,70 @@ export default class IgcTileComponent extends EventEmitterMixin<
375382 if ( ghostElement ) {
376383 const deltaX = event . detail . event . clientX - this . _initialPointerX ! ;
377384 const deltaY = event . detail . event . clientY - this . _initialPointerY ! ;
385+ const minWidth = this . _cachedStyles . minWidth ! ;
386+ const minHeight = this . _cachedStyles . minHeight ! ;
387+ const columnGap = 10 ;
388+
389+ const snappedWidth = this . _calculateSnappedWidth (
390+ deltaX ,
391+ event . detail . state . initial . width ,
392+ minWidth ,
393+ columnGap
394+ ) ;
395+ const snappedHeight = this . _calculateSnappedHeight (
396+ deltaY ,
397+ event . detail . state . initial . height ,
398+ minHeight ,
399+ columnGap
400+ ) ;
401+
402+ ghostElement . width = snappedWidth ;
403+ ghostElement . height = snappedHeight ;
404+ }
405+ }
378406
379- ghostElement . width = event . detail . state . initial . width + deltaX ;
380- ghostElement . height = event . detail . state . initial . height + deltaY ;
407+ private _calculateSnappedWidth (
408+ deltaX : number ,
409+ initialWidth : number ,
410+ minWidth : number ,
411+ gap : number
412+ ) : number {
413+ const newSize = initialWidth + deltaX ;
414+ const wholeUnits = Math . floor ( newSize / ( minWidth + gap ) ) ;
415+ const fraction = newSize / ( minWidth + gap ) - wholeUnits ;
416+ const gapMultiplier =
417+ fraction > 0.5 ? wholeUnits : wholeUnits > 1 ? wholeUnits - 1 : 0 ;
418+
419+ return fraction > 0.5
420+ ? ( wholeUnits + 1 ) * minWidth + gapMultiplier * gap
421+ : wholeUnits * minWidth + gapMultiplier * gap ;
422+ }
423+
424+ private _calculateSnappedHeight (
425+ deltaY : number ,
426+ initialHeight : number ,
427+ minHeight : number ,
428+ rowGap : number
429+ ) : number {
430+ let snappedHeight = initialHeight ;
431+
432+ if ( deltaY > 0 ) {
433+ // For resizing down, add the gaps and the rows multiplied by min height to the initial tile height
434+ const wholeRows = Math . floor ( deltaY / minHeight ) ;
435+ const totalGaps = Math . max ( wholeRows - 1 , 0 ) * rowGap ;
436+ snappedHeight = initialHeight + wholeRows * minHeight + totalGaps ;
437+ } else if ( deltaY < 0 && initialHeight > minHeight ) {
438+ // For resizing up, subtract the gaps and the rows multiplied by min height from the initial tile height
439+ const extraHeight = Math . abs ( deltaY ) ;
440+ const wholeRows = Math . floor ( extraHeight / minHeight ) ;
441+ const totalGaps = Math . max ( wholeRows - 1 , 0 ) * rowGap ;
442+ snappedHeight = Math . max (
443+ initialHeight - ( wholeRows * minHeight + totalGaps ) ,
444+ minHeight
445+ ) ;
381446 }
447+
448+ return snappedHeight ;
382449 }
383450
384451 private _handleResizeEnd ( event : CustomEvent < ResizeCallbackParams > ) {
@@ -388,15 +455,31 @@ export default class IgcTileComponent extends EventEmitterMixin<
388455
389456 const resizeElement = event . target as HTMLElement ;
390457
458+ const parentWrapper =
459+ this . parentElement ! . shadowRoot ! . querySelector ( '[part="base"]' ) ! ;
460+ const computedStyle = window . getComputedStyle ( parentWrapper ) ;
461+ const tm = parentWrapper . getBoundingClientRect ( ) ;
462+
463+ tm . height -=
464+ Number . parseFloat ( computedStyle . paddingTop ) +
465+ Number . parseFloat ( computedStyle . paddingBottom ) ;
466+ tm . width -=
467+ Number . parseFloat ( computedStyle . paddingLeft ) +
468+ Number . parseFloat ( computedStyle . paddingRight ) ;
469+
470+ const gridColumnWidth = tm . width / this . _cachedStyles . columnCount ! ;
471+ let colSpan = Math . round ( width / gridColumnWidth ) ;
472+ colSpan = Math . max ( 1 , Math . min ( colSpan , this . _cachedStyles . columnCount ! ) ) ;
473+
474+ const minH = this . _cachedStyles . minHeight ;
475+ const rowSpan = Math . max ( 1 , Math . floor ( height / minH ! ) ) ;
476+
391477 // REVIEW
392478 Object . assign ( resizeElement . style , {
393479 width : '' ,
394480 height : '' ,
395481 } ) ;
396482
397- const colSpan = Math . max ( 1 , Math . floor ( width / 200 ) ) ;
398- const rowSpan = Math . max ( 1 , Math . floor ( height / 200 ) ) ;
399-
400483 Object . assign ( this . style , {
401484 gridRow : `span ${ rowSpan } ` ,
402485 gridColumn : `span ${ colSpan } ` ,
@@ -418,9 +501,9 @@ export default class IgcTileComponent extends EventEmitterMixin<
418501 top : 0 ,
419502 left : 0 ,
420503 zIndex : 1000 ,
421- background : this . _cachedStyles . ghostBackground ,
422- border : `1px solid ${ this . _cachedStyles . ghostBorder } ` ,
423- borderRadius : this . _cachedStyles . ghostBorderRadius ,
504+ background : this . _cachedStyles . background ,
505+ border : `1px solid ${ this . _cachedStyles . border } ` ,
506+ borderRadius : this . _cachedStyles . borderRadius ,
424507 width : '100%' ,
425508 height : '100%' ,
426509 gridRow : '' ,
0 commit comments