@@ -4,37 +4,35 @@ import { debounceTime } from 'rxjs/operators';
44
55import { IArea , IPoint , ISplitSnapshot , IAreaSnapshot , ISplitSideAbsorptionCapacity , IOutputData , IOutputAreaSizes } from '../interface' ;
66import { SplitAreaDirective } from '../directive/splitArea.directive' ;
7- import { getInputPositiveNumber , getInputBoolean , getPointFromEvent , getElementPixelSize , getAreaAbsorptionCapacity , updateAreaSize , isUserSizesValid } from '../utils' ;
7+ import { getInputPositiveNumber , getInputBoolean , isUserSizesValid , getPointFromEvent , getElementPixelSize , getGutterSideAbsorptionCapacity , updateAreaSize } from '../utils' ;
88
99/**
1010 * angular-split
1111 *
12- * Areas size are set in percentage of the split container.
13- * Gutters size are set in pixels.
1412 *
15- * So we set css 'flex-basis' property like this (where 0 <= area.size <= 1):
16- * calc( { area.size * 100 }% - { area.size * nbGutter * gutterSize }px );
13+ * PERCENT MODE ([unit]="'percent'")
14+ * ___________________________________________________________________________________________
15+ * | A [g1] B [g2] C [g3] D [g4] E |
16+ * |-------------------------------------------------------------------------------------------|
17+ * | 20 30 20 15 15 | <-- [size]="x"
18+ * | 10px 10px 10px 10px | <-- [gutterSize]="10"
19+ * |calc(20% - 8px) calc(30% - 12px) calc(20% - 8px) calc(15% - 6px) calc(15% - 6px)| <-- CSS flex-basis property (with flex-grow&shrink at 0)
20+ * | 152px 228px 152px 114px 114px | <-- el.getBoundingClientRect().width
21+ * |___________________________________________________________________________________________|
22+ * 800px <-- el.getBoundingClientRect().width
23+ * flex-basis = calc( { area.size }% - { area.size/100 * nbGutter*gutterSize }px );
1724 *
18- * Examples with 3 visible areas and 2 gutters:
1925 *
20- * | 10px 10px |
21- * |---------------------[]---------------------[]------------------------------------|
22- * | calc(20% - 4px) calc(20% - 4px) calc(60% - 12px) |
23- *
24- *
25- * | 10px 10px |
26- * |--------------------------[]--------------------------[]--------------------------|
27- * | calc(33.33% - 6.667px) calc(33.33% - 6.667px) calc(33.33% - 6.667px) |
28- *
29- *
30- * |10px 10px |
31- * |[]----------------------------------------------------[]--------------------------|
32- * |0 calc(66.66% - 13.333px) calc(33%% - 6.667px) |
33- *
34- *
35- * 10px 10px |
36- * |[][]------------------------------------------------------------------------------|
37- * |0 0 calc(100% - 20px) |
26+ * PIXEL MODE ([unit]="'pixel'")
27+ * ___________________________________________________________________________________________
28+ * | A [g1] B [g2] C [g3] D [g4] E |
29+ * |-------------------------------------------------------------------------------------------|
30+ * | 100 250 * 150 100 | <-- [size]="y"
31+ * | 10px 10px 10px 10px | <-- [gutterSize]="10"
32+ * | 0 0 100px 0 0 250px 1 1 auto 0 0 150px 0 0 100px | <-- CSS flex property (flex-grow/flex-shrink/flex-basis)
33+ * | 100px 250px 200px 150px 100px | <-- el.getBoundingClientRect().width
34+ * |___________________________________________________________________________________________|
35+ * 800px <-- el.getBoundingClientRect().width
3836 *
3937 */
4038
@@ -287,7 +285,7 @@ export class SplitComponent implements AfterViewInit, OnDestroy {
287285 }
288286
289287 public getVisibleAreaSizes ( ) : IOutputAreaSizes {
290- return this . displayedAreas . map ( a => a . size || '*' ) ;
288+ return this . displayedAreas . map ( a => a . size === null ? '*' : a . size ) ;
291289 }
292290
293291 public setVisibleAreaSizes ( sizes : IOutputAreaSizes ) : boolean {
@@ -380,22 +378,34 @@ export class SplitComponent implements AfterViewInit, OnDestroy {
380378
381379 private refreshStyleSizes ( ) : void {
382380 if ( this . displayedAreas . length === 1 ) {
383- this . displayedAreas [ 0 ] . component . setStyleFlex ( `0 0 100%` ) ;
381+ this . displayedAreas [ 0 ] . component . setStyleFlex ( `0 0 100%` , false , false ) ;
384382 }
385383 else if ( this . unit === 'percent' ) {
386384 const sumGutterSize = this . getNbGutters ( ) * this . gutterSize ;
387385
388386 this . displayedAreas . forEach ( area => {
389- area . component . setStyleFlex ( `0 0 calc( ${ area . size } % - ${ < number > area . size / 100 * sumGutterSize } px )` ) ;
387+ area . component . setStyleFlex (
388+ `0 0 calc( ${ area . size } % - ${ < number > area . size / 100 * sumGutterSize } px )` ,
389+ area . minSize !== null && area . minSize === area . size ? true : false ,
390+ area . maxSize !== null && area . maxSize === area . size ? true : false ,
391+ ) ;
390392 } ) ;
391393 }
392394 else if ( this . unit === 'pixel' ) {
393395 this . displayedAreas . forEach ( area => {
394396 if ( area . size === null ) {
395- area . component . setStyleFlex ( `1 1 auto` ) ;
397+ area . component . setStyleFlex (
398+ `1 1 auto` ,
399+ area . minSize !== null && area . minSize === area . size ? true : false ,
400+ area . maxSize !== null && area . maxSize === area . size ? true : false ,
401+ ) ;
396402 }
397403 else {
398- area . component . setStyleFlex ( `0 0 ${ area . size } px` ) ;
404+ area . component . setStyleFlex (
405+ `0 0 ${ area . size } px` ,
406+ area . minSize !== null && area . minSize === area . size ? true : false ,
407+ area . maxSize !== null && area . maxSize === area . size ? true : false ,
408+ ) ;
399409 }
400410 } ) ;
401411 }
@@ -427,7 +437,7 @@ export class SplitComponent implements AfterViewInit, OnDestroy {
427437 this . snapshot = {
428438 gutterNum,
429439 lastSteppedOffset : 0 ,
430- containerSizePixel : getElementPixelSize ( this . elRef , this . direction ) ,
440+ allAreasSizePixel : getElementPixelSize ( this . elRef , this . direction ) - this . getNbGutters ( ) * this . gutterSize ,
431441 areasBeforeGutter : [ ] ,
432442 areasAfterGutter : [ ] ,
433443 } ;
@@ -498,24 +508,44 @@ export class SplitComponent implements AfterViewInit, OnDestroy {
498508
499509 // Need to know if each gutter side areas could reacts to steppedOffset
500510
501- const areasBefore : ISplitSideAbsorptionCapacity = this . snapshot . areasBeforeGutter . reduce ( ( acc , area ) => {
502- const res = getAreaAbsorptionCapacity ( this . unit , area , acc . remain , this . snapshot . containerSizePixel ) ;
503- acc . list . push ( res ) ;
504- acc . remain = res . pixelRemain ;
505- return acc ;
506- } , { remain : - steppedOffset , list : [ ] } ) ;
511+ let areasBefore = getGutterSideAbsorptionCapacity ( this . unit , this . snapshot . areasBeforeGutter , - steppedOffset , this . snapshot . allAreasSizePixel ) ;
512+ let areasAfter = getGutterSideAbsorptionCapacity ( this . unit , this . snapshot . areasAfterGutter , steppedOffset , this . snapshot . allAreasSizePixel ) ;
513+
514+ // Each gutter side areas can't absorb all offset
515+ if ( areasBefore . remain !== 0 && areasAfter . remain !== 0 ) {
516+ console . log ( 'Case AAA > before=' , areasBefore , ' - after=' , areasAfter )
517+ if ( Math . abs ( areasBefore . remain ) > Math . abs ( areasAfter . remain ) ) {
518+
519+ }
520+ else {
521+
522+ }
523+ }
524+ // Areas before gutter can't absorbs all offset > need to recalculate sizes for areas after gutter.
525+ else if ( areasBefore . remain !== 0 ) {
526+ console . log ( 'Case BBB > before=' , areasBefore . remain )
527+ areasAfter = getGutterSideAbsorptionCapacity ( this . unit , this . snapshot . areasAfterGutter , steppedOffset + areasBefore . remain , this . snapshot . allAreasSizePixel ) ;
528+ }
529+ // Areas after gutter can't absorbs all offset > need to recalculate sizes for areas before gutter.
530+ else if ( areasAfter . remain !== 0 ) {
531+ console . log ( 'Case CCC > after=' , areasAfter . remain )
532+ areasBefore = getGutterSideAbsorptionCapacity ( this . unit , this . snapshot . areasBeforeGutter , - ( steppedOffset - areasAfter . remain ) , this . snapshot . allAreasSizePixel ) ;
533+ }
534+
535+ // Hack to force total === 100
536+ if ( this . unit === 'percent' ) {
537+ // get first area not at min/max and set size to 100-allAreaSizes
538+ const areaToReset = this . displayedAreas . find ( a => a . size !== 0 && a . size !== a . minSize && a . size !== a . maxSize ) ;
539+
540+ areaToReset . size = 100 - this . displayedAreas . filter ( a => a !== areaToReset ) . reduce ( ( total , a ) => total + a . size , 0 ) ;
541+ }
542+
507543
508- const areasAfter : ISplitSideAbsorptionCapacity = this . snapshot . areasAfterGutter . reduce ( ( acc , area ) => {
509- const res = getAreaAbsorptionCapacity ( this . unit , area , acc . remain , this . snapshot . containerSizePixel ) ;
510- acc . list . push ( res ) ;
511- acc . remain = res . pixelRemain ;
512- return acc ;
513- } , { remain : steppedOffset , list : [ ] } ) ;
544+ const tt = [ ...areasBefore . list . map ( a => a . percentAfterAbsorption ) , ...areasAfter . list . map ( a => a . percentAfterAbsorption ) ] . reduce ( ( t , s ) => t + s , 0 ) ;
545+ if ( tt !== 100 ) debugger ;
514546
515547 // Now we know areas could absorb steppedOffset, time to really update sizes
516548
517- console . log ( 'A' , areasBefore . list [ 0 ] . pixelAbsorb , areasBefore . list [ 0 ] . percentAfterAbsorption ) ;
518- console . log ( 'B' , areasAfter . list [ 0 ] . pixelAbsorb , areasAfter . list [ 0 ] . percentAfterAbsorption ) ;
519549 areasBefore . list . forEach ( item => updateAreaSize ( this . unit , item ) ) ;
520550 areasAfter . list . forEach ( item => updateAreaSize ( this . unit , item ) ) ;
521551
0 commit comments