Skip to content

Commit e7a7d46

Browse files
committed
fix: Remove manual change detection in favor of DI
Signed-off-by: Akshat Patel <[email protected]>
1 parent 53d76cf commit e7a7d46

File tree

6 files changed

+277
-180
lines changed

6 files changed

+277
-180
lines changed

src/grid/column.directive.ts

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
import {
2+
Directive,
3+
HostBinding,
4+
Input,
5+
OnChanges,
6+
OnDestroy,
7+
OnInit,
8+
Optional
9+
} from "@angular/core";
10+
import { Subscription } from "rxjs";
11+
import { GridService } from "./grid.service";
12+
13+
@Directive({
14+
selector: "[cdsCol], [ibmCol]"
15+
})
16+
export class ColumnDirective implements OnInit, OnChanges, OnDestroy {
17+
@HostBinding("class")
18+
get columnClasses(): string {
19+
return this._columnClasses.join(" ");
20+
}
21+
set columnClasses(classes: string) {
22+
this._columnClasses = classes.split(" ");
23+
}
24+
25+
@Input() class = "";
26+
27+
/**
28+
* Defines columns width for specified breakpoint
29+
* Accepts the following formats:
30+
* - {[breakpoint]: number}
31+
* - {[breakpoint]: "auto"} - css only
32+
* - {[breakpoint]: {[start|end]: number}} - css only
33+
*
34+
* Example:
35+
* <div cdsCol [columnNumbers]={md: 3, lg: 4}></div>
36+
*/
37+
@Input() columnNumbers = {};
38+
39+
/**
40+
* Defines columns offset, which increases the left margin of the column.
41+
* This field will only work with flexbox grid.
42+
*
43+
* Accepts the following formats:
44+
* - {[breakpoint]: number}
45+
*
46+
* Example:
47+
* <div cdsCol [offsets]={md: 3, lg: 4}></div>
48+
*/
49+
@Input() offsets = {};
50+
51+
/**
52+
* Set to `true` to use css grid column hang class
53+
* This will only work when `isCss` property is set to true
54+
*
55+
* Useful when trying to align content across css grid/subgrid
56+
*/
57+
@Input() columnHang = false;
58+
59+
protected _columnClasses: string[] = [];
60+
61+
private isCssGrid = false;
62+
private subscription = new Subscription();
63+
64+
constructor(@Optional() private gridService: GridService) {}
65+
66+
ngOnInit() {
67+
if (this.gridService) {
68+
this.gridService.gridObservable.subscribe((isCssGrid: boolean) => {
69+
this.isCssGrid = isCssGrid;
70+
this.updateColumnClasses();
71+
});
72+
} else {
73+
this.updateColumnClasses();
74+
}
75+
}
76+
77+
ngOnChanges() {
78+
this.updateColumnClasses();
79+
}
80+
81+
/**
82+
* Unsubscribe from subscription
83+
*/
84+
ngOnDestroy() {
85+
this.subscription.unsubscribe();
86+
}
87+
88+
private updateColumnClasses() {
89+
try {
90+
this._columnClasses = [];
91+
const columnKeys = Object.keys(this.columnNumbers);
92+
console.log(columnKeys);
93+
94+
// Assign classes based on the type of grid used.
95+
if (this.isCssGrid) {
96+
// Default css grid class
97+
this._columnClasses.push("cds--css-grid-column");
98+
if (this.columnHang) {
99+
this._columnClasses.push("cds--grid-column-hang");
100+
}
101+
102+
columnKeys.forEach(key => {
103+
/**
104+
* Passing in `auto` to a breakpoint as such: {'md': 'auto'}
105+
* will assign the element which will automatically determine the width of the column
106+
* for the breakpoint passed
107+
*/
108+
if (this.columnNumbers[key] === "auto") {
109+
this._columnClasses.push(`cds--${key}:col-span-auto`);
110+
} else if (typeof this.columnNumbers[key] === "object") {
111+
/**
112+
* In css grid, objects can be passed to the keys in the following format:
113+
* {'md': {'start': 3}}
114+
*
115+
* These objects are used to position the column
116+
*/
117+
if (this.columnNumbers[key]["start"]) {
118+
// col-start is simular equivalent of flex offset
119+
this._columnClasses.push(`cds--${key}:col-start-${this.columnNumbers[key].start}`);
120+
}
121+
if (this.columnNumbers[key]["end"]) {
122+
this._columnClasses.push(`cds--${key}:col-end-${this.columnNumbers[key].end}`);
123+
}
124+
if (this.columnNumbers[key]["span"]) {
125+
this._columnClasses.push(`cds--${key}:col-span-${this.columnNumbers[key].span}`);
126+
}
127+
} else {
128+
this._columnClasses.push(`cds--${key}:col-span-${this.columnNumbers[key]}`);
129+
}
130+
});
131+
} else {
132+
// Set column classes for flex grid
133+
if (columnKeys.length <= 0) {
134+
this._columnClasses.push("cds--col");
135+
}
136+
137+
columnKeys.forEach(key => {
138+
if (this.columnNumbers[key] === "nobreak") {
139+
this._columnClasses.push(`cds--col-${key}`);
140+
} else {
141+
this._columnClasses.push(`cds--col-${key}-${this.columnNumbers[key]}`);
142+
}
143+
});
144+
145+
Object.keys(this.offsets).forEach(key => {
146+
this._columnClasses.push(`cds--start-${key}-${this.offsets[key] + 1}`);
147+
});
148+
}
149+
} catch (err) {
150+
console.error(`Malformed \`offsets\` or \`columnNumbers\`: ${err}`);
151+
}
152+
153+
/**
154+
* Append the classes passed so they aren't overriden when we set the column classes
155+
* from host binding
156+
*/
157+
if (this.class) {
158+
this._columnClasses.push(this.class);
159+
}
160+
}
161+
}

0 commit comments

Comments
 (0)