UNPKG

@davvidess/angular-split

Version:

Angular UI library to split views and allow dragging to resize areas using CSS flexbox layout.

1,069 lines 104 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Component, Input, Output, ChangeDetectionStrategy, ChangeDetectorRef, Renderer2, ElementRef, NgZone, ViewChildren, QueryList, EventEmitter, ViewEncapsulation, } from '@angular/core'; import { Observable, Subject } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; import { getInputPositiveNumber, getInputBoolean, isUserSizesValid, getAreaMinSize, getAreaMaxSize, getPointFromEvent, getElementPixelSize, getGutterSideAbsorptionCapacity, updateAreaSize, } from '../utils'; /** * angular-split * * * PERCENT MODE ([unit]="'percent'") * ___________________________________________________________________________________________ * | A [g1] B [g2] C [g3] D [g4] E | * |-------------------------------------------------------------------------------------------| * | 20 30 20 15 15 | <-- [size]="x" * | 10px 10px 10px 10px | <-- [gutterSize]="10" * |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) * | 152px 228px 152px 114px 114px | <-- el.getBoundingClientRect().width * |___________________________________________________________________________________________| * 800px <-- el.getBoundingClientRect().width * flex-basis = calc( { area.size }% - { area.size/100 * nbGutter*gutterSize }px ); * * * PIXEL MODE ([unit]="'pixel'") * ___________________________________________________________________________________________ * | A [g1] B [g2] C [g3] D [g4] E | * |-------------------------------------------------------------------------------------------| * | 100 250 * 150 100 | <-- [size]="y" * | 10px 10px 10px 10px | <-- [gutterSize]="10" * | 0 0 100px 0 0 250px 1 1 auto 0 0 150px 0 0 100px | <-- CSS flex property (flex-grow/flex-shrink/flex-basis) * | 100px 250px 200px 150px 100px | <-- el.getBoundingClientRect().width * |___________________________________________________________________________________________| * 800px <-- el.getBoundingClientRect().width * */ export class SplitComponent { /** * @param {?} ngZone * @param {?} elRef * @param {?} cdRef * @param {?} renderer */ constructor(ngZone, elRef, cdRef, renderer) { this.ngZone = ngZone; this.elRef = elRef; this.cdRef = cdRef; this.renderer = renderer; this._direction = 'horizontal'; //// this._unit = 'percent'; //// this._gutterSize = 11; //// this._gutterStep = 1; //// this._restrictMove = false; //// this._useTransition = false; //// this._disabled = false; //// this._dir = 'ltr'; //// this._gutterDblClickDuration = 0; //// this.dragStart = new EventEmitter(false); this.dragEnd = new EventEmitter(false); this.gutterClick = new EventEmitter(false); this.gutterDblClick = new EventEmitter(false); this.dragProgressSubject = new Subject(); this.dragProgress$ = this.dragProgressSubject.asObservable(); //// this.isDragging = false; this.isWaitingClear = false; this.dragListeners = []; this.snapshot = null; this.startPoint = null; this.endPoint = null; this.displayedAreas = []; this.hidedAreas = []; this._clickTimeout = null; // To force adding default class, could be override by user @Input() or not this.direction = this._direction; } /** * @param {?} v * @return {?} */ set direction(v) { this._direction = v === 'vertical' ? 'vertical' : 'horizontal'; this.renderer.addClass(this.elRef.nativeElement, `as-${this._direction}`); this.renderer.removeClass(this.elRef.nativeElement, `as-${this._direction === 'vertical' ? 'horizontal' : 'vertical'}`); this.build(false, false); } /** * @return {?} */ get direction() { return this._direction; } /** * @param {?} v * @return {?} */ set unit(v) { this._unit = v === 'pixel' ? 'pixel' : 'percent'; this.renderer.addClass(this.elRef.nativeElement, `as-${this._unit}`); this.renderer.removeClass(this.elRef.nativeElement, `as-${this._unit === 'pixel' ? 'percent' : 'pixel'}`); this.build(false, true); } /** * @return {?} */ get unit() { return this._unit; } /** * @param {?} v * @return {?} */ set gutterSize(v) { this._gutterSize = getInputPositiveNumber(v, 11); this.build(false, false); } /** * @return {?} */ get gutterSize() { return this._gutterSize; } /** * @param {?} v * @return {?} */ set gutterStep(v) { this._gutterStep = getInputPositiveNumber(v, 1); } /** * @return {?} */ get gutterStep() { return this._gutterStep; } /** * @param {?} v * @return {?} */ set restrictMove(v) { this._restrictMove = getInputBoolean(v); } /** * @return {?} */ get restrictMove() { return this._restrictMove; } /** * @param {?} v * @return {?} */ set useTransition(v) { this._useTransition = getInputBoolean(v); if (this._useTransition) this.renderer.addClass(this.elRef.nativeElement, 'as-transition'); else this.renderer.removeClass(this.elRef.nativeElement, 'as-transition'); } /** * @return {?} */ get useTransition() { return this._useTransition; } /** * @param {?} v * @return {?} */ set disabled(v) { this._disabled = getInputBoolean(v); if (this._disabled) this.renderer.addClass(this.elRef.nativeElement, 'as-disabled'); else this.renderer.removeClass(this.elRef.nativeElement, 'as-disabled'); } /** * @return {?} */ get disabled() { return this._disabled; } /** * @param {?} v * @return {?} */ set dir(v) { this._dir = v === 'rtl' ? 'rtl' : 'ltr'; this.renderer.setAttribute(this.elRef.nativeElement, 'dir', this._dir); } /** * @return {?} */ get dir() { return this._dir; } /** * @param {?} v * @return {?} */ set gutterDblClickDuration(v) { this._gutterDblClickDuration = getInputPositiveNumber(v, 0); } /** * @return {?} */ get gutterDblClickDuration() { return this._gutterDblClickDuration; } /** * @return {?} */ get transitionEnd() { return new Observable((/** * @param {?} subscriber * @return {?} */ (subscriber) => (this.transitionEndSubscriber = subscriber))).pipe(debounceTime(20)); } /** * @return {?} */ ngAfterViewInit() { this.ngZone.runOutsideAngular((/** * @return {?} */ () => { // To avoid transition at first rendering setTimeout((/** * @return {?} */ () => this.renderer.addClass(this.elRef.nativeElement, 'as-init'))); })); } /** * @private * @return {?} */ getNbGutters() { return this.displayedAreas.length === 0 ? 0 : this.displayedAreas.length - 1; } /** * @param {?} component * @return {?} */ addArea(component) { /** @type {?} */ const newArea = { component, order: 0, size: 0, minSize: null, maxSize: null, }; if (component.visible === true) { this.displayedAreas.push(newArea); this.build(true, true); } else { this.hidedAreas.push(newArea); } } /** * @param {?} component * @return {?} */ removeArea(component) { if (this.displayedAreas.some((/** * @param {?} a * @return {?} */ (a) => a.component === component))) { /** @type {?} */ const area = this.displayedAreas.find((/** * @param {?} a * @return {?} */ (a) => a.component === component)); this.displayedAreas.splice(this.displayedAreas.indexOf(area), 1); this.build(true, true); } else if (this.hidedAreas.some((/** * @param {?} a * @return {?} */ (a) => a.component === component))) { /** @type {?} */ const area = this.hidedAreas.find((/** * @param {?} a * @return {?} */ (a) => a.component === component)); this.hidedAreas.splice(this.hidedAreas.indexOf(area), 1); } } /** * @param {?} component * @param {?} resetOrders * @param {?} resetSizes * @return {?} */ updateArea(component, resetOrders, resetSizes) { if (component.visible === true) { this.build(resetOrders, resetSizes); } } /** * @param {?} component * @return {?} */ showArea(component) { /** @type {?} */ const area = this.hidedAreas.find((/** * @param {?} a * @return {?} */ (a) => a.component === component)); if (area === undefined) { return; } /** @type {?} */ const areas = this.hidedAreas.splice(this.hidedAreas.indexOf(area), 1); this.displayedAreas.push(...areas); this.build(true, true); } /** * @param {?} comp * @return {?} */ hideArea(comp) { /** @type {?} */ const area = this.displayedAreas.find((/** * @param {?} a * @return {?} */ (a) => a.component === comp)); if (area === undefined) { return; } /** @type {?} */ const areas = this.displayedAreas.splice(this.displayedAreas.indexOf(area), 1); areas.forEach((/** * @param {?} area * @return {?} */ (area) => { area.order = 0; area.size = 0; })); this.hidedAreas.push(...areas); this.build(true, true); } /** * @return {?} */ getVisibleAreaSizes() { return this.displayedAreas.map((/** * @param {?} a * @return {?} */ (a) => (a.size === null ? '*' : a.size))); } /** * @param {?} sizes * @return {?} */ setVisibleAreaSizes(sizes) { if (sizes.length !== this.displayedAreas.length) { return false; } /** @type {?} */ const formatedSizes = sizes.map((/** * @param {?} s * @return {?} */ (s) => getInputPositiveNumber(s, null))); /** @type {?} */ const isValid = isUserSizesValid(this.unit, formatedSizes); if (isValid === false) { return false; } // @ts-ignore this.displayedAreas.forEach((/** * @param {?} area * @param {?} i * @return {?} */ (area, i) => (area.component._size = formatedSizes[i]))); this.build(false, true); return true; } /** * @private * @param {?} resetOrders * @param {?} resetSizes * @return {?} */ build(resetOrders, resetSizes) { this.stopDragging(); // ¤ AREAS ORDER if (resetOrders === true) { // If user provided 'order' for each area, use it to sort them. if (this.displayedAreas.every((/** * @param {?} a * @return {?} */ (a) => a.component.order !== null))) { this.displayedAreas.sort((/** * @param {?} a * @param {?} b * @return {?} */ (a, b) => (/** @type {?} */ (a.component.order)) - (/** @type {?} */ (b.component.order)))); } // Then set real order with multiples of 2, numbers between will be used by gutters. this.displayedAreas.forEach((/** * @param {?} area * @param {?} i * @return {?} */ (area, i) => { area.order = i * 2; area.component.setStyleOrder(area.order); })); } // ¤ AREAS SIZE if (resetSizes === true) { /** @type {?} */ const useUserSizes = isUserSizesValid(this.unit, this.displayedAreas.map((/** * @param {?} a * @return {?} */ (a) => a.component.size))); switch (this.unit) { case 'percent': { /** @type {?} */ const defaultSize = 100 / this.displayedAreas.length; this.displayedAreas.forEach((/** * @param {?} area * @return {?} */ (area) => { area.size = useUserSizes ? (/** @type {?} */ (area.component.size)) : defaultSize; area.minSize = getAreaMinSize(area); area.maxSize = getAreaMaxSize(area); })); break; } case 'pixel': { if (useUserSizes) { this.displayedAreas.forEach((/** * @param {?} area * @return {?} */ (area) => { area.size = area.component.size; area.minSize = getAreaMinSize(area); area.maxSize = getAreaMaxSize(area); })); } else { /** @type {?} */ const wildcardSizeAreas = this.displayedAreas.filter((/** * @param {?} a * @return {?} */ (a) => a.component.size === null)) // No wildcard area > Need to select one arbitrarily > first ; // No wildcard area > Need to select one arbitrarily > first if (wildcardSizeAreas.length === 0 && this.displayedAreas.length > 0) { this.displayedAreas.forEach((/** * @param {?} area * @param {?} i * @return {?} */ (area, i) => { area.size = i === 0 ? null : area.component.size; area.minSize = i === 0 ? null : getAreaMinSize(area); area.maxSize = i === 0 ? null : getAreaMaxSize(area); })); } // More than one wildcard area > Need to keep only one arbitrarly > first else if (wildcardSizeAreas.length > 1) { /** @type {?} */ let alreadyGotOne = false; this.displayedAreas.forEach((/** * @param {?} area * @return {?} */ (area) => { if (area.component.size === null) { if (alreadyGotOne === false) { area.size = null; area.minSize = null; area.maxSize = null; alreadyGotOne = true; } else { area.size = 100; area.minSize = null; area.maxSize = null; } } else { area.size = area.component.size; area.minSize = getAreaMinSize(area); area.maxSize = getAreaMaxSize(area); } })); } } break; } } } this.refreshStyleSizes(); this.cdRef.markForCheck(); } /** * @private * @return {?} */ refreshStyleSizes() { /////////////////////////////////////////// // PERCENT MODE if (this.unit === 'percent') { // Only one area > flex-basis 100% if (this.displayedAreas.length === 1) { this.displayedAreas[0].component.setStyleFlex(0, 0, `100%`, false, false); } // Multiple areas > use each percent basis else { /** @type {?} */ const sumGutterSize = this.getNbGutters() * this.gutterSize; this.displayedAreas.forEach((/** * @param {?} area * @return {?} */ (area) => { area.component.setStyleFlex(0, 0, `calc( ${area.size}% - ${((/** @type {?} */ (area.size)) / 100) * sumGutterSize}px )`, area.minSize !== null && area.minSize === area.size ? true : false, area.maxSize !== null && area.maxSize === area.size ? true : false); })); } } /////////////////////////////////////////// // PIXEL MODE else if (this.unit === 'pixel') { this.displayedAreas.forEach((/** * @param {?} area * @return {?} */ (area) => { // Area with wildcard size if (area.size === null) { if (this.displayedAreas.length === 1) { area.component.setStyleFlex(1, 1, `100%`, false, false); } else { area.component.setStyleFlex(1, 1, `auto`, false, false); } } // Area with pixel size else { // Only one area > flex-basis 100% if (this.displayedAreas.length === 1) { area.component.setStyleFlex(0, 0, `100%`, false, false); } // Multiple areas > use each pixel basis else { area.component.setStyleFlex(0, 0, `${area.size}px`, area.minSize !== null && area.minSize === area.size ? true : false, area.maxSize !== null && area.maxSize === area.size ? true : false); } } })); } } /** * @param {?} event * @param {?} gutterNum * @return {?} */ clickGutter(event, gutterNum) { /** @type {?} */ const tempPoint = getPointFromEvent(event) // Be sure mouseup/touchend happened at same point as mousedown/touchstart to trigger click/dblclick ; // Be sure mouseup/touchend happened at same point as mousedown/touchstart to trigger click/dblclick if (this.startPoint && this.startPoint.x === tempPoint.x && this.startPoint.y === tempPoint.y) { // If timeout in progress and new click > clearTimeout & dblClickEvent if (this._clickTimeout !== null) { window.clearTimeout(this._clickTimeout); this._clickTimeout = null; this.notify('dblclick', gutterNum); this.stopDragging(); } // Else start timeout to call clickEvent at end else { this._clickTimeout = window.setTimeout((/** * @return {?} */ () => { this._clickTimeout = null; this.notify('click', gutterNum); this.stopDragging(); }), this.gutterDblClickDuration); } } } /** * @param {?} event * @param {?} gutterOrder * @param {?} gutterNum * @return {?} */ startDragging(event, gutterOrder, gutterNum) { event.preventDefault(); event.stopPropagation(); this.startPoint = getPointFromEvent(event); if (this.startPoint === null || this.disabled === true || this.isWaitingClear === true) { return; } this.snapshot = { gutterNum, lastSteppedOffset: 0, allAreasSizePixel: getElementPixelSize(this.elRef, this.direction) - this.getNbGutters() * this.gutterSize, allInvolvedAreasSizePercent: 100, areasBeforeGutter: [], areasAfterGutter: [], }; this.displayedAreas.forEach((/** * @param {?} area * @return {?} */ (area) => { /** @type {?} */ const areaSnapshot = { area, sizePixelAtStart: getElementPixelSize(area.component.elRef, this.direction), sizePercentAtStart: this.unit === 'percent' ? area.size : -1, }; if (area.order < gutterOrder) { if (this.restrictMove === true) { this.snapshot.areasBeforeGutter = [areaSnapshot]; } else { this.snapshot.areasBeforeGutter.unshift(areaSnapshot); } } else if (area.order > gutterOrder) { if (this.restrictMove === true) { if (this.snapshot.areasAfterGutter.length === 0) this.snapshot.areasAfterGutter = [areaSnapshot]; } else { this.snapshot.areasAfterGutter.push(areaSnapshot); } } })); this.snapshot.allInvolvedAreasSizePercent = [ ...this.snapshot.areasBeforeGutter, ...this.snapshot.areasAfterGutter, ].reduce((/** * @param {?} t * @param {?} a * @return {?} */ (t, a) => t + a.sizePercentAtStart), 0); if (this.snapshot.areasBeforeGutter.length === 0 || this.snapshot.areasAfterGutter.length === 0) { return; } this.dragListeners.push(this.renderer.listen(this.elRef.nativeElement, 'mouseup', this.stopDragging.bind(this))); this.dragListeners.push(this.renderer.listen(this.elRef.nativeElement, 'touchend', this.stopDragging.bind(this))); this.dragListeners.push(this.renderer.listen(this.elRef.nativeElement, 'touchcancel', this.stopDragging.bind(this))); this.ngZone.runOutsideAngular((/** * @return {?} */ () => { this.dragListeners.push(this.renderer.listen(this.elRef.nativeElement, 'mousemove', this.dragEvent.bind(this))); this.dragListeners.push(this.renderer.listen(this.elRef.nativeElement, 'touchmove', this.dragEvent.bind(this))); })); this.displayedAreas.forEach((/** * @param {?} area * @return {?} */ (area) => area.component.lockEvents())); this.isDragging = true; this.renderer.addClass(this.elRef.nativeElement, 'as-dragging'); this.renderer.addClass(this.gutterEls.toArray()[this.snapshot.gutterNum - 1].nativeElement, 'as-dragged'); this.notify('start', this.snapshot.gutterNum); } /** * @private * @param {?} event * @return {?} */ dragEvent(event) { event.preventDefault(); event.stopPropagation(); if (this._clickTimeout !== null) { window.clearTimeout(this._clickTimeout); this._clickTimeout = null; } if (this.isDragging === false) { return; } this.endPoint = getPointFromEvent(event); if (this.endPoint === null) { return; } // Calculate steppedOffset /** @type {?} */ let offset = this.direction === 'horizontal' ? this.startPoint.x - this.endPoint.x : this.startPoint.y - this.endPoint.y; if (this.dir === 'rtl') { offset = -offset; } /** @type {?} */ const steppedOffset = Math.round(offset / this.gutterStep) * this.gutterStep; if (steppedOffset === this.snapshot.lastSteppedOffset) { return; } this.snapshot.lastSteppedOffset = steppedOffset; // Need to know if each gutter side areas could reacts to steppedOffset /** @type {?} */ let areasBefore = getGutterSideAbsorptionCapacity(this.unit, this.snapshot.areasBeforeGutter, -steppedOffset, this.snapshot.allAreasSizePixel); /** @type {?} */ let areasAfter = getGutterSideAbsorptionCapacity(this.unit, this.snapshot.areasAfterGutter, steppedOffset, this.snapshot.allAreasSizePixel) // Each gutter side areas can't absorb all offset ; // Each gutter side areas can't absorb all offset if (areasBefore.remain !== 0 && areasAfter.remain !== 0) { if (Math.abs(areasBefore.remain) === Math.abs(areasAfter.remain)) { } else if (Math.abs(areasBefore.remain) > Math.abs(areasAfter.remain)) { areasAfter = getGutterSideAbsorptionCapacity(this.unit, this.snapshot.areasAfterGutter, steppedOffset + areasBefore.remain, this.snapshot.allAreasSizePixel); } else { areasBefore = getGutterSideAbsorptionCapacity(this.unit, this.snapshot.areasBeforeGutter, -(steppedOffset - areasAfter.remain), this.snapshot.allAreasSizePixel); } } // Areas before gutter can't absorbs all offset > need to recalculate sizes for areas after gutter. else if (areasBefore.remain !== 0) { areasAfter = getGutterSideAbsorptionCapacity(this.unit, this.snapshot.areasAfterGutter, steppedOffset + areasBefore.remain, this.snapshot.allAreasSizePixel); } // Areas after gutter can't absorbs all offset > need to recalculate sizes for areas before gutter. else if (areasAfter.remain !== 0) { areasBefore = getGutterSideAbsorptionCapacity(this.unit, this.snapshot.areasBeforeGutter, -(steppedOffset - areasAfter.remain), this.snapshot.allAreasSizePixel); } if (this.unit === 'percent') { // Hack because of browser messing up with sizes using calc(X% - Ypx) -> el.getBoundingClientRect() // If not there, playing with gutters makes total going down to 99.99875% then 99.99286%, 99.98986%,.. /** @type {?} */ const all = [...areasBefore.list, ...areasAfter.list]; /** @type {?} */ const areaToReset = all.find((/** * @param {?} a * @return {?} */ (a) => a.percentAfterAbsorption !== 0 && a.percentAfterAbsorption !== a.areaSnapshot.area.minSize && a.percentAfterAbsorption !== a.areaSnapshot.area.maxSize)); if (areaToReset) { areaToReset.percentAfterAbsorption = this.snapshot.allInvolvedAreasSizePercent - all.filter((/** * @param {?} a * @return {?} */ (a) => a !== areaToReset)).reduce((/** * @param {?} total * @param {?} a * @return {?} */ (total, a) => total + a.percentAfterAbsorption), 0); } } // Now we know areas could absorb steppedOffset, time to really update sizes areasBefore.list.forEach((/** * @param {?} item * @return {?} */ (item) => updateAreaSize(this.unit, item))); areasAfter.list.forEach((/** * @param {?} item * @return {?} */ (item) => updateAreaSize(this.unit, item))); this.refreshStyleSizes(); this.notify('progress', this.snapshot.gutterNum); } /** * @private * @param {?=} event * @return {?} */ stopDragging(event) { if (event) { event.preventDefault(); event.stopPropagation(); } if (this.isDragging === false) { return; } this.displayedAreas.forEach((/** * @param {?} area * @return {?} */ (area) => area.component.unlockEvents())); while (this.dragListeners.length > 0) { /** @type {?} */ const fct = this.dragListeners.pop(); if (fct) fct(); } // Warning: Have to be before "notify('end')" // because "notify('end')"" can be linked to "[size]='x'" > "build()" > "stopDragging()" this.isDragging = false; // If moved from starting point, notify end if (this.endPoint && (this.startPoint.x !== this.endPoint.x || this.startPoint.y !== this.endPoint.y)) { this.notify('end', this.snapshot.gutterNum); } this.renderer.removeClass(this.elRef.nativeElement, 'as-dragging'); this.renderer.removeClass(this.gutterEls.toArray()[this.snapshot.gutterNum - 1].nativeElement, 'as-dragged'); this.snapshot = null; this.isWaitingClear = true; // Needed to let (click)="clickGutter(...)" event run and verify if mouse moved or not this.ngZone.runOutsideAngular((/** * @return {?} */ () => { setTimeout((/** * @return {?} */ () => { this.startPoint = null; this.endPoint = null; this.isWaitingClear = false; })); })); } /** * @param {?} type * @param {?} gutterNum * @return {?} */ notify(type, gutterNum) { /** @type {?} */ const sizes = this.getVisibleAreaSizes(); if (type === 'start') { this.dragStart.emit({ gutterNum, sizes }); } else if (type === 'end') { this.dragEnd.emit({ gutterNum, sizes }); } else if (type === 'click') { this.gutterClick.emit({ gutterNum, sizes }); } else if (type === 'dblclick') { this.gutterDblClick.emit({ gutterNum, sizes }); } else if (type === 'transitionEnd') { if (this.transitionEndSubscriber) { this.ngZone.run((/** * @return {?} */ () => this.transitionEndSubscriber.next(sizes))); } } else if (type === 'progress') { // Stay outside zone to allow users do what they want about change detection mechanism. this.dragProgressSubject.next({ gutterNum, sizes }); } } /** * @return {?} */ ngOnDestroy() { this.stopDragging(); } } SplitComponent.decorators = [ { type: Component, args: [{ selector: 'as-split', exportAs: 'asSplit', changeDetection: ChangeDetectionStrategy.OnPush, template: ` <ng-content></ng-content> <ng-template ngFor [ngForOf]="displayedAreas" let-index="index" let-last="last"> <div *ngIf="last === false" #gutterEls class="as-split-gutter" [style.flex-basis.px]="gutterSize" [style.order]="index * 2 + 1" (mousedown)="startDragging($event, index * 2 + 1, index + 1)" (touchstart)="startDragging($event, index * 2 + 1, index + 1)" (mouseup)="clickGutter($event, index + 1)" (touchend)="clickGutter($event, index + 1)" > <div class="as-split-gutter-icon"></div> </div> </ng-template>`, encapsulation: ViewEncapsulation.Emulated, styles: [":host{display:flex;flex-wrap:nowrap;justify-content:flex-start;align-items:stretch;overflow:hidden;width:100%;height:100%}:host>.as-split-gutter{flex-grow:0;flex-shrink:0;background-color:#eee;display:flex;align-items:center;justify-content:center}:host>.as-split-gutter>.as-split-gutter-icon{width:100%;height:100%;background-position:center center;background-repeat:no-repeat}:host ::ng-deep>.as-split-area{flex-grow:0;flex-shrink:0;overflow-x:hidden;overflow-y:auto}:host ::ng-deep>.as-split-area.as-hidden{flex:0 1 0px!important;overflow-x:hidden;overflow-y:hidden}:host.as-horizontal{flex-direction:row}:host.as-horizontal>.as-split-gutter{flex-direction:row;cursor:col-resize;height:100%}:host.as-horizontal>.as-split-gutter>.as-split-gutter-icon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==)}:host.as-horizontal ::ng-deep>.as-split-area{height:100%}:host.as-vertical{flex-direction:column}:host.as-vertical>.as-split-gutter{flex-direction:column;cursor:row-resize;width:100%}:host.as-vertical>.as-split-gutter .as-split-gutter-icon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFCAMAAABl/6zIAAAABlBMVEUAAADMzMzIT8AyAAAAAXRSTlMAQObYZgAAABRJREFUeAFjYGRkwIMJSeMHlBkOABP7AEGzSuPKAAAAAElFTkSuQmCC)}:host.as-vertical ::ng-deep>.as-split-area{width:100%}:host.as-vertical ::ng-deep>.as-split-area.as-hidden{max-width:0}:host.as-disabled>.as-split-gutter{cursor:default}:host.as-disabled>.as-split-gutter .as-split-gutter-icon{background-image:url(\"\")}:host.as-transition.as-init:not(.as-dragging) ::ng-deep>.as-split-area,:host.as-transition.as-init:not(.as-dragging)>.as-split-gutter{transition:flex-basis .3s}"] }] } ]; /** @nocollapse */ SplitComponent.ctorParameters = () => [ { type: NgZone }, { type: ElementRef }, { type: ChangeDetectorRef }, { type: Renderer2 } ]; SplitComponent.propDecorators = { direction: [{ type: Input }], unit: [{ type: Input }], gutterSize: [{ type: Input }], gutterStep: [{ type: Input }], restrictMove: [{ type: Input }], useTransition: [{ type: Input }], disabled: [{ type: Input }], dir: [{ type: Input }], gutterDblClickDuration: [{ type: Input }], dragStart: [{ type: Output }], dragEnd: [{ type: Output }], gutterClick: [{ type: Output }], gutterDblClick: [{ type: Output }], transitionEnd: [{ type: Output }], gutterEls: [{ type: ViewChildren, args: ['gutterEls',] }] }; if (false) { /** * @type {?} * @private */ SplitComponent.prototype._direction; /** * @type {?} * @private */ SplitComponent.prototype._unit; /** * @type {?} * @private */ SplitComponent.prototype._gutterSize; /** * @type {?} * @private */ SplitComponent.prototype._gutterStep; /** * @type {?} * @private */ SplitComponent.prototype._restrictMove; /** * @type {?} * @private */ SplitComponent.prototype._useTransition; /** * @type {?} * @private */ SplitComponent.prototype._disabled; /** * @type {?} * @private */ SplitComponent.prototype._dir; /** * @type {?} * @private */ SplitComponent.prototype._gutterDblClickDuration; /** @type {?} */ SplitComponent.prototype.dragStart; /** @type {?} */ SplitComponent.prototype.dragEnd; /** @type {?} */ SplitComponent.prototype.gutterClick; /** @type {?} */ SplitComponent.prototype.gutterDblClick; /** * @type {?} * @private */ SplitComponent.prototype.transitionEndSubscriber; /** * @type {?} * @private */ SplitComponent.prototype.dragProgressSubject; /** @type {?} */ SplitComponent.prototype.dragProgress$; /** * @type {?} * @private */ SplitComponent.prototype.isDragging; /** * @type {?} * @private */ SplitComponent.prototype.isWaitingClear; /** * @type {?} * @private */ SplitComponent.prototype.dragListeners; /** * @type {?} * @private */ SplitComponent.prototype.snapshot; /** * @type {?} * @private */ SplitComponent.prototype.startPoint; /** * @type {?} * @private */ SplitComponent.prototype.endPoint; /** @type {?} */ SplitComponent.prototype.displayedAreas; /** * @type {?} * @private */ SplitComponent.prototype.hidedAreas; /** * @type {?} * @private */ SplitComponent.prototype.gutterEls; /** @type {?} */ SplitComponent.prototype._clickTimeout; /** * @type {?} * @private */ SplitComponent.prototype.ngZone; /** * @type {?} * @private */ SplitComponent.prototype.elRef; /** * @type {?} * @private */ SplitComponent.prototype.cdRef; /** * @type {?} * @private */ SplitComponent.prototype.renderer; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BsaXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQGRhdnZpZGVzcy9hbmd1bGFyLXNwbGl0LyIsInNvdXJjZXMiOlsibGliL2NvbXBvbmVudC9zcGxpdC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsS0FBSyxFQUNMLE1BQU0sRUFDTix1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFHVCxVQUFVLEVBQ1YsTUFBTSxFQUNOLFlBQVksRUFDWixTQUFTLEVBQ1QsWUFBWSxFQUNaLGlCQUFpQixHQUNsQixNQUFNLGVBQWUsQ0FBQTtBQUN0QixPQUFPLEVBQUUsVUFBVSxFQUFjLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQTtBQUN0RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUE7QUFJN0MsT0FBTyxFQUNMLHNCQUFzQixFQUN0QixlQUFlLEVBQ2YsZ0JBQWdCLEVBQ2hCLGNBQWMsRUFDZCxjQUFjLEVBQ2QsaUJBQWlCLEVBQ2pCLG1CQUFtQixFQUNuQiwrQkFBK0IsRUFDL0IsY0FBYyxHQUNmLE1BQU0sVUFBVSxDQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUF1RGpCLE1BQU0sT0FBTyxjQUFjOzs7Ozs7O0lBaUt6QixZQUNVLE1BQWMsRUFDZCxLQUFpQixFQUNqQixLQUF3QixFQUN4QixRQUFtQjtRQUhuQixXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQ2QsVUFBSyxHQUFMLEtBQUssQ0FBWTtRQUNqQixVQUFLLEdBQUwsS0FBSyxDQUFtQjtRQUN4QixhQUFRLEdBQVIsUUFBUSxDQUFXO1FBcEtyQixlQUFVLEdBQThCLFlBQVksQ0FBQTs7UUFvQnBELFVBQUssR0FBd0IsU0FBUyxDQUFBOztRQWlCdEMsZ0JBQVcsR0FBVyxFQUFFLENBQUE7O1FBY3hCLGdCQUFXLEdBQVcsQ0FBQyxDQUFBOztRQVl2QixrQkFBYSxHQUFZLEtBQUss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