@@ -29,6 +29,11 @@ export interface WaterfallLayoutOptions {
2929 * @default 18 x 18
3030 */
3131 minSpace ?: Size ,
32+ /**
33+ * The maximum allowed horizontal space between items.
34+ * @default Infinity
35+ */
36+ maxHorizontalSpace ?: number ,
3237 /**
3338 * The maximum number of columns.
3439 * @default Infinity
@@ -55,6 +60,7 @@ const DEFAULT_OPTIONS = {
5560 minItemSize : new Size ( 200 , 200 ) ,
5661 maxItemSize : new Size ( Infinity , Infinity ) ,
5762 minSpace : new Size ( 18 , 18 ) ,
63+ maxSpace : Infinity ,
5864 maxColumns : Infinity ,
5965 dropIndicatorThickness : 2
6066} ;
@@ -64,20 +70,23 @@ export class WaterfallLayout<T extends object, O extends WaterfallLayoutOptions
6470 private layoutInfos : Map < Key , WaterfallLayoutInfo > = new Map ( ) ;
6571 protected numColumns = 0 ;
6672 protected dropIndicatorThickness = 2 ;
73+ private margin : number = 0 ;
6774
6875 shouldInvalidateLayoutOptions ( newOptions : O , oldOptions : O ) : boolean {
6976 return newOptions . maxColumns !== oldOptions . maxColumns
7077 || newOptions . dropIndicatorThickness !== oldOptions . dropIndicatorThickness
7178 || ( ! ( newOptions . minItemSize || DEFAULT_OPTIONS . minItemSize ) . equals ( oldOptions . minItemSize || DEFAULT_OPTIONS . minItemSize ) )
7279 || ( ! ( newOptions . maxItemSize || DEFAULT_OPTIONS . maxItemSize ) . equals ( oldOptions . maxItemSize || DEFAULT_OPTIONS . maxItemSize ) )
73- || ( ! ( newOptions . minSpace || DEFAULT_OPTIONS . minSpace ) . equals ( oldOptions . minSpace || DEFAULT_OPTIONS . minSpace ) ) ;
80+ || ( ! ( newOptions . minSpace || DEFAULT_OPTIONS . minSpace ) . equals ( oldOptions . minSpace || DEFAULT_OPTIONS . minSpace ) )
81+ || ( newOptions . maxHorizontalSpace !== oldOptions . maxHorizontalSpace ) ;
7482 }
7583
7684 update ( invalidationContext : InvalidationContext < O > ) : void {
7785 let {
7886 minItemSize = DEFAULT_OPTIONS . minItemSize ,
7987 maxItemSize = DEFAULT_OPTIONS . maxItemSize ,
8088 minSpace = DEFAULT_OPTIONS . minSpace ,
89+ maxHorizontalSpace = DEFAULT_OPTIONS . maxSpace ,
8190 maxColumns = DEFAULT_OPTIONS . maxColumns ,
8291 dropIndicatorThickness = DEFAULT_OPTIONS . dropIndicatorThickness
8392 } = invalidationContext . layoutOptions || { } ;
@@ -107,8 +116,9 @@ export class WaterfallLayout<T extends object, O extends WaterfallLayoutOptions
107116 let itemHeight = minItemSize . height + Math . floor ( ( maxItemHeight - minItemSize . height ) * t ) ;
108117 itemHeight = Math . max ( minItemSize . height , Math . min ( maxItemHeight , itemHeight ) ) ;
109118
110- // Compute the horizontal spacing and content height
111- let horizontalSpacing = Math . floor ( ( visibleWidth - numColumns * itemWidth ) / ( numColumns + 1 ) ) ;
119+ // Compute the horizontal spacing, content height and horizontal margin
120+ let horizontalSpacing = Math . min ( Math . max ( maxHorizontalSpace , minSpace . width ) , Math . floor ( ( visibleWidth - numColumns * itemWidth ) / ( numColumns + 1 ) ) ) ;
121+ this . margin = Math . floor ( ( visibleWidth - numColumns * itemWidth - horizontalSpacing * ( numColumns + 1 ) ) / 2 ) ;
112122
113123 // Setup an array of column heights
114124 let columnHeights = Array ( numColumns ) . fill ( minSpace . height ) ;
@@ -126,7 +136,7 @@ export class WaterfallLayout<T extends object, O extends WaterfallLayoutOptions
126136 // Preserve the previous column index so items don't jump around during resizing unless the number of columns changed.
127137 let prevColumn = numColumns === this . numColumns && oldLayoutInfo && oldLayoutInfo . rect . y < this . virtualizer ! . visibleRect . maxY ? oldLayoutInfo . column : undefined ;
128138 let column = prevColumn ?? columnHeights . reduce ( ( minIndex , h , i ) => h < columnHeights [ minIndex ] ? i : minIndex , 0 ) ;
129- let x = horizontalSpacing + column * ( itemWidth + horizontalSpacing ) ;
139+ let x = horizontalSpacing + column * ( itemWidth + horizontalSpacing ) + this . margin ;
130140 let y = columnHeights [ column ] ;
131141
132142 let rect = new Rect ( x , y , itemWidth , height ) ;
0 commit comments