Skip to content

Commit c3e30c7

Browse files
authored
feat: introduce proper types for public API (#49)
BREAKING CHANGE: Almost every public API has now proper types. While this should in theory not affect applications it will now fail compilation if the APIs were used in an incorrect manner.
1 parent bdab162 commit c3e30c7

File tree

107 files changed

+979
-664
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

107 files changed

+979
-664
lines changed

projects/ngx-datatable/src/lib/components/body/body-cell.component.ts

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ import {
1818
import { TableColumn } from '../../types/table-column.type';
1919
import { SortDirection } from '../../types/sort-direction.type';
2020
import { Keys } from '../../utils/keys';
21+
import { RowOrGroup } from "../../types/group.type";
22+
import { BehaviorSubject } from "rxjs";
23+
import { ActivateEvent } from '../../types/activate-event.type';
24+
import { CellContext } from '../../types/cell-context.type';
25+
import { SortPropDir } from '../../types/sort-prop-dir.type';
2126

2227
export type TreeStatus = 'collapsed' | 'expanded' | 'loading' | 'disabled';
2328

@@ -70,19 +75,19 @@ export type TreeStatus = 'collapsed' | 'expanded' | 'loading' | 'disabled';
7075
</ng-template>
7176
`
7277
})
73-
export class DataTableBodyCellComponent implements DoCheck, OnDestroy {
74-
@Input() displayCheck: (row: any, column?: TableColumn, value?: any) => boolean;
78+
export class DataTableBodyCellComponent<TRow extends {level?: number} = any> implements DoCheck, OnDestroy {
79+
@Input() displayCheck: (row: RowOrGroup<TRow>, column: TableColumn, value: any) => boolean;
7580

76-
_disable$;
77-
@Input() set disable$(val: any) {
81+
_disable$: BehaviorSubject<boolean>;
82+
@Input() set disable$(val: BehaviorSubject<boolean>) {
7883
this._disable$ = val;
7984
this.cellContext.disable$ = val;
8085
};
8186
get disable$() {
8287
return this._disable$;
8388
}
8489

85-
@Input() set group(group: any) {
90+
@Input() set group(group: TRow[]) {
8691
this._group = group;
8792
this.cellContext.group = group;
8893
this.checkValueUpdates();
@@ -146,23 +151,23 @@ export class DataTableBodyCellComponent implements DoCheck, OnDestroy {
146151
return this._column;
147152
}
148153

149-
@Input() set row(row: any) {
154+
@Input() set row(row: RowOrGroup<TRow>) {
150155
this._row = row;
151156
this.cellContext.row = row;
152157
this.checkValueUpdates();
153158
this.cd.markForCheck();
154159
}
155160

156-
get row(): any {
161+
get row(): RowOrGroup<TRow> {
157162
return this._row;
158163
}
159164

160-
@Input() set sorts(val: any[]) {
165+
@Input() set sorts(val: SortPropDir[]) {
161166
this._sorts = val;
162-
this.calcSortDir = this.calcSortDir(val);
167+
this.sortDir = this.calcSortDir(val);
163168
}
164169

165-
get sorts(): any[] {
170+
get sorts(): SortPropDir[] {
166171
return this._sorts;
167172
}
168173

@@ -183,7 +188,7 @@ export class DataTableBodyCellComponent implements DoCheck, OnDestroy {
183188

184189
@Input() ghostLoadingIndicator = false;
185190

186-
@Output() activate: EventEmitter<any> = new EventEmitter();
191+
@Output() activate: EventEmitter<ActivateEvent<TRow>> = new EventEmitter();
187192

188193
@Output() treeAction: EventEmitter<any> = new EventEmitter();
189194

@@ -194,7 +199,7 @@ export class DataTableBodyCellComponent implements DoCheck, OnDestroy {
194199
ghostLoaderTemplate: ViewContainerRef;
195200

196201
@HostBinding('class')
197-
get columnCssClasses(): any {
202+
get columnCssClasses(): string {
198203
let cls = 'datatable-body-cell';
199204
if (this.column.cellClass) {
200205
if (typeof this.column.cellClass === 'string') {
@@ -263,30 +268,28 @@ export class DataTableBodyCellComponent implements DoCheck, OnDestroy {
263268
return height + 'px';
264269
}
265270

266-
sanitizedValue: any;
271+
sanitizedValue: string;
267272
value: any;
268273
sortDir: SortDirection;
269274
isFocused = false;
270-
onCheckboxChangeFn = this.onCheckboxChange.bind(this);
271-
activateFn = this.activate.emit.bind(this.activate);
272275

273-
cellContext: any;
276+
cellContext: CellContext<TRow>;
274277

275278
private _isSelected: boolean;
276-
private _sorts: any[];
279+
private _sorts: SortPropDir[];
277280
private _column: TableColumn;
278-
private _row: any;
279-
private _group: any;
281+
private _row: RowOrGroup<TRow>;
282+
private _group: TRow[];
280283
private _rowHeight: number;
281284
private _rowIndex: number;
282285
private _expanded: boolean;
283-
private _element: any;
286+
private _element: HTMLElement;
284287
private _treeStatus: TreeStatus;
285288

286-
constructor(element: ElementRef, private cd: ChangeDetectorRef) {
289+
constructor(element: ElementRef<HTMLElement>, private cd: ChangeDetectorRef) {
287290
this.cellContext = {
288-
onCheckboxChangeFn: this.onCheckboxChangeFn,
289-
activateFn: this.activateFn,
291+
onCheckboxChangeFn: (event: Event) => this.onCheckboxChange(event),
292+
activateFn: (event: ActivateEvent<TRow>) => this.activate.emit(event),
290293
row: this.row,
291294
group: this.group,
292295
value: this.value,
@@ -296,7 +299,7 @@ export class DataTableBodyCellComponent implements DoCheck, OnDestroy {
296299
rowIndex: this.rowIndex,
297300
treeStatus: this.treeStatus,
298301
disable$: this.disable$,
299-
onTreeAction: this.onTreeAction.bind(this)
302+
onTreeAction: () => this.onTreeAction()
300303
};
301304

302305
this._element = element.nativeElement;
@@ -407,7 +410,7 @@ export class DataTableBodyCellComponent implements DoCheck, OnDestroy {
407410
}
408411
}
409412

410-
onCheckboxChange(event: any): void {
413+
onCheckboxChange(event: Event): void {
411414
this.activate.emit({
412415
type: 'checkbox',
413416
event,
@@ -421,15 +424,15 @@ export class DataTableBodyCellComponent implements DoCheck, OnDestroy {
421424
});
422425
}
423426

424-
calcSortDir(sorts: any[]): any {
427+
calcSortDir(sorts: SortPropDir[]): SortDirection {
425428
if (!sorts) {
426429
return;
427430
}
428431

429-
const sort = sorts.find((s: any) => s.prop === this.column.prop);
432+
const sort = sorts.find(s => s.prop === this.column.prop);
430433

431434
if (sort) {
432-
return sort.dir;
435+
return sort.dir as SortDirection;
433436
}
434437
}
435438

@@ -444,8 +447,8 @@ export class DataTableBodyCellComponent implements DoCheck, OnDestroy {
444447
this.treeAction.emit(this.row);
445448
}
446449

447-
calcLeftMargin(column: any, row: any) {
450+
calcLeftMargin(column: TableColumn, row: RowOrGroup<TRow>): number {
448451
const levelIndent = column.treeLevelIndent != null ? column.treeLevelIndent : 50;
449-
return column.isTreeColumn ? row.level * levelIndent : 0;
452+
return column.isTreeColumn ? (row as TRow).level * levelIndent : 0;
450453
}
451454
}
Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
import { Directive, TemplateRef } from '@angular/core';
2+
import { GroupContext } from '../../types/cell-context.type';
23

34
@Directive({
45
selector: '[ngx-datatable-group-header-template]'
56
})
6-
export class DatatableGroupHeaderTemplateDirective {
7-
constructor(public template: TemplateRef<any>) {}
7+
export class DatatableGroupHeaderTemplateDirective<TRow> {
8+
static ngTemplateContextGuard<TRow>(
9+
directive: DatatableGroupHeaderTemplateDirective<TRow>,
10+
context: unknown
11+
): context is GroupContext<TRow> {
12+
return true;
13+
}
814
}

projects/ngx-datatable/src/lib/components/body/body-group-header.directive.spec.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ class TestFixtureComponent {}
1919
describe('DatatableGroupHeaderDirective', () => {
2020
let fixture: ComponentFixture<TestFixtureComponent>;
2121
let component: TestFixtureComponent;
22-
let element: any;
2322

2423
// provide our implementations or mocks to the dependency injector
2524
beforeEach(() => {
@@ -33,7 +32,6 @@ describe('DatatableGroupHeaderDirective', () => {
3332
TestBed.compileComponents().then(() => {
3433
fixture = TestBed.createComponent(TestFixtureComponent);
3534
component = fixture.componentInstance;
36-
element = fixture.nativeElement;
3735
});
3836
})
3937
);

projects/ngx-datatable/src/lib/components/body/body-group-header.directive.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { ContentChild, Directive, EventEmitter, Input, Output, TemplateRef } from '@angular/core';
22
import { DatatableGroupHeaderTemplateDirective } from './body-group-header-template.directive';
3+
import { GroupContext } from '../../types/cell-context.type';
34

45
@Directive({ selector: 'ngx-datatable-group-header' })
5-
export class DatatableGroupHeaderDirective {
6+
export class DatatableGroupHeaderDirective<TRow = any> {
67
/**
78
* Row height is required when virtual scroll is enabled.
89
*/
@@ -14,12 +15,12 @@ export class DatatableGroupHeaderDirective {
1415
@Input() checkboxable = false;
1516

1617
@Input('template')
17-
_templateInput: TemplateRef<any>;
18+
_templateInput: TemplateRef<GroupContext<TRow>>;
1819

1920
@ContentChild(DatatableGroupHeaderTemplateDirective, { read: TemplateRef, static: true })
20-
_templateQuery: TemplateRef<any>;
21+
_templateQuery: TemplateRef<GroupContext<TRow>>;
2122

22-
get template(): TemplateRef<any> {
23+
get template(): TemplateRef<GroupContext<TRow>> {
2324
return this._templateInput || this._templateQuery;
2425
}
2526

0 commit comments

Comments
 (0)