Skip to content

Commit 0b26a53

Browse files
feat: convert components to use OnPush change detection strategy (#3094)
Signed-off-by: rrothschild18 <raultonello18@gmail.com> Co-authored-by: Akshat Patel <38994122+Akshat55@users.noreply.github.com>
1 parent b2368b7 commit 0b26a53

File tree

9 files changed

+63
-44
lines changed

9 files changed

+63
-44
lines changed

src/accordion/accordion-item.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ import {
4848
display: list-item;
4949
}
5050
`],
51-
changeDetection: ChangeDetectionStrategy.OnPush
51+
changeDetection: ChangeDetectionStrategy.OnPush
5252
})
5353
export class AccordionItem {
5454
static accordionItemCount = 0;

src/breadcrumb/breadcrumb-item.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import { Router } from "@angular/router";
2929
<ng-container *ngTemplateOutlet="content" />
3030
}
3131
`,
32-
changeDetection: ChangeDetectionStrategy.OnPush
32+
changeDetection: ChangeDetectionStrategy.OnPush
3333
})
3434
export class BreadcrumbItemComponent {
3535
@Input() set href(v: string) {

src/breadcrumb/breadcrumb.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ const MINIMUM_OVERFLOW_THRESHOLD = 4;
123123
}
124124
</nav>
125125
`,
126-
changeDetection: ChangeDetectionStrategy.OnPush
126+
changeDetection: ChangeDetectionStrategy.OnPush
127127
})
128128
export class Breadcrumb implements AfterContentInit {
129129
@ContentChildren(BreadcrumbItemComponent) children: QueryList<BreadcrumbItemComponent>;

src/loading/loading.component.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { Component, Input, HostBinding } from "@angular/core";
1+
import {
2+
ChangeDetectionStrategy,
3+
Component,
4+
HostBinding,
5+
Input
6+
} from "@angular/core";
27
import { I18n } from "carbon-components-angular/i18n";
38

49
/**
@@ -25,7 +30,8 @@ import { I18n } from "carbon-components-angular/i18n";
2530
<circle class="cds--loading__stroke" cx="50%" cy="50%" r="44" />
2631
</svg>
2732
</div>
28-
`
33+
`,
34+
changeDetection: ChangeDetectionStrategy.OnPush
2935
})
3036
export class Loading {
3137
/**

src/number-input/number.component.spec.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { ComponentFixture, TestBed } from "@angular/core/testing";
22
import { By } from "@angular/platform-browser";
33

4-
import { Number } from "./number.component";
54
import { FormsModule } from "@angular/forms";
65
import { I18nModule } from "../i18n/index";
76
import { IconModule } from "../icon/index";
7+
import { Number } from "./number.component";
88

99
describe("Number", () => {
1010
let component: Number;
@@ -71,13 +71,13 @@ describe("Number", () => {
7171
});
7272

7373
it("should bind input label", () => {
74-
component.label = "Number Input";
74+
fixture.componentRef.setInput("label", "Number Input");
7575
fixture.detectChanges();
7676
labelElement = fixture.debugElement.query(By.css(".cds--label")).nativeElement;
7777
expect(labelElement.innerHTML.includes("Number Input")).toEqual(true);
7878
expect(containerElement.className.includes("cds--number--nolabel")).toEqual(false);
7979

80-
component.label = null;
80+
fixture.componentRef.setInput("label", null);
8181
fixture.detectChanges();
8282
expect(fixture.debugElement.query(By.css(".cds--label"))).toBeNull();
8383
expect(containerElement.className.includes("cds--number--nolabel")).toEqual(true);
@@ -186,10 +186,10 @@ describe("Number", () => {
186186
});
187187

188188
it("should have dark and light theme", () => {
189-
component.theme = "dark";
189+
fixture.componentRef.setInput("theme", "dark");
190190
fixture.detectChanges();
191191
expect(containerElement.className.includes("cds--number--light")).toEqual(false);
192-
component.theme = "light";
192+
fixture.componentRef.setInput("theme", "light");
193193
fixture.detectChanges();
194194
expect(containerElement.className.includes("cds--number--light")).toEqual(true);
195195
});

src/number-input/number.component.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import {
2+
ChangeDetectionStrategy,
23
Component,
3-
Input,
4-
HostBinding,
54
EventEmitter,
5+
HostBinding,
6+
HostListener,
7+
Input,
68
Output,
7-
TemplateRef,
8-
HostListener
9+
TemplateRef
910
} from "@angular/core";
1011
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
1112

@@ -167,7 +168,8 @@ export class NumberChange {
167168
useExisting: NumberComponent,
168169
multi: true
169170
}
170-
]
171+
],
172+
changeDetection: ChangeDetectionStrategy.OnPush
171173
})
172174
export class NumberComponent implements ControlValueAccessor {
173175
/**

src/progress-indicator/progress-indicator.component.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import {
2+
ChangeDetectionStrategy,
23
Component,
4+
EventEmitter,
35
Input,
4-
Output,
5-
EventEmitter
6+
Output
67
} from "@angular/core";
78
import { I18n } from "carbon-components-angular/i18n";
89
import { Step } from "./progress-indicator-step.interface";
@@ -72,7 +73,8 @@ import { Step } from "./progress-indicator-step.interface";
7273
</li>
7374
}
7475
</ul>
75-
`
76+
`,
77+
changeDetection: ChangeDetectionStrategy.OnPush
7678
})
7779
export class ProgressIndicator {
7880
@Input() get current() {

src/search/search.component.spec.ts

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing";
22
import { By } from "@angular/platform-browser";
33

4-
import { Search } from "./search.component";
54
import { FormsModule } from "@angular/forms";
65
import { I18nModule } from "../i18n/index";
76
import { IconModule } from "../icon/index";
7+
import { Search } from "./search.component";
88

99
describe("Search", () => {
1010
let component: Search;
@@ -38,46 +38,46 @@ describe("Search", () => {
3838
});
3939

4040
it("should bind input value", () => {
41-
component.value = "Text";
41+
fixture.componentRef.setInput("value", "Text");
4242
fixture.detectChanges();
4343
expect(inputElement.value).toEqual("Text");
4444
});
4545

4646
it("should bind input disabled", () => {
4747
expect(inputElement.disabled).toEqual(false);
48-
component.disabled = true;
48+
fixture.componentRef.setInput("disabled", true);
4949
fixture.detectChanges();
5050
expect(inputElement.disabled).toEqual(true);
5151
});
5252

5353
it("should bind input required", () => {
54-
component.required = true;
54+
fixture.componentRef.setInput("required", true);
5555
fixture.detectChanges();
5656
expect(inputElement.required).toEqual(true);
5757
});
5858

5959
it("should display component of the correct size", () => {
6060
containerElement = fixture.debugElement.query(By.css(".cds--search")).nativeElement;
61-
component.size = "lg";
61+
fixture.componentRef.setInput("size", "lg");
6262
fixture.detectChanges();
6363
expect(containerElement.className.includes("cds--search--lg")).toEqual(true);
64-
component.size = "sm";
64+
fixture.componentRef.setInput("size", "sm");
6565
fixture.detectChanges();
6666
expect(containerElement.className.includes("cds--search--sm")).toEqual(true);
6767
});
6868

6969
it("should display clear button", () => {
7070
clearButtonElement = fixture.debugElement.query(By.css("button")).nativeElement;
71-
component.value = "";
71+
fixture.componentRef.setInput("value", "");
7272
fixture.detectChanges();
7373
expect(clearButtonElement.className.includes("cds--search-close--hidden")).toEqual(true);
74-
component.value = "Text";
74+
fixture.componentRef.setInput("value", "Text");
7575
fixture.detectChanges();
7676
expect(clearButtonElement.className.includes("cds--search-close--hidden")).toEqual(false);
7777
});
7878

7979
it("should clear input when clear button is clicked", () => {
80-
component.value = "Text";
80+
fixture.componentRef.setInput("value", "Text");
8181
fixture.detectChanges();
8282
clearButtonElement = fixture.debugElement.query(By.css("button")).nativeElement;
8383
clearButtonElement.click();
@@ -86,8 +86,8 @@ describe("Search", () => {
8686
});
8787

8888
it("should clear the input when the clear button is clicked on the expandable component", () => {
89-
component.expandable = true;
90-
component.value = "TextToClear";
89+
fixture.componentRef.setInput("expandable", true);
90+
fixture.componentRef.setInput("value", "TextToClear");
9191
fixture.detectChanges();
9292
clearButtonElement = fixture.debugElement.query(By.css("button")).nativeElement;
9393
clearButtonElement.click();
@@ -97,7 +97,7 @@ describe("Search", () => {
9797

9898
it("should clear the input when the escape key is pressed", () => {
9999
clearButtonElement = fixture.debugElement.query(By.css("button")).nativeElement;
100-
component.value = "TextToClear";
100+
fixture.componentRef.setInput("value", "TextToClear");
101101
fixture.detectChanges();
102102
expect(clearButtonElement.className.includes("cds--search-close--hidden")).toEqual(false);
103103
component.keyDown(new KeyboardEvent("keydown", {
@@ -109,10 +109,10 @@ describe("Search", () => {
109109
});
110110

111111
it("should clear the input and keep the expanded state open when the escape key is pressed", () => {
112-
component.expandable = true;
113-
component.active = true;
112+
fixture.componentRef.setInput("expandable", true);
113+
fixture.componentRef.setInput("active", true);
114114
containerElement = fixture.debugElement.query(By.css(".cds--search")).nativeElement;
115-
component.value = "TextToClear";
115+
fixture.componentRef.setInput("value", "TextToClear");
116116
fixture.detectChanges();
117117
expect(containerElement.className.includes("cds--search--expanded")).toEqual(true);
118118
component.keyDown(new KeyboardEvent("keydown", {
@@ -124,10 +124,10 @@ describe("Search", () => {
124124
});
125125

126126
it("should close the expandable search component when esc is pressed when content is empty", () => {
127-
component.expandable = true;
128-
component.active = true;
127+
fixture.componentRef.setInput("expandable", true);
128+
fixture.componentRef.setInput("active", true);
129129
containerElement = fixture.debugElement.query(By.css(".cds--search")).nativeElement;
130-
component.value = "";
130+
fixture.componentRef.setInput("value", "");
131131
fixture.detectChanges();
132132
expect(containerElement.className.includes("cds--search--expanded")).toEqual(true);
133133
component.keyDown(new KeyboardEvent("keydown", {
@@ -140,10 +140,10 @@ describe("Search", () => {
140140

141141
it("should have dark and light theme", () => {
142142
containerElement = fixture.debugElement.query(By.css(".cds--search")).nativeElement;
143-
component.theme = "dark";
143+
fixture.componentRef.setInput("theme", "dark");
144144
fixture.detectChanges();
145145
expect(containerElement.className.includes("cds--search--light")).toEqual(false);
146-
component.theme = "light";
146+
fixture.componentRef.setInput("theme", "light");
147147
fixture.detectChanges();
148148
expect(containerElement.className.includes("cds--search--light")).toEqual(true);
149149
});

src/search/search.component.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import {
2+
ChangeDetectionStrategy,
3+
ChangeDetectorRef,
24
Component,
3-
Input,
5+
ElementRef,
46
EventEmitter,
5-
Output,
67
HostBinding,
7-
ElementRef,
88
HostListener,
9+
Input,
10+
Output,
911
ViewChild
1012
} from "@angular/core";
11-
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from "@angular/forms";
13+
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
1214
import { I18n } from "carbon-components-angular/i18n";
1315

1416
/**
@@ -29,7 +31,8 @@ import { I18n } from "carbon-components-angular/i18n";
2931
useExisting: Search,
3032
multi: true
3133
}
32-
]
34+
],
35+
changeDetection: ChangeDetectionStrategy.OnPush
3336
})
3437
export class Search implements ControlValueAccessor {
3538
/**
@@ -151,7 +154,11 @@ export class Search implements ControlValueAccessor {
151154
* Creates an instance of `Search`.
152155
* @param i18n The i18n translations.
153156
*/
154-
constructor(protected elementRef: ElementRef, protected i18n: I18n) {
157+
constructor(
158+
protected elementRef: ElementRef,
159+
protected i18n: I18n,
160+
protected changeDetectorRef: ChangeDetectorRef
161+
) {
155162
Search.searchCount++;
156163
}
157164

@@ -234,6 +241,7 @@ export class Search implements ControlValueAccessor {
234241
if (this.value === "") {
235242
this.active = false;
236243
this.open.emit(this.active);
244+
this.changeDetectorRef.markForCheck();
237245
}
238246
} else if (event.key === "Enter") {
239247
this.openSearch();
@@ -243,6 +251,7 @@ export class Search implements ControlValueAccessor {
243251
if (event.key === "Escape") {
244252
if (this.value !== "") {
245253
this.clearSearch();
254+
this.changeDetectorRef.markForCheck();
246255
}
247256
}
248257
}

0 commit comments

Comments
 (0)