Skip to content

Commit 02abfd5

Browse files
committed
refactor(collapse): input signals, host bindings
1 parent 9cbd0e3 commit 02abfd5

File tree

3 files changed

+38
-38
lines changed

3 files changed

+38
-38
lines changed

projects/coreui-angular/src/lib/collapse/collapse.directive.spec.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ class MockElementRef extends ElementRef {}
1515
class TestComponent {}
1616

1717
describe('CollapseDirective', () => {
18-
1918
let component: TestComponent;
2019
let fixture: ComponentFixture<TestComponent>;
2120
let elementRef: DebugElement;
@@ -25,11 +24,7 @@ describe('CollapseDirective', () => {
2524
beforeEach(() => {
2625
TestBed.configureTestingModule({
2726
imports: [TestComponent, CollapseDirective, NoopAnimationsModule],
28-
providers: [
29-
{ provide: ElementRef, useClass: MockElementRef },
30-
{ provide: AnimationBuilder },
31-
Renderer2
32-
]
27+
providers: [{ provide: ElementRef, useClass: MockElementRef }, { provide: AnimationBuilder }, Renderer2]
3328
});
3429

3530
fixture = TestBed.createComponent(TestComponent);
@@ -41,12 +36,13 @@ describe('CollapseDirective', () => {
4136
});
4237

4338
it('should create an instance', () => {
44-
const directive = new CollapseDirective(elementRef, renderer, animationBuilder);
45-
expect(directive).toBeTruthy();
39+
TestBed.runInInjectionContext(() => {
40+
const directive = new CollapseDirective(elementRef, renderer, animationBuilder);
41+
expect(directive).toBeTruthy();
42+
});
4643
});
4744

4845
it('should have css classes', () => {
4946
expect(elementRef.nativeElement).toHaveClass('collapse-horizontal');
5047
});
51-
5248
});

projects/coreui-angular/src/lib/collapse/collapse.directive.ts

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import {
22
AfterViewInit,
33
booleanAttribute,
4+
computed,
45
Directive,
56
DoCheck,
67
ElementRef,
7-
EventEmitter,
8-
HostBinding,
98
Input,
9+
input,
1010
OnChanges,
1111
OnDestroy,
12-
Output,
12+
output,
1313
Renderer2,
1414
SimpleChanges
1515
} from '@angular/core';
@@ -26,11 +26,13 @@ import {
2626
@Directive({
2727
selector: '[cCollapse]',
2828
exportAs: 'cCollapse',
29-
standalone: true
29+
standalone: true,
30+
host: { '[class]': 'hostClasses()' }
3031
})
31-
export class CollapseDirective implements OnChanges, OnDestroy, DoCheck, AfterViewInit {
32+
export class CollapseDirective implements OnDestroy, AfterViewInit, DoCheck, OnChanges {
3233
/**
3334
* @ignore
35+
* todo: 'animate' input signal for navbar
3436
*/
3537
@Input({ transform: booleanAttribute }) animate: boolean = true;
3638

@@ -39,12 +41,13 @@ export class CollapseDirective implements OnChanges, OnDestroy, DoCheck, AfterVi
3941
* @type boolean
4042
* @default false
4143
*/
42-
@Input({ transform: booleanAttribute }) horizontal: boolean = false;
44+
readonly horizontal = input(false, { transform: booleanAttribute });
4345

4446
/**
4547
* Toggle the visibility of collapsible element.
4648
* @type boolean
4749
* @default false
50+
* todo: 'visible' input signal
4851
*/
4952
@Input({ transform: booleanAttribute })
5053
set visible(value) {
@@ -62,21 +65,23 @@ export class CollapseDirective implements OnChanges, OnDestroy, DoCheck, AfterVi
6265
* @type boolean
6366
* @default false
6467
*/
65-
@Input({ transform: booleanAttribute }) navbar: boolean = false;
68+
readonly navbar = input(false, { transform: booleanAttribute });
6669

6770
/**
6871
* @ignore
6972
*/
70-
@Input() duration = '350ms';
73+
readonly duration = input('350ms');
74+
7175
/**
7276
* @ignore
7377
*/
74-
@Input() transition = 'ease';
78+
readonly transition = input('ease');
79+
7580
/**
7681
* Event emitted on visibility change. [docs]
7782
* @type string
7883
*/
79-
@Output() collapseChange = new EventEmitter<string>();
84+
readonly collapseChange = output<string>();
8085

8186
private player!: AnimationPlayer;
8287
private readonly host: HTMLElement;
@@ -85,21 +90,20 @@ export class CollapseDirective implements OnChanges, OnDestroy, DoCheck, AfterVi
8590
private collapsing: boolean = false;
8691

8792
constructor(
88-
private hostElement: ElementRef,
89-
private renderer: Renderer2,
90-
private animationBuilder: AnimationBuilder
93+
private readonly hostElement: ElementRef,
94+
private readonly renderer: Renderer2,
95+
private readonly animationBuilder: AnimationBuilder
9196
) {
9297
this.host = this.hostElement.nativeElement;
9398
this.renderer.setStyle(this.host, 'display', 'none');
9499
}
95100

96-
@HostBinding('class')
97-
get hostClasses(): any {
101+
readonly hostClasses = computed(() => {
98102
return {
99-
'navbar-collapse': this.navbar,
100-
'collapse-horizontal': this.horizontal
101-
};
102-
}
103+
'navbar-collapse': this.navbar(),
104+
'collapse-horizontal': this.horizontal()
105+
} as Record<string, boolean>;
106+
});
103107

104108
ngAfterViewInit(): void {
105109
if (this.visible) {
@@ -143,17 +147,17 @@ export class CollapseDirective implements OnChanges, OnDestroy, DoCheck, AfterVi
143147
this.renderer.removeStyle(this.host, 'display');
144148
}
145149

146-
const duration = this.animate ? this.duration : '0ms';
150+
const duration = this.animate ? this.duration() : '0ms';
147151

148-
const expand = this.horizontal ? expandHorizontalAnimation : expandAnimation;
149-
const collapse = this.horizontal ? collapseHorizontalAnimation : collapseAnimation;
152+
const expand = this.horizontal() ? expandHorizontalAnimation : expandAnimation;
153+
const collapse = this.horizontal() ? collapseHorizontalAnimation : collapseAnimation;
150154

151-
const dimension = this.horizontal ? 'width' : 'height';
155+
const dimension = this.horizontal() ? 'width' : 'height';
152156
const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);
153157
const scrollSize = `scroll${capitalizedDimension}`;
154158

155-
const animationFactory = this.animationBuilder.build(
156-
useAnimation(visible ? expand : collapse, { params: { time: duration, easing: this.transition } })
159+
const animationFactory = this.animationBuilder?.build(
160+
useAnimation(visible ? expand : collapse, { params: { time: duration, easing: this.transition() } })
157161
);
158162

159163
this.player = animationFactory.create(this.host);
@@ -169,8 +173,7 @@ export class CollapseDirective implements OnChanges, OnDestroy, DoCheck, AfterVi
169173
this.renderer.removeClass(this.host, 'show');
170174
this.collapsing = true;
171175
if (visible) {
172-
// @ts-ignore
173-
this.renderer.setStyle(this.host, dimension, `${this.host[scrollSize]}px`);
176+
this.renderer.setStyle(this.host, dimension, `${this.hostElement.nativeElement[scrollSize]}px`);
174177
} else {
175178
this.renderer.setStyle(this.host, dimension, '');
176179
}
@@ -193,7 +196,7 @@ export class CollapseDirective implements OnChanges, OnDestroy, DoCheck, AfterVi
193196

194197
setMaxSize() {
195198
// setTimeout(() => {
196-
if (this.horizontal) {
199+
if (this.horizontal()) {
197200
this.scrollWidth = this.host.scrollWidth;
198201
this.scrollWidth > 0 && this.renderer.setStyle(this.host, 'maxWidth', `${this.scrollWidth}px`);
199202
// } else {

projects/coreui-angular/src/lib/navbar/navbar.component.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,9 @@ export class NavbarComponent implements AfterContentInit {
7777
this.breakpointObserver.observe([onBreakpoint]).subscribe((result) => {
7878
if (this.collapse) {
7979
const animate = this.collapse.animate;
80-
this.collapse.toggle(false);
80+
// todo: collapse animate input signal setter
8181
this.collapse.animate = false;
82+
this.collapse.toggle(false);
8283
setTimeout(() => {
8384
this.collapse.toggle(result.matches);
8485
setTimeout(() => {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy