UNPKG

5.88 kBJavaScriptView Raw
1import { AnimationBuilder } from '@angular/animations';
2import { Directive, ElementRef, EventEmitter, HostBinding, Input, Output, Renderer2 } from '@angular/core';
3import { collapseAnimation, expandAnimation } from './collapse-animations';
4export class CollapseDirective {
5 constructor(_el, _renderer, _builder) {
6 this._el = _el;
7 this._renderer = _renderer;
8 /** This event fires as soon as content collapses */
9 this.collapsed = new EventEmitter();
10 /** This event fires when collapsing is started */
11 this.collapses = new EventEmitter();
12 /** This event fires as soon as content becomes visible */
13 this.expanded = new EventEmitter();
14 /** This event fires when expansion is started */
15 this.expands = new EventEmitter();
16 // shown
17 this.isExpanded = true;
18 this.collapseNewValue = true;
19 // hidden
20 this.isCollapsed = false;
21 // stale state
22 this.isCollapse = true;
23 // animation state
24 this.isCollapsing = false;
25 /** turn on/off animation */
26 this.isAnimated = false;
27 this._display = 'block';
28 this._stylesLoaded = false;
29 this._COLLAPSE_ACTION_NAME = 'collapse';
30 this._EXPAND_ACTION_NAME = 'expand';
31 this._factoryCollapseAnimation = _builder.build(collapseAnimation);
32 this._factoryExpandAnimation = _builder.build(expandAnimation);
33 }
34 set display(value) {
35 if (!this.isAnimated) {
36 this._renderer.setStyle(this._el.nativeElement, 'display', value);
37 return;
38 }
39 this._display = value;
40 if (value === 'none') {
41 this.hide();
42 return;
43 }
44 this.show();
45 }
46 /** A flag indicating visibility of content (shown or hidden) */
47 set collapse(value) {
48 this.collapseNewValue = value;
49 if (!this._player || this._isAnimationDone) {
50 this.isExpanded = value;
51 this.toggle();
52 }
53 }
54 get collapse() {
55 return this.isExpanded;
56 }
57 ngAfterViewChecked() {
58 this._stylesLoaded = true;
59 if (!this._player || !this._isAnimationDone) {
60 return;
61 }
62 this._player.reset();
63 this._renderer.setStyle(this._el.nativeElement, 'height', '*');
64 }
65 /** allows to manually toggle content visibility */
66 toggle() {
67 if (this.isExpanded) {
68 this.hide();
69 }
70 else {
71 this.show();
72 }
73 }
74 /** allows to manually hide content */
75 hide() {
76 this.isCollapsing = true;
77 this.isExpanded = false;
78 this.isCollapsed = true;
79 this.isCollapsing = false;
80 this.collapses.emit(this);
81 this._isAnimationDone = false;
82 this.animationRun(this.isAnimated, this._COLLAPSE_ACTION_NAME)(() => {
83 this._isAnimationDone = true;
84 if (this.collapseNewValue !== this.isCollapsed && this.isAnimated) {
85 this.show();
86 return;
87 }
88 this.collapsed.emit(this);
89 this._renderer.setStyle(this._el.nativeElement, 'display', 'none');
90 });
91 }
92 /** allows to manually show collapsed content */
93 show() {
94 this._renderer.setStyle(this._el.nativeElement, 'display', this._display);
95 this.isCollapsing = true;
96 this.isExpanded = true;
97 this.isCollapsed = false;
98 this.isCollapsing = false;
99 this.expands.emit(this);
100 this._isAnimationDone = false;
101 this.animationRun(this.isAnimated, this._EXPAND_ACTION_NAME)(() => {
102 this._isAnimationDone = true;
103 if (this.collapseNewValue !== this.isCollapsed && this.isAnimated) {
104 this.hide();
105 return;
106 }
107 this.expanded.emit(this);
108 this._renderer.removeStyle(this._el.nativeElement, 'overflow');
109 });
110 }
111 animationRun(isAnimated, action) {
112 if (!isAnimated || !this._stylesLoaded) {
113 return (callback) => callback();
114 }
115 this._renderer.setStyle(this._el.nativeElement, 'overflow', 'hidden');
116 this._renderer.addClass(this._el.nativeElement, 'collapse');
117 const factoryAnimation = (action === this._EXPAND_ACTION_NAME)
118 ? this._factoryExpandAnimation
119 : this._factoryCollapseAnimation;
120 if (this._player) {
121 this._player.destroy();
122 }
123 this._player = factoryAnimation.create(this._el.nativeElement);
124 this._player.play();
125 return (callback) => { var _a; return (_a = this._player) === null || _a === void 0 ? void 0 : _a.onDone(callback); };
126 }
127}
128CollapseDirective.decorators = [
129 { type: Directive, args: [{
130 selector: '[collapse]',
131 exportAs: 'bs-collapse',
132 // eslint-disable-next-line @angular-eslint/no-host-metadata-property
133 host: {
134 '[class.collapse]': 'true'
135 }
136 },] }
137];
138CollapseDirective.ctorParameters = () => [
139 { type: ElementRef },
140 { type: Renderer2 },
141 { type: AnimationBuilder }
142];
143CollapseDirective.propDecorators = {
144 collapsed: [{ type: Output }],
145 collapses: [{ type: Output }],
146 expanded: [{ type: Output }],
147 expands: [{ type: Output }],
148 isExpanded: [{ type: HostBinding, args: ['class.in',] }, { type: HostBinding, args: ['class.show',] }, { type: HostBinding, args: ['attr.aria-expanded',] }],
149 isCollapsed: [{ type: HostBinding, args: ['attr.aria-hidden',] }],
150 isCollapse: [{ type: HostBinding, args: ['class.collapse',] }],
151 isCollapsing: [{ type: HostBinding, args: ['class.collapsing',] }],
152 display: [{ type: Input }],
153 isAnimated: [{ type: Input }],
154 collapse: [{ type: Input }]
155};
156//# sourceMappingURL=collapse.directive.js.map
\No newline at end of file