UNPKG

@odymaui/angular-tree-component

Version:

A simple yet powerful tree component for Angular16. WARNING: This is an unsupported fork for use in a dependent project to upgrade it to Angular 16. Unit tests pass and the example-app works as expected.

109 lines 13.6 kB
import { Directive, Input } from '@angular/core'; import * as i0 from "@angular/core"; const EASE_ACCELERATION = 1.005; export class TreeAnimateOpenDirective { renderer; templateRef; viewContainerRef; _isOpen; animateSpeed; animateAcceleration; isEnabled; set isOpen(value) { if (value) { this._show(); if (this.isEnabled && this._isOpen === false) { this._animateOpen(); } } else { this.isEnabled ? this._animateClose() : this._hide(); } this._isOpen = !!value; } ; innerElement; constructor(renderer, templateRef, viewContainerRef) { this.renderer = renderer; this.templateRef = templateRef; this.viewContainerRef = viewContainerRef; } _show() { if (this.innerElement) return; // create child view this.innerElement = this.viewContainerRef.createEmbeddedView(this.templateRef).rootNodes[0]; } _hide() { this.viewContainerRef.clear(); this.innerElement = null; } _animateOpen() { let delta = this.animateSpeed; let ease = this.animateAcceleration; let maxHeight = 0; // set height to 0 this.renderer.setStyle(this.innerElement, 'max-height', `0`); // increase maxHeight until height doesn't change setTimeout(() => { const i = setInterval(() => { if (!this._isOpen || !this.innerElement) return clearInterval(i); maxHeight += delta; const roundedMaxHeight = Math.round(maxHeight); this.renderer.setStyle(this.innerElement, 'max-height', `${roundedMaxHeight}px`); const height = this.innerElement.getBoundingClientRect ? this.innerElement.getBoundingClientRect().height : 0; // TBD use renderer delta *= ease; ease *= EASE_ACCELERATION; if (height < roundedMaxHeight) { // Make maxHeight auto because animation finished and container might change height later on this.renderer.setStyle(this.innerElement, 'max-height', null); clearInterval(i); } }, 17); }); } _animateClose() { if (!this.innerElement) return; let delta = this.animateSpeed; let ease = this.animateAcceleration; let height = this.innerElement.getBoundingClientRect().height; // TBD use renderer // slowly decrease maxHeight to 0, starting from current height const i = setInterval(() => { if (this._isOpen || !this.innerElement) return clearInterval(i); height -= delta; this.renderer.setStyle(this.innerElement, 'max-height', `${height}px`); delta *= ease; ease *= EASE_ACCELERATION; if (height <= 0) { // after animation complete - remove child element this.viewContainerRef.clear(); this.innerElement = null; clearInterval(i); } }, 17); } /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: TreeAnimateOpenDirective, deps: [{ token: i0.Renderer2 }, { token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive }); /** @nocollapse */ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.2", type: TreeAnimateOpenDirective, selector: "[treeAnimateOpen]", inputs: { animateSpeed: ["treeAnimateOpenSpeed", "animateSpeed"], animateAcceleration: ["treeAnimateOpenAcceleration", "animateAcceleration"], isEnabled: ["treeAnimateOpenEnabled", "isEnabled"], isOpen: ["treeAnimateOpen", "isOpen"] }, ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: TreeAnimateOpenDirective, decorators: [{ type: Directive, args: [{ selector: '[treeAnimateOpen]' }] }], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i0.TemplateRef }, { type: i0.ViewContainerRef }]; }, propDecorators: { animateSpeed: [{ type: Input, args: ['treeAnimateOpenSpeed'] }], animateAcceleration: [{ type: Input, args: ['treeAnimateOpenAcceleration'] }], isEnabled: [{ type: Input, args: ['treeAnimateOpenEnabled'] }], isOpen: [{ type: Input, args: ['treeAnimateOpen'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS1hbmltYXRlLW9wZW4uZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci10cmVlLWNvbXBvbmVudC9zcmMvbGliL2RpcmVjdGl2ZXMvdHJlZS1hbmltYXRlLW9wZW4uZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUE0QyxNQUFNLGVBQWUsQ0FBQzs7QUFFM0YsTUFBTSxpQkFBaUIsR0FBRyxLQUFLLENBQUM7QUFLaEMsTUFBTSxPQUFPLHdCQUF3QjtJQXVCekI7SUFDQTtJQUNBO0lBeEJGLE9BQU8sQ0FBVTtJQUVNLFlBQVksQ0FBUztJQUNkLG1CQUFtQixDQUFTO0lBQ2pDLFNBQVMsQ0FBVTtJQUVwRCxJQUNJLE1BQU0sQ0FBQyxLQUFjO1FBQ3ZCLElBQUksS0FBSyxFQUFFO1lBQ1QsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2IsSUFBSSxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxPQUFPLEtBQUssS0FBSyxFQUFFO2dCQUM1QyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7YUFDckI7U0FDRjthQUFNO1lBQ0wsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7U0FDdEQ7UUFDRCxJQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUM7SUFDekIsQ0FBQztJQUFBLENBQUM7SUFFTSxZQUFZLENBQU07SUFFMUIsWUFDVSxRQUFtQixFQUNuQixXQUE2QixFQUM3QixnQkFBa0M7UUFGbEMsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQUNuQixnQkFBVyxHQUFYLFdBQVcsQ0FBa0I7UUFDN0IscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtJQUM1QyxDQUFDO0lBRU8sS0FBSztRQUNYLElBQUksSUFBSSxDQUFDLFlBQVk7WUFBRSxPQUFPO1FBRTlCLG9CQUFvQjtRQUNwQixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzlGLENBQUM7SUFFTyxLQUFLO1FBQ1gsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO0lBQzNCLENBQUM7SUFFTyxZQUFZO1FBQ2xCLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7UUFDOUIsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDO1FBQ3BDLElBQUksU0FBUyxHQUFHLENBQUMsQ0FBQztRQUVsQixrQkFBa0I7UUFDbEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxZQUFZLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFFN0QsaURBQWlEO1FBQ2pELFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxNQUFNLENBQUMsR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFO2dCQUN6QixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZO29CQUFFLE9BQU8sYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUVqRSxTQUFTLElBQUksS0FBSyxDQUFDO2dCQUNuQixNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7Z0JBRS9DLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsWUFBWSxFQUFFLEdBQUcsZ0JBQWdCLElBQUksQ0FBQyxDQUFDO2dCQUNqRixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLHFCQUFxQixFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxtQkFBbUI7Z0JBRWxJLEtBQUssSUFBSSxJQUFJLENBQUM7Z0JBQ2QsSUFBSSxJQUFJLGlCQUFpQixDQUFDO2dCQUMxQixJQUFJLE1BQU0sR0FBRyxnQkFBZ0IsRUFBRTtvQkFDN0IsNEZBQTRGO29CQUM1RixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLFlBQVksRUFBRSxJQUFJLENBQUMsQ0FBQztvQkFDOUQsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO2lCQUNsQjtZQUNILENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNULENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLGFBQWE7UUFDbkIsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZO1lBQUUsT0FBTztRQUUvQixJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO1FBQzlCLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztRQUNwQyxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLHFCQUFxQixFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsbUJBQW1CO1FBRWxGLCtEQUErRDtRQUMvRCxNQUFNLENBQUMsR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFO1lBQ3pCLElBQUksSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZO2dCQUFFLE9BQU8sYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRWhFLE1BQU0sSUFBSSxLQUFLLENBQUM7WUFDaEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxZQUFZLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDO1lBQ3ZFLEtBQUssSUFBSSxJQUFJLENBQUM7WUFDZCxJQUFJLElBQUksaUJBQWlCLENBQUM7WUFFMUIsSUFBSSxNQUFNLElBQUksQ0FBQyxFQUFFO2dCQUNmLGtEQUFrRDtnQkFDbEQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUM5QixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztnQkFDekIsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ2xCO1FBQ0gsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ1QsQ0FBQzswSEE3RlUsd0JBQXdCOzhHQUF4Qix3QkFBd0I7OzJGQUF4Qix3QkFBd0I7a0JBSHBDLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLG1CQUFtQjtpQkFDOUI7eUpBSWdDLFlBQVk7c0JBQTFDLEtBQUs7dUJBQUMsc0JBQXNCO2dCQUNTLG1CQUFtQjtzQkFBeEQsS0FBSzt1QkFBQyw2QkFBNkI7Z0JBQ0gsU0FBUztzQkFBekMsS0FBSzt1QkFBQyx3QkFBd0I7Z0JBRzNCLE1BQU07c0JBRFQsS0FBSzt1QkFBQyxpQkFBaUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEaXJlY3RpdmUsIElucHV0LCBSZW5kZXJlcjIsIFRlbXBsYXRlUmVmLCBWaWV3Q29udGFpbmVyUmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcblxyXG5jb25zdCBFQVNFX0FDQ0VMRVJBVElPTiA9IDEuMDA1O1xyXG5cclxuQERpcmVjdGl2ZSh7XHJcbiAgc2VsZWN0b3I6ICdbdHJlZUFuaW1hdGVPcGVuXSdcclxufSlcclxuZXhwb3J0IGNsYXNzIFRyZWVBbmltYXRlT3BlbkRpcmVjdGl2ZSB7XHJcbiAgcHJpdmF0ZSBfaXNPcGVuOiBib29sZWFuO1xyXG5cclxuICBASW5wdXQoJ3RyZWVBbmltYXRlT3BlblNwZWVkJykgYW5pbWF0ZVNwZWVkOiBudW1iZXI7XHJcbiAgQElucHV0KCd0cmVlQW5pbWF0ZU9wZW5BY2NlbGVyYXRpb24nKSBhbmltYXRlQWNjZWxlcmF0aW9uOiBudW1iZXI7XHJcbiAgQElucHV0KCd0cmVlQW5pbWF0ZU9wZW5FbmFibGVkJykgaXNFbmFibGVkOiBib29sZWFuO1xyXG5cclxuICBASW5wdXQoJ3RyZWVBbmltYXRlT3BlbicpXHJcbiAgc2V0IGlzT3Blbih2YWx1ZTogYm9vbGVhbikge1xyXG4gICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgIHRoaXMuX3Nob3coKTtcclxuICAgICAgaWYgKHRoaXMuaXNFbmFibGVkICYmIHRoaXMuX2lzT3BlbiA9PT0gZmFsc2UpIHtcclxuICAgICAgICB0aGlzLl9hbmltYXRlT3BlbigpO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmlzRW5hYmxlZCA/IHRoaXMuX2FuaW1hdGVDbG9zZSgpIDogdGhpcy5faGlkZSgpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5faXNPcGVuID0gISF2YWx1ZTtcclxuICB9O1xyXG5cclxuICBwcml2YXRlIGlubmVyRWxlbWVudDogYW55O1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMixcclxuICAgIHByaXZhdGUgdGVtcGxhdGVSZWY6IFRlbXBsYXRlUmVmPGFueT4sXHJcbiAgICBwcml2YXRlIHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYpIHtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX3Nob3coKSB7XHJcbiAgICBpZiAodGhpcy5pbm5lckVsZW1lbnQpIHJldHVybjtcclxuXHJcbiAgICAvLyBjcmVhdGUgY2hpbGQgdmlld1xyXG4gICAgdGhpcy5pbm5lckVsZW1lbnQgPSB0aGlzLnZpZXdDb250YWluZXJSZWYuY3JlYXRlRW1iZWRkZWRWaWV3KHRoaXMudGVtcGxhdGVSZWYpLnJvb3ROb2Rlc1swXTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2hpZGUoKSB7XHJcbiAgICB0aGlzLnZpZXdDb250YWluZXJSZWYuY2xlYXIoKTtcclxuICAgIHRoaXMuaW5uZXJFbGVtZW50ID0gbnVsbDtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2FuaW1hdGVPcGVuKCkge1xyXG4gICAgbGV0IGRlbHRhID0gdGhpcy5hbmltYXRlU3BlZWQ7XHJcbiAgICBsZXQgZWFzZSA9IHRoaXMuYW5pbWF0ZUFjY2VsZXJhdGlvbjtcclxuICAgIGxldCBtYXhIZWlnaHQgPSAwO1xyXG5cclxuICAgIC8vIHNldCBoZWlnaHQgdG8gMFxyXG4gICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmlubmVyRWxlbWVudCwgJ21heC1oZWlnaHQnLCBgMGApO1xyXG5cclxuICAgIC8vIGluY3JlYXNlIG1heEhlaWdodCB1bnRpbCBoZWlnaHQgZG9lc24ndCBjaGFuZ2VcclxuICAgIHNldFRpbWVvdXQoKCkgPT4geyAvLyBBbGxvdyBpbm5lciBlbGVtZW50IHRvIGNyZWF0ZSBpdHMgY29udGVudFxyXG4gICAgICBjb25zdCBpID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xyXG4gICAgICAgIGlmICghdGhpcy5faXNPcGVuIHx8ICF0aGlzLmlubmVyRWxlbWVudCkgcmV0dXJuIGNsZWFySW50ZXJ2YWwoaSk7XHJcblxyXG4gICAgICAgIG1heEhlaWdodCArPSBkZWx0YTtcclxuICAgICAgICBjb25zdCByb3VuZGVkTWF4SGVpZ2h0ID0gTWF0aC5yb3VuZChtYXhIZWlnaHQpO1xyXG5cclxuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuaW5uZXJFbGVtZW50LCAnbWF4LWhlaWdodCcsIGAke3JvdW5kZWRNYXhIZWlnaHR9cHhgKTtcclxuICAgICAgICBjb25zdCBoZWlnaHQgPSB0aGlzLmlubmVyRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QgPyB0aGlzLmlubmVyRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHQgOiAwOyAvLyBUQkQgdXNlIHJlbmRlcmVyXHJcblxyXG4gICAgICAgIGRlbHRhICo9IGVhc2U7XHJcbiAgICAgICAgZWFzZSAqPSBFQVNFX0FDQ0VMRVJBVElPTjtcclxuICAgICAgICBpZiAoaGVpZ2h0IDwgcm91bmRlZE1heEhlaWdodCkge1xyXG4gICAgICAgICAgLy8gTWFrZSBtYXhIZWlnaHQgYXV0byBiZWNhdXNlIGFuaW1hdGlvbiBmaW5pc2hlZCBhbmQgY29udGFpbmVyIG1pZ2h0IGNoYW5nZSBoZWlnaHQgbGF0ZXIgb25cclxuICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5pbm5lckVsZW1lbnQsICdtYXgtaGVpZ2h0JywgbnVsbCk7XHJcbiAgICAgICAgICBjbGVhckludGVydmFsKGkpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSwgMTcpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9hbmltYXRlQ2xvc2UoKSB7XHJcbiAgICBpZiAoIXRoaXMuaW5uZXJFbGVtZW50KSByZXR1cm47XHJcblxyXG4gICAgbGV0IGRlbHRhID0gdGhpcy5hbmltYXRlU3BlZWQ7XHJcbiAgICBsZXQgZWFzZSA9IHRoaXMuYW5pbWF0ZUFjY2VsZXJhdGlvbjtcclxuICAgIGxldCBoZWlnaHQgPSB0aGlzLmlubmVyRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHQ7IC8vIFRCRCB1c2UgcmVuZGVyZXJcclxuXHJcbiAgICAvLyBzbG93bHkgZGVjcmVhc2UgbWF4SGVpZ2h0IHRvIDAsIHN0YXJ0aW5nIGZyb20gY3VycmVudCBoZWlnaHRcclxuICAgIGNvbnN0IGkgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XHJcbiAgICAgIGlmICh0aGlzLl9pc09wZW4gfHwgIXRoaXMuaW5uZXJFbGVtZW50KSByZXR1cm4gY2xlYXJJbnRlcnZhbChpKTtcclxuXHJcbiAgICAgIGhlaWdodCAtPSBkZWx0YTtcclxuICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmlubmVyRWxlbWVudCwgJ21heC1oZWlnaHQnLCBgJHtoZWlnaHR9cHhgKTtcclxuICAgICAgZGVsdGEgKj0gZWFzZTtcclxuICAgICAgZWFzZSAqPSBFQVNFX0FDQ0VMRVJBVElPTjtcclxuXHJcbiAgICAgIGlmIChoZWlnaHQgPD0gMCkge1xyXG4gICAgICAgIC8vIGFmdGVyIGFuaW1hdGlvbiBjb21wbGV0ZSAtIHJlbW92ZSBjaGlsZCBlbGVtZW50XHJcbiAgICAgICAgdGhpcy52aWV3Q29udGFpbmVyUmVmLmNsZWFyKCk7XHJcbiAgICAgICAgdGhpcy5pbm5lckVsZW1lbnQgPSBudWxsO1xyXG4gICAgICAgIGNsZWFySW50ZXJ2YWwoaSk7XHJcbiAgICAgIH1cclxuICAgIH0sIDE3KTtcclxuICB9XHJcbn1cclxuIl19