11import { Component , Input , Output , HostBinding , ChangeDetectionStrategy , ChangeDetectorRef , Renderer2 , AfterViewInit , OnDestroy , ElementRef , NgZone } from '@angular/core' ;
2- import { Observable , Subscriber } from 'rxjs' ;
2+ import { Observable , Subscriber , Subject } from 'rxjs' ;
33import { debounceTime } from 'rxjs/operators' ;
44
55import { IArea } from '../interface/IArea' ;
66import { IPoint } from '../interface/IPoint' ;
77import { SplitAreaDirective } from '../directive/splitArea.directive' ;
8- import { getPointFromEvent , getPixelSize } from '../utils' ;
8+ import { getPointFromEvent , getPixelSize , getInputBoolean , isValidTotalSize } from '../utils' ;
99
1010/**
1111 * angular-split
@@ -50,9 +50,9 @@ import { getPointFromEvent, getPixelSize } from '../utils';
5050 class="as-split-gutter"
5151 [style.flex-basis.px]="gutterSize"
5252 [style.order]="index*2+1"
53- (click)="clickGutter($event, index+1)"
54- (mousedown)="startDragging($event, index*2+1, index+1)"
55- (touchstart)="startDragging($event, index*2+1, index+1)">
53+ (click.out-zone )="clickGutter($event, index+1)"
54+ (mousedown.out-zone )="startDragging($event, index*2+1, index+1)"
55+ (touchstart.out-zone )="startDragging($event, index*2+1, index+1)">
5656 <div class="as-split-gutter-icon"></div>
5757 </div>
5858 </ng-template>` ,
@@ -62,8 +62,7 @@ export class SplitComponent implements AfterViewInit, OnDestroy {
6262 private _direction : 'horizontal' | 'vertical' = 'horizontal' ;
6363
6464 @Input ( ) set direction ( v : 'horizontal' | 'vertical' ) {
65- v = ( v === 'vertical' ) ? 'vertical' : 'horizontal' ;
66- this . _direction = v ;
65+ this . _direction = ( v === 'vertical' ) ? 'vertical' : 'horizontal' ;
6766
6867 this . renderer . addClass ( this . elRef . nativeElement , `is-${ this . _direction } ` ) ;
6968 this . renderer . removeClass ( this . elRef . nativeElement , `is-${ ( this . _direction === 'vertical' ) ? 'horizontal' : 'vertical' } ` ) ;
@@ -95,11 +94,10 @@ export class SplitComponent implements AfterViewInit, OnDestroy {
9594 private _useTransition : boolean = false ;
9695
9796 @Input ( ) set useTransition ( v : boolean ) {
98- v = ( typeof ( v ) === 'boolean' ) ? v : ( v === 'false' ? false : true ) ;
99- this . _useTransition = v ;
97+ this . _useTransition = getInputBoolean ( v ) ;
10098
101- if ( v ) this . renderer . addClass ( this . elRef . nativeElement , 'is-transition' ) ;
102- else this . renderer . removeClass ( this . elRef . nativeElement , 'is-transition' ) ;
99+ if ( this . _useTransition ) this . renderer . addClass ( this . elRef . nativeElement , 'is-transition' ) ;
100+ else this . renderer . removeClass ( this . elRef . nativeElement , 'is-transition' ) ;
103101 }
104102
105103 get useTransition ( ) : boolean {
@@ -111,11 +109,10 @@ export class SplitComponent implements AfterViewInit, OnDestroy {
111109 private _disabled : boolean = false ;
112110
113111 @Input ( ) set disabled ( v : boolean ) {
114- v = ( typeof ( v ) === 'boolean' ) ? v : ( v === 'false' ? false : true ) ;
115- this . _disabled = v ;
112+ this . _disabled = getInputBoolean ( v ) ;
116113
117- if ( v ) this . renderer . addClass ( this . elRef . nativeElement , 'is-disabled' ) ;
118- else this . renderer . removeClass ( this . elRef . nativeElement , 'is-disabled' ) ;
114+ if ( this . _disabled ) this . renderer . addClass ( this . elRef . nativeElement , 'is-disabled' ) ;
115+ else this . renderer . removeClass ( this . elRef . nativeElement , 'is-disabled' ) ;
119116 }
120117
121118 get disabled ( ) : boolean {
@@ -139,37 +136,42 @@ export class SplitComponent implements AfterViewInit, OnDestroy {
139136
140137 ////
141138
142- private _dragStartSubscriber : Subscriber < { gutterNum : number , sizes : Array < number > } >
139+ private dragStartSubscriber : Subscriber < { gutterNum : number , sizes : Array < number > } >
143140 @Output ( ) get dragStart ( ) : Observable < { gutterNum : number , sizes : Array < number > } > {
144- return new Observable ( subscriber => this . _dragStartSubscriber = subscriber ) ;
141+ return new Observable ( subscriber => this . dragStartSubscriber = subscriber ) ;
145142 }
146- private _dragProgressSubscriber : Subscriber < { gutterNum : number , sizes : Array < number > } >
147- @Output ( ) get dragProgress ( ) : Observable < { gutterNum : number , sizes : Array < number > } > {
148- return new Observable ( subscriber => this . _dragProgressSubscriber = subscriber ) ;
149- }
150- private _dragEndSubscriber : Subscriber < { gutterNum : number , sizes : Array < number > } >
143+
144+ private dragEndSubscriber : Subscriber < { gutterNum : number , sizes : Array < number > } >
151145 @Output ( ) get dragEnd ( ) : Observable < { gutterNum : number , sizes : Array < number > } > {
152- return new Observable ( subscriber => this . _dragEndSubscriber = subscriber ) ;
146+ return new Observable ( subscriber => this . dragEndSubscriber = subscriber ) ;
153147 }
154- private _gutterClickSubscriber : Subscriber < { gutterNum : number , sizes : Array < number > } >
148+
149+ private gutterClickSubscriber : Subscriber < { gutterNum : number , sizes : Array < number > } >
155150 @Output ( ) get gutterClick ( ) : Observable < { gutterNum : number , sizes : Array < number > } > {
156- return new Observable ( subscriber => this . _gutterClickSubscriber = subscriber ) ;
151+ return new Observable ( subscriber => this . gutterClickSubscriber = subscriber ) ;
157152 }
158153
159- private _transitionEndSubscriber : Subscriber < Array < number > >
154+ private transitionEndSubscriber : Subscriber < Array < number > >
160155 @Output ( ) get transitionEnd ( ) : Observable < Array < number > > {
161- return new Observable ( subscriber => this . _transitionEndSubscriber = subscriber ) . pipe (
156+ return new Observable ( subscriber => this . transitionEndSubscriber = subscriber ) . pipe (
162157 debounceTime < Array < number > > ( 20 )
163158 ) ;
164159 }
160+
161+ private dragProgressSubject : Subject < { gutterNum : number , sizes : Array < number > } > = new Subject ( ) ;
162+ dragProgress$ : Observable < { gutterNum : number , sizes : Array < number > } > = this . dragProgressSubject . asObservable ( ) ;
165163
166- @HostBinding ( 'style.min-width' ) get cssMinwidth ( ) {
167- return ( this . direction === 'horizontal' ) ? `${ this . getNbGutters ( ) * this . gutterSize } px` : null ;
168- }
164+ ////
169165
170- @HostBinding ( 'style.min-height' ) get cssMinheight ( ) {
171- return ( this . direction === 'vertical' ) ? `${ this . getNbGutters ( ) * this . gutterSize } px` : null ;
172- }
166+ // @HostBinding ('style.min-width') get cssMinwidth() {
167+ // return (this.direction === 'horizontal') ? `${ this.getNbGutters() * this.gutterSize }px` : null;
168+ // }
169+
170+ // @HostBinding ('style.min-height') get cssMinheight() {
171+ // return (this.direction === 'vertical') ? `${ this.getNbGutters() * this.gutterSize }px` : null;
172+ // }
173+
174+ ////
173175
174176 private isDragging : boolean = false ;
175177 private currentGutterNum : number = 0 ;
@@ -279,6 +281,26 @@ export class SplitComponent implements AfterViewInit, OnDestroy {
279281 this . cdRef . markForCheck ( ) ;
280282 }
281283
284+ public setVisibleAreaSizes ( sizes : Array < number > ) : boolean {
285+ if ( sizes . length !== this . displayedAreas . length ) {
286+ return false ;
287+ }
288+
289+ sizes = sizes . map ( s => s / 100 ) ;
290+
291+ const total = sizes . reduce ( ( total : number , v : number ) => total + v , 0 ) ;
292+ if ( ! isValidTotalSize ( total ) ) {
293+ return false ;
294+ }
295+
296+ this . displayedAreas . forEach ( ( area , i ) => {
297+ area . component [ '_size' ] = sizes [ i ] ;
298+ } )
299+
300+ this . build ( false , true ) ;
301+ return true ;
302+ }
303+
282304 private build ( resetOrders : boolean , resetSizes : boolean ) : void {
283305 this . stopDragging ( ) ;
284306
@@ -306,7 +328,7 @@ export class SplitComponent implements AfterViewInit, OnDestroy {
306328 const totalUserSize = < number > this . displayedAreas . reduce ( ( total : number , s : IArea ) => s . component . size ? total + s . component . size : total , 0 ) ;
307329
308330 // If user provided 'size' for each area and total == 1, use it.
309- if ( this . displayedAreas . every ( a => a . component . size !== null ) && totalUserSize > .999 && totalUserSize < 1.001 ) {
331+ if ( this . displayedAreas . every ( a => a . component . size !== null ) && isValidTotalSize ( totalUserSize ) ) {
310332
311333 this . displayedAreas . forEach ( area => {
312334 area . size = < number > area . component . size ;
@@ -367,17 +389,21 @@ export class SplitComponent implements AfterViewInit, OnDestroy {
367389 }
368390
369391 public clickGutter ( event : MouseEvent , gutterNum : number ) : void {
392+ event . preventDefault ( ) ;
393+ event . stopPropagation ( ) ;
394+
370395 if ( this . startPoint && this . startPoint . x === event . pageX && this . startPoint . y === event . pageY ) {
371396 this . currentGutterNum = gutterNum ;
372397
373398 this . notify ( 'click' ) ;
374399 }
375400 }
376401
377- public startDragging ( startEvent : MouseEvent | TouchEvent , gutterOrder : number , gutterNum : number ) : void {
378- startEvent . preventDefault ( ) ;
402+ public startDragging ( event : MouseEvent | TouchEvent , gutterOrder : number , gutterNum : number ) : void {
403+ event . preventDefault ( ) ;
404+ event . stopPropagation ( ) ;
379405
380- this . startPoint = getPointFromEvent ( startEvent ) ;
406+ this . startPoint = getPointFromEvent ( event ) ;
381407 if ( ! this . startPoint || this . disabled ) {
382408 return ;
383409 }
@@ -415,6 +441,7 @@ export class SplitComponent implements AfterViewInit, OnDestroy {
415441
416442 private dragEvent ( event : MouseEvent | TouchEvent , areaA : IArea , areaB : IArea ) : void {
417443 event . preventDefault ( ) ;
444+ event . stopPropagation ( ) ;
418445
419446 if ( ! this . isDragging ) {
420447 return ;
@@ -479,6 +506,7 @@ export class SplitComponent implements AfterViewInit, OnDestroy {
479506
480507 this . refreshStyleSizes ( ) ;
481508
509+ // If moved from starting point, notify progress
482510 if ( this . startPoint . x !== this . endPoint . x || this . startPoint . y !== this . endPoint . y ) {
483511 this . notify ( 'progress' ) ;
484512 }
@@ -487,23 +515,25 @@ export class SplitComponent implements AfterViewInit, OnDestroy {
487515 private stopDragging ( event ?: Event ) : void {
488516 if ( event ) {
489517 event . preventDefault ( ) ;
518+ event . stopPropagation ( ) ;
490519 }
491-
520+
492521 if ( this . isDragging === false ) {
493522 return ;
494523 }
495-
524+
496525 this . displayedAreas . forEach ( area => {
497526 area . component . unlockEvents ( ) ;
498527 } ) ;
499-
528+
500529 while ( this . dragListeners . length > 0 ) {
501530 const fct = this . dragListeners . pop ( ) ;
502531 if ( fct ) {
503532 fct ( ) ;
504533 }
505534 }
506535
536+ // If moved from starting point, notify end
507537 if ( this . endPoint && ( this . startPoint . x !== this . endPoint . x || this . startPoint . y !== this . endPoint . y ) ) {
508538 this . notify ( 'end' ) ;
509539 }
@@ -520,35 +550,33 @@ export class SplitComponent implements AfterViewInit, OnDestroy {
520550 } ) ;
521551 }
522552
523-
524553 public notify ( type : 'start' | 'progress' | 'end' | 'click' | 'transitionEnd' ) : void {
525554 const sizes : Array < number > = this . displayedAreas . map ( a => a . size * 100 ) ;
526555
527556 if ( type === 'start' ) {
528- if ( this . _dragStartSubscriber ) {
529- this . ngZone . run ( ( ) => this . _dragStartSubscriber . next ( { gutterNum : this . currentGutterNum , sizes} ) ) ;
530- }
531- }
532- else if ( type === 'progress' ) {
533- if ( this . _dragProgressSubscriber ) {
534- this . ngZone . run ( ( ) => this . _dragProgressSubscriber . next ( { gutterNum : this . currentGutterNum , sizes} ) ) ;
557+ if ( this . dragStartSubscriber ) {
558+ this . ngZone . run ( ( ) => this . dragStartSubscriber . next ( { gutterNum : this . currentGutterNum , sizes} ) ) ;
535559 }
536560 }
537561 else if ( type === 'end' ) {
538- if ( this . _dragEndSubscriber ) {
539- this . ngZone . run ( ( ) => this . _dragEndSubscriber . next ( { gutterNum : this . currentGutterNum , sizes} ) ) ;
562+ if ( this . dragEndSubscriber ) {
563+ this . ngZone . run ( ( ) => this . dragEndSubscriber . next ( { gutterNum : this . currentGutterNum , sizes} ) ) ;
540564 }
541565 }
542566 else if ( type === 'click' ) {
543- if ( this . _gutterClickSubscriber ) {
544- this . ngZone . run ( ( ) => this . _gutterClickSubscriber . next ( { gutterNum : this . currentGutterNum , sizes} ) ) ;
567+ if ( this . gutterClickSubscriber ) {
568+ this . ngZone . run ( ( ) => this . gutterClickSubscriber . next ( { gutterNum : this . currentGutterNum , sizes} ) ) ;
545569 }
546570 }
547571 else if ( type === 'transitionEnd' ) {
548- if ( this . _transitionEndSubscriber ) {
549- this . ngZone . run ( ( ) => this . _transitionEndSubscriber . next ( sizes ) ) ;
572+ if ( this . transitionEndSubscriber ) {
573+ this . ngZone . run ( ( ) => this . transitionEndSubscriber . next ( sizes ) ) ;
550574 }
551575 }
576+ else if ( type === 'progress' ) {
577+ // Stay outside zone to allow users do what they want about change detection mecanism.
578+ this . dragProgressSubject . next ( { gutterNum : this . currentGutterNum , sizes} ) ;
579+ }
552580 }
553581
554582 public ngOnDestroy ( ) : void {
0 commit comments