Skip to content

Commit f260aa0

Browse files
committed
refactor(cdk/table): remove mixin function usages
Removes the final usages of TypeScript mixins in the CDK table by adding the sticky functionality to the individual usages. Ideally we'd have a base class for this, but that won't be usable in `CdkHeaderRowDef` and `CdkFooterRowDef` because they already inherit from `BaseRowDef` and we can't put the sticky functionality there, because `CdkRowDef` shouldn't support `sticky`. The logic is pretty basic so I think it's fine to duplicate it.
1 parent d361f79 commit f260aa0

File tree

7 files changed

+140
-43
lines changed

7 files changed

+140
-43
lines changed

src/cdk/table/can-stick.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@ export interface CanStick {
2121
/** Whether sticky positioning should be applied. */
2222
sticky: boolean;
2323

24-
/** Whether the sticky input has changed since it was last checked. */
25-
_hasStickyChanged: boolean;
26-
2724
/** Whether the sticky value has changed since this was last called. */
2825
hasStickyChanged(): boolean;
2926

src/cdk/table/cell.ts

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
TemplateRef,
1717
booleanAttribute,
1818
} from '@angular/core';
19-
import {CanStick, CanStickCtor, mixinHasStickyInput} from './can-stick';
19+
import {CanStick} from './can-stick';
2020
import {CDK_TABLE} from './tokens';
2121

2222
/** Base interface for a cell definition. Captures a column's cell template definition. */
@@ -60,23 +60,18 @@ export class CdkFooterCellDef implements CellDef {
6060
constructor(/** @docs-private */ public template: TemplateRef<any>) {}
6161
}
6262

63-
// Boilerplate for applying mixins to CdkColumnDef.
64-
/** @docs-private */
65-
class CdkColumnDefBase {}
66-
const _CdkColumnDefBase: CanStickCtor & typeof CdkColumnDefBase =
67-
mixinHasStickyInput(CdkColumnDefBase);
68-
6963
/**
7064
* Column definition for the CDK table.
7165
* Defines a set of cells available for a table column.
7266
*/
7367
@Directive({
7468
selector: '[cdkColumnDef]',
75-
inputs: ['sticky'],
7669
providers: [{provide: 'MAT_SORT_HEADER_COLUMN_DEF', useExisting: CdkColumnDef}],
7770
standalone: true,
7871
})
79-
export class CdkColumnDef extends _CdkColumnDefBase implements CanStick {
72+
export class CdkColumnDef implements CanStick {
73+
private _hasStickyChanged = false;
74+
8075
/** Unique name for this column. */
8176
@Input('cdkColumnDef')
8277
get name(): string {
@@ -87,6 +82,19 @@ export class CdkColumnDef extends _CdkColumnDefBase implements CanStick {
8782
}
8883
protected _name: string;
8984

85+
/** Whether the cell is sticky. */
86+
@Input({transform: booleanAttribute})
87+
get sticky(): boolean {
88+
return this._sticky;
89+
}
90+
set sticky(value: boolean) {
91+
if (value !== this._sticky) {
92+
this._sticky = value;
93+
this._hasStickyChanged = true;
94+
}
95+
}
96+
private _sticky = false;
97+
9098
/**
9199
* Whether this column should be sticky positioned on the end of the row. Should make sure
92100
* that it mimics the `CanStick` mixin such that `_hasStickyChanged` is set to true if the value
@@ -126,8 +134,18 @@ export class CdkColumnDef extends _CdkColumnDefBase implements CanStick {
126134
*/
127135
_columnCssClassName: string[];
128136

129-
constructor(@Inject(CDK_TABLE) @Optional() public _table?: any) {
130-
super();
137+
constructor(@Inject(CDK_TABLE) @Optional() public _table?: any) {}
138+
139+
/** Whether the sticky state has changed. */
140+
hasStickyChanged(): boolean {
141+
const hasStickyChanged = this._hasStickyChanged;
142+
this.resetStickyChanged();
143+
return hasStickyChanged;
144+
}
145+
146+
/** Resets the sticky changed state. */
147+
resetStickyChanged(): void {
148+
this._hasStickyChanged = false;
131149
}
132150

133151
/**

src/cdk/table/row.ts

Lines changed: 65 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ import {
2121
ViewEncapsulation,
2222
Inject,
2323
Optional,
24+
Input,
25+
booleanAttribute,
2426
} from '@angular/core';
25-
import {CanStick, CanStickCtor, mixinHasStickyInput} from './can-stick';
27+
import {CanStick} from './can-stick';
2628
import {CdkCellDef, CdkColumnDef} from './cell';
2729
import {CDK_TABLE} from './tokens';
2830

@@ -80,22 +82,31 @@ export abstract class BaseRowDef implements OnChanges {
8082
}
8183
}
8284

83-
// Boilerplate for applying mixins to CdkHeaderRowDef.
84-
/** @docs-private */
85-
class CdkHeaderRowDefBase extends BaseRowDef {}
86-
const _CdkHeaderRowDefBase: CanStickCtor & typeof CdkHeaderRowDefBase =
87-
mixinHasStickyInput(CdkHeaderRowDefBase);
88-
8985
/**
9086
* Header row definition for the CDK table.
9187
* Captures the header row's template and other header properties such as the columns to display.
9288
*/
9389
@Directive({
9490
selector: '[cdkHeaderRowDef]',
95-
inputs: ['columns: cdkHeaderRowDef', 'sticky: cdkHeaderRowDefSticky'],
91+
inputs: [{name: 'columns', alias: 'cdkHeaderRowDef'}],
9692
standalone: true,
9793
})
98-
export class CdkHeaderRowDef extends _CdkHeaderRowDefBase implements CanStick, OnChanges {
94+
export class CdkHeaderRowDef extends BaseRowDef implements CanStick, OnChanges {
95+
private _hasStickyChanged = false;
96+
97+
/** Whether the row is sticky. */
98+
@Input({alias: 'cdkHeaderRowDefSticky', transform: booleanAttribute})
99+
get sticky(): boolean {
100+
return this._sticky;
101+
}
102+
set sticky(value: boolean) {
103+
if (value !== this._sticky) {
104+
this._sticky = value;
105+
this._hasStickyChanged = true;
106+
}
107+
}
108+
private _sticky = false;
109+
99110
constructor(
100111
template: TemplateRef<any>,
101112
_differs: IterableDiffers,
@@ -109,24 +120,45 @@ export class CdkHeaderRowDef extends _CdkHeaderRowDefBase implements CanStick, O
109120
override ngOnChanges(changes: SimpleChanges): void {
110121
super.ngOnChanges(changes);
111122
}
112-
}
113123

114-
// Boilerplate for applying mixins to CdkFooterRowDef.
115-
/** @docs-private */
116-
class CdkFooterRowDefBase extends BaseRowDef {}
117-
const _CdkFooterRowDefBase: CanStickCtor & typeof CdkFooterRowDefBase =
118-
mixinHasStickyInput(CdkFooterRowDefBase);
124+
/** Whether the sticky state has changed. */
125+
hasStickyChanged(): boolean {
126+
const hasStickyChanged = this._hasStickyChanged;
127+
this.resetStickyChanged();
128+
return hasStickyChanged;
129+
}
130+
131+
/** Resets the sticky changed state. */
132+
resetStickyChanged(): void {
133+
this._hasStickyChanged = false;
134+
}
135+
}
119136

120137
/**
121138
* Footer row definition for the CDK table.
122139
* Captures the footer row's template and other footer properties such as the columns to display.
123140
*/
124141
@Directive({
125142
selector: '[cdkFooterRowDef]',
126-
inputs: ['columns: cdkFooterRowDef', 'sticky: cdkFooterRowDefSticky'],
143+
inputs: [{name: 'columns', alias: 'cdkFooterRowDef'}],
127144
standalone: true,
128145
})
129-
export class CdkFooterRowDef extends _CdkFooterRowDefBase implements CanStick, OnChanges {
146+
export class CdkFooterRowDef extends BaseRowDef implements CanStick, OnChanges {
147+
private _hasStickyChanged = false;
148+
149+
/** Whether the row is sticky. */
150+
@Input({alias: 'cdkFooterRowDefSticky', transform: booleanAttribute})
151+
get sticky(): boolean {
152+
return this._sticky;
153+
}
154+
set sticky(value: boolean) {
155+
if (value !== this._sticky) {
156+
this._sticky = value;
157+
this._hasStickyChanged = true;
158+
}
159+
}
160+
private _sticky = false;
161+
130162
constructor(
131163
template: TemplateRef<any>,
132164
_differs: IterableDiffers,
@@ -140,6 +172,18 @@ export class CdkFooterRowDef extends _CdkFooterRowDefBase implements CanStick, O
140172
override ngOnChanges(changes: SimpleChanges): void {
141173
super.ngOnChanges(changes);
142174
}
175+
176+
/** Whether the sticky state has changed. */
177+
hasStickyChanged(): boolean {
178+
const hasStickyChanged = this._hasStickyChanged;
179+
this.resetStickyChanged();
180+
return hasStickyChanged;
181+
}
182+
183+
/** Resets the sticky changed state. */
184+
resetStickyChanged(): void {
185+
this._hasStickyChanged = false;
186+
}
143187
}
144188

145189
/**
@@ -149,7 +193,10 @@ export class CdkFooterRowDef extends _CdkFooterRowDefBase implements CanStick, O
149193
*/
150194
@Directive({
151195
selector: '[cdkRowDef]',
152-
inputs: ['columns: cdkRowDefColumns', 'when: cdkRowDefWhen'],
196+
inputs: [
197+
{name: 'columns', alias: 'cdkRowDefColumns'},
198+
{name: 'when', alias: 'cdkRowDefWhen'},
199+
],
153200
standalone: true,
154201
})
155202
export class CdkRowDef<T> extends BaseRowDef {

src/material/table/cell.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ export class MatFooterCellDef extends CdkFooterCellDef {}
5656
*/
5757
@Directive({
5858
selector: '[matColumnDef]',
59-
inputs: ['sticky'],
6059
providers: [
6160
{provide: CdkColumnDef, useExisting: MatColumnDef},
6261
{provide: 'MAT_SORT_HEADER_COLUMN_DEF', useExisting: MatColumnDef},

src/material/table/row.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,13 @@ import {
1616
CdkNoDataRow,
1717
CdkCellOutlet,
1818
} from '@angular/cdk/table';
19-
import {ChangeDetectionStrategy, Component, Directive, ViewEncapsulation} from '@angular/core';
19+
import {
20+
ChangeDetectionStrategy,
21+
Component,
22+
Directive,
23+
ViewEncapsulation,
24+
booleanAttribute,
25+
} from '@angular/core';
2026

2127
// We can't reuse `CDK_ROW_TEMPLATE` because it's incompatible with local compilation mode.
2228
const ROW_TEMPLATE = `<ng-container cdkCellOutlet></ng-container>`;
@@ -28,7 +34,10 @@ const ROW_TEMPLATE = `<ng-container cdkCellOutlet></ng-container>`;
2834
@Directive({
2935
selector: '[matHeaderRowDef]',
3036
providers: [{provide: CdkHeaderRowDef, useExisting: MatHeaderRowDef}],
31-
inputs: ['columns: matHeaderRowDef', 'sticky: matHeaderRowDefSticky'],
37+
inputs: [
38+
{name: 'columns', alias: 'matHeaderRowDef'},
39+
{name: 'sticky', alias: 'matHeaderRowDefSticky', transform: booleanAttribute},
40+
],
3241
standalone: true,
3342
})
3443
export class MatHeaderRowDef extends CdkHeaderRowDef {}
@@ -40,7 +49,10 @@ export class MatHeaderRowDef extends CdkHeaderRowDef {}
4049
@Directive({
4150
selector: '[matFooterRowDef]',
4251
providers: [{provide: CdkFooterRowDef, useExisting: MatFooterRowDef}],
43-
inputs: ['columns: matFooterRowDef', 'sticky: matFooterRowDefSticky'],
52+
inputs: [
53+
{name: 'columns', alias: 'matFooterRowDef'},
54+
{name: 'sticky', alias: 'matFooterRowDefSticky', transform: booleanAttribute},
55+
],
4456
standalone: true,
4557
})
4658
export class MatFooterRowDef extends CdkFooterRowDef {}
@@ -53,7 +65,10 @@ export class MatFooterRowDef extends CdkFooterRowDef {}
5365
@Directive({
5466
selector: '[matRowDef]',
5567
providers: [{provide: CdkRowDef, useExisting: MatRowDef}],
56-
inputs: ['columns: matRowDefColumns', 'when: matRowDefWhen'],
68+
inputs: [
69+
{name: 'columns', alias: 'matRowDefColumns'},
70+
{name: 'when', alias: 'matRowDefWhen'},
71+
],
5772
standalone: true,
5873
})
5974
export class MatRowDef<T> extends CdkRowDef<T> {}

tools/public_api_guard/cdk/table.md

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ export abstract class BaseRowDef implements OnChanges {
6161
// @public
6262
export interface CanStick {
6363
hasStickyChanged(): boolean;
64-
_hasStickyChanged: boolean;
6564
resetStickyChanged(): void;
6665
sticky: boolean;
6766
}
@@ -138,20 +137,26 @@ export interface CdkCellOutletRowContext<T> {
138137
}
139138

140139
// @public
141-
export class CdkColumnDef extends _CdkColumnDefBase implements CanStick {
140+
export class CdkColumnDef implements CanStick {
142141
constructor(_table?: any);
143142
cell: CdkCellDef;
144143
_columnCssClassName: string[];
145144
cssClassFriendlyName: string;
146145
footerCell: CdkFooterCellDef;
146+
hasStickyChanged(): boolean;
147147
headerCell: CdkHeaderCellDef;
148148
get name(): string;
149149
set name(name: string);
150150
// (undocumented)
151151
protected _name: string;
152152
// (undocumented)
153+
static ngAcceptInputType_sticky: unknown;
154+
// (undocumented)
153155
static ngAcceptInputType_stickyEnd: unknown;
156+
resetStickyChanged(): void;
154157
protected _setNameInput(value: string): void;
158+
get sticky(): boolean;
159+
set sticky(value: boolean);
155160
get stickyEnd(): boolean;
156161
set stickyEnd(value: boolean);
157162
// (undocumented)
@@ -160,7 +165,7 @@ export class CdkColumnDef extends _CdkColumnDefBase implements CanStick {
160165
_table?: any;
161166
protected _updateColumnCssClassName(): void;
162167
// (undocumented)
163-
static ɵdir: i0.ɵɵDirectiveDeclaration<CdkColumnDef, "[cdkColumnDef]", never, { "sticky": { "alias": "sticky"; "required": false; }; "name": { "alias": "cdkColumnDef"; "required": false; }; "stickyEnd": { "alias": "stickyEnd"; "required": false; }; }, {}, ["cell", "headerCell", "footerCell"], never, true, never>;
168+
static ɵdir: i0.ɵɵDirectiveDeclaration<CdkColumnDef, "[cdkColumnDef]", never, { "name": { "alias": "cdkColumnDef"; "required": false; }; "sticky": { "alias": "sticky"; "required": false; }; "stickyEnd": { "alias": "stickyEnd"; "required": false; }; }, {}, ["cell", "headerCell", "footerCell"], never, true, never>;
164169
// (undocumented)
165170
static ɵfac: i0.ɵɵFactoryDeclaration<CdkColumnDef, [{ optional: true; }]>;
166171
}
@@ -194,10 +199,16 @@ export class CdkFooterRow {
194199
}
195200

196201
// @public
197-
export class CdkFooterRowDef extends _CdkFooterRowDefBase implements CanStick, OnChanges {
202+
export class CdkFooterRowDef extends BaseRowDef implements CanStick, OnChanges {
198203
constructor(template: TemplateRef<any>, _differs: IterableDiffers, _table?: any);
204+
hasStickyChanged(): boolean;
205+
// (undocumented)
206+
static ngAcceptInputType_sticky: unknown;
199207
// (undocumented)
200208
ngOnChanges(changes: SimpleChanges): void;
209+
resetStickyChanged(): void;
210+
get sticky(): boolean;
211+
set sticky(value: boolean);
201212
// (undocumented)
202213
_table?: any;
203214
// (undocumented)
@@ -235,10 +246,16 @@ export class CdkHeaderRow {
235246
}
236247

237248
// @public
238-
export class CdkHeaderRowDef extends _CdkHeaderRowDefBase implements CanStick, OnChanges {
249+
export class CdkHeaderRowDef extends BaseRowDef implements CanStick, OnChanges {
239250
constructor(template: TemplateRef<any>, _differs: IterableDiffers, _table?: any);
251+
hasStickyChanged(): boolean;
252+
// (undocumented)
253+
static ngAcceptInputType_sticky: unknown;
240254
// (undocumented)
241255
ngOnChanges(changes: SimpleChanges): void;
256+
resetStickyChanged(): void;
257+
get sticky(): boolean;
258+
set sticky(value: boolean);
242259
// (undocumented)
243260
_table?: any;
244261
// (undocumented)

tools/public_api_guard/material/table.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export class MatColumnDef extends CdkColumnDef {
5151
set name(name: string);
5252
protected _updateColumnCssClassName(): void;
5353
// (undocumented)
54-
static ɵdir: i0.ɵɵDirectiveDeclaration<MatColumnDef, "[matColumnDef]", never, { "sticky": { "alias": "sticky"; "required": false; }; "name": { "alias": "matColumnDef"; "required": false; }; }, {}, never, never, true, never>;
54+
static ɵdir: i0.ɵɵDirectiveDeclaration<MatColumnDef, "[matColumnDef]", never, { "name": { "alias": "matColumnDef"; "required": false; }; }, {}, never, never, true, never>;
5555
// (undocumented)
5656
static ɵfac: i0.ɵɵFactoryDeclaration<MatColumnDef, never>;
5757
}
@@ -82,6 +82,8 @@ export class MatFooterRow extends CdkFooterRow {
8282

8383
// @public
8484
export class MatFooterRowDef extends CdkFooterRowDef {
85+
// (undocumented)
86+
static ngAcceptInputType_sticky: unknown;
8587
// (undocumented)
8688
static ɵdir: i0.ɵɵDirectiveDeclaration<MatFooterRowDef, "[matFooterRowDef]", never, { "columns": { "alias": "matFooterRowDef"; "required": false; }; "sticky": { "alias": "matFooterRowDefSticky"; "required": false; }; }, {}, never, never, true, never>;
8789
// (undocumented)
@@ -114,6 +116,8 @@ export class MatHeaderRow extends CdkHeaderRow {
114116

115117
// @public
116118
export class MatHeaderRowDef extends CdkHeaderRowDef {
119+
// (undocumented)
120+
static ngAcceptInputType_sticky: unknown;
117121
// (undocumented)
118122
static ɵdir: i0.ɵɵDirectiveDeclaration<MatHeaderRowDef, "[matHeaderRowDef]", never, { "columns": { "alias": "matHeaderRowDef"; "required": false; }; "sticky": { "alias": "matHeaderRowDefSticky"; "required": false; }; }, {}, never, never, true, never>;
119123
// (undocumented)

0 commit comments

Comments
 (0)