Skip to content

Commit

Permalink
refactor(cdk/table): remove mixin function usages
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
crisbeto committed Feb 21, 2024
1 parent facd027 commit 5ce0045
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 36 deletions.
3 changes: 0 additions & 3 deletions src/cdk/table/can-stick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ export interface CanStick {
/** Whether sticky positioning should be applied. */
sticky: boolean;

/** Whether the sticky input has changed since it was last checked. */
_hasStickyChanged: boolean;

/** Whether the sticky value has changed since this was last called. */
hasStickyChanged(): boolean;

Expand Down
38 changes: 27 additions & 11 deletions src/cdk/table/cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
TemplateRef,
booleanAttribute,
} from '@angular/core';
import {CanStick, CanStickCtor, mixinHasStickyInput} from './can-stick';
import {CanStick} from './can-stick';
import {CDK_TABLE} from './tokens';

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

// Boilerplate for applying mixins to CdkColumnDef.
/** @docs-private */
class CdkColumnDefBase {}
const _CdkColumnDefBase: CanStickCtor & typeof CdkColumnDefBase =
mixinHasStickyInput(CdkColumnDefBase);

/**
* Column definition for the CDK table.
* Defines a set of cells available for a table column.
*/
@Directive({
selector: '[cdkColumnDef]',
inputs: ['sticky'],
providers: [{provide: 'MAT_SORT_HEADER_COLUMN_DEF', useExisting: CdkColumnDef}],
standalone: true,
})
export class CdkColumnDef extends _CdkColumnDefBase implements CanStick {
export class CdkColumnDef implements CanStick {
private _hasStickyChanged = false;

/** Unique name for this column. */
@Input('cdkColumnDef')
get name(): string {
Expand All @@ -87,6 +82,19 @@ export class CdkColumnDef extends _CdkColumnDefBase implements CanStick {
}
protected _name: string;

/** Whether the cell is sticky. */
@Input({transform: booleanAttribute})
get sticky(): boolean {
return this._sticky;
}
set sticky(value: boolean) {
if (value !== this._sticky) {
this._sticky = value;
this._hasStickyChanged = true;
}
}
private _sticky = false;

/**
* Whether this column should be sticky positioned on the end of the row. Should make sure
* that it mimics the `CanStick` mixin such that `_hasStickyChanged` is set to true if the value
Expand Down Expand Up @@ -126,8 +134,16 @@ export class CdkColumnDef extends _CdkColumnDefBase implements CanStick {
*/
_columnCssClassName: string[];

constructor(@Inject(CDK_TABLE) @Optional() public _table?: any) {
super();
constructor(@Inject(CDK_TABLE) @Optional() public _table?: any) {}

/** Whether the sticky state has changed. */
hasStickyChanged(): boolean {
return this._hasStickyChanged;
}

/** Resets the sticky changed state. */
resetStickyChanged(): void {
this._hasStickyChanged = false;
}

/**
Expand Down
74 changes: 57 additions & 17 deletions src/cdk/table/row.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ import {
ViewEncapsulation,
Inject,
Optional,
Input,
booleanAttribute,
} from '@angular/core';
import {CanStick, CanStickCtor, mixinHasStickyInput} from './can-stick';
import {CanStick} from './can-stick';
import {CdkCellDef, CdkColumnDef} from './cell';
import {CDK_TABLE} from './tokens';

Expand Down Expand Up @@ -80,22 +82,31 @@ export abstract class BaseRowDef implements OnChanges {
}
}

// Boilerplate for applying mixins to CdkHeaderRowDef.
/** @docs-private */
class CdkHeaderRowDefBase extends BaseRowDef {}
const _CdkHeaderRowDefBase: CanStickCtor & typeof CdkHeaderRowDefBase =
mixinHasStickyInput(CdkHeaderRowDefBase);

/**
* Header row definition for the CDK table.
* Captures the header row's template and other header properties such as the columns to display.
*/
@Directive({
selector: '[cdkHeaderRowDef]',
inputs: ['columns: cdkHeaderRowDef', 'sticky: cdkHeaderRowDefSticky'],
inputs: ['columns: cdkHeaderRowDef'],
standalone: true,
})
export class CdkHeaderRowDef extends _CdkHeaderRowDefBase implements CanStick, OnChanges {
export class CdkHeaderRowDef extends BaseRowDef implements CanStick, OnChanges {
private _hasStickyChanged = false;

/** Whether the row is sticky. */
@Input({alias: 'cdkHeaderRowDefSticky', transform: booleanAttribute})
get sticky(): boolean {
return this._sticky;
}
set sticky(value: boolean) {
if (value !== this._sticky) {
this._sticky = value;
this._hasStickyChanged = true;
}
}
private _sticky = false;

constructor(
template: TemplateRef<any>,
_differs: IterableDiffers,
Expand All @@ -109,24 +120,43 @@ export class CdkHeaderRowDef extends _CdkHeaderRowDefBase implements CanStick, O
override ngOnChanges(changes: SimpleChanges): void {
super.ngOnChanges(changes);
}
}

// Boilerplate for applying mixins to CdkFooterRowDef.
/** @docs-private */
class CdkFooterRowDefBase extends BaseRowDef {}
const _CdkFooterRowDefBase: CanStickCtor & typeof CdkFooterRowDefBase =
mixinHasStickyInput(CdkFooterRowDefBase);
/** Whether the sticky state has changed. */
hasStickyChanged(): boolean {
return this._hasStickyChanged;
}

/** Resets the sticky changed state. */
resetStickyChanged(): void {
this._hasStickyChanged = false;
}
}

/**
* Footer row definition for the CDK table.
* Captures the footer row's template and other footer properties such as the columns to display.
*/
@Directive({
selector: '[cdkFooterRowDef]',
inputs: ['columns: cdkFooterRowDef', 'sticky: cdkFooterRowDefSticky'],
inputs: ['columns: cdkFooterRowDef'],
standalone: true,
})
export class CdkFooterRowDef extends _CdkFooterRowDefBase implements CanStick, OnChanges {
export class CdkFooterRowDef extends BaseRowDef implements CanStick, OnChanges {
private _hasStickyChanged = false;

/** Whether the row is sticky. */
@Input({alias: 'cdkFooterRowDefSticky', transform: booleanAttribute})
get sticky(): boolean {
return this._sticky;
}
set sticky(value: boolean) {
if (value !== this._sticky) {
this._sticky = value;
this._hasStickyChanged = true;
}
}
private _sticky = false;

constructor(
template: TemplateRef<any>,
_differs: IterableDiffers,
Expand All @@ -140,6 +170,16 @@ export class CdkFooterRowDef extends _CdkFooterRowDefBase implements CanStick, O
override ngOnChanges(changes: SimpleChanges): void {
super.ngOnChanges(changes);
}

/** Whether the sticky state has changed. */
hasStickyChanged(): boolean {
return this._hasStickyChanged;
}

/** Resets the sticky changed state. */
resetStickyChanged(): void {
this._hasStickyChanged = false;
}
}

/**
Expand Down
27 changes: 22 additions & 5 deletions tools/public_api_guard/cdk/table.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ export abstract class BaseRowDef implements OnChanges {
// @public
export interface CanStick {
hasStickyChanged(): boolean;
_hasStickyChanged: boolean;
resetStickyChanged(): void;
sticky: boolean;
}
Expand Down Expand Up @@ -138,20 +137,26 @@ export interface CdkCellOutletRowContext<T> {
}

// @public
export class CdkColumnDef extends _CdkColumnDefBase implements CanStick {
export class CdkColumnDef implements CanStick {
constructor(_table?: any);
cell: CdkCellDef;
_columnCssClassName: string[];
cssClassFriendlyName: string;
footerCell: CdkFooterCellDef;
hasStickyChanged(): boolean;
headerCell: CdkHeaderCellDef;
get name(): string;
set name(name: string);
// (undocumented)
protected _name: string;
// (undocumented)
static ngAcceptInputType_sticky: unknown;
// (undocumented)
static ngAcceptInputType_stickyEnd: unknown;
resetStickyChanged(): void;
protected _setNameInput(value: string): void;
get sticky(): boolean;
set sticky(value: boolean);
get stickyEnd(): boolean;
set stickyEnd(value: boolean);
// (undocumented)
Expand All @@ -160,7 +165,7 @@ export class CdkColumnDef extends _CdkColumnDefBase implements CanStick {
_table?: any;
protected _updateColumnCssClassName(): void;
// (undocumented)
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>;
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>;
// (undocumented)
static ɵfac: i0.ɵɵFactoryDeclaration<CdkColumnDef, [{ optional: true; }]>;
}
Expand Down Expand Up @@ -194,10 +199,16 @@ export class CdkFooterRow {
}

// @public
export class CdkFooterRowDef extends _CdkFooterRowDefBase implements CanStick, OnChanges {
export class CdkFooterRowDef extends BaseRowDef implements CanStick, OnChanges {
constructor(template: TemplateRef<any>, _differs: IterableDiffers, _table?: any);
hasStickyChanged(): boolean;
// (undocumented)
static ngAcceptInputType_sticky: unknown;
// (undocumented)
ngOnChanges(changes: SimpleChanges): void;
resetStickyChanged(): void;
get sticky(): boolean;
set sticky(value: boolean);
// (undocumented)
_table?: any;
// (undocumented)
Expand Down Expand Up @@ -235,10 +246,16 @@ export class CdkHeaderRow {
}

// @public
export class CdkHeaderRowDef extends _CdkHeaderRowDefBase implements CanStick, OnChanges {
export class CdkHeaderRowDef extends BaseRowDef implements CanStick, OnChanges {
constructor(template: TemplateRef<any>, _differs: IterableDiffers, _table?: any);
hasStickyChanged(): boolean;
// (undocumented)
static ngAcceptInputType_sticky: unknown;
// (undocumented)
ngOnChanges(changes: SimpleChanges): void;
resetStickyChanged(): void;
get sticky(): boolean;
set sticky(value: boolean);
// (undocumented)
_table?: any;
// (undocumented)
Expand Down

0 comments on commit 5ce0045

Please sign in to comment.