Skip to content

Commit

Permalink
fix(table): column class names should be css friendly (#6173)
Browse files Browse the repository at this point in the history
* fix(table): column class names should be css friendly

* rename function

* add to docs, replace with -, make var

* fix test
  • Loading branch information
andrewseguin authored and tinayuangao committed Aug 2, 2017
1 parent 953b38e commit 1748397
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 5 deletions.
11 changes: 11 additions & 0 deletions guides/cdk-table.md
Expand Up @@ -107,6 +107,17 @@ Event and property bindings can be added directly to the row element.
</cdk-row>
```

##### Styling columns

Each header and row cell will be provided a CSS class that includes its column. For example,
cells that are displayed in the column `name` will be given the class `cdk-column-name`. This allows
columns to be given styles that will match across the header and rows.

Since columns can be given any string for its name, its possible that it cannot be directly applied
to the CSS class (e.g. `*nameColumn!`). In these cases, the special characters will be replaced by
the `-` character. For example, cells container in a column named `*nameColumn!` will be given
the class `cdk-column--nameColumn-`.

#### Connecting the table to a data source

Data is provided to the table through a `DataSource`. When the table receives a data source,
Expand Down
19 changes: 16 additions & 3 deletions src/cdk/table/cell.ts
Expand Up @@ -33,13 +33,26 @@ export class CdkHeaderCellDef {
@Directive({selector: '[cdkColumnDef]'})
export class CdkColumnDef {
/** Unique name for this column. */
@Input('cdkColumnDef') name: string;
@Input('cdkColumnDef')
get name(): string { return this._name; }
set name(name: string) {
this._name = name;
this.cssClassFriendlyName = name.replace(/[^a-z0-9_-]/ig, '-');
}
_name: string;

/** @docs-private */
@ContentChild(CdkCellDef) cell: CdkCellDef;

/** @docs-private */
@ContentChild(CdkHeaderCellDef) headerCell: CdkHeaderCellDef;

/**
* Transformed version of the column name that can be used as part of a CSS classname. Excludes
* all non-alphanumeric characters and the special characters '-' and '_'. Any characters that
* do not match are replaced by the '-' character.
*/
cssClassFriendlyName: string;
}

/** Header cell template container that adds the right classes and role. */
Expand All @@ -52,7 +65,7 @@ export class CdkColumnDef {
})
export class CdkHeaderCell {
constructor(columnDef: CdkColumnDef, elementRef: ElementRef, renderer: Renderer2) {
renderer.addClass(elementRef.nativeElement, `cdk-column-${columnDef.name}`);
renderer.addClass(elementRef.nativeElement, `cdk-column-${columnDef.cssClassFriendlyName}`);
}
}

Expand All @@ -66,6 +79,6 @@ export class CdkHeaderCell {
})
export class CdkCell {
constructor(columnDef: CdkColumnDef, elementRef: ElementRef, renderer: Renderer2) {
renderer.addClass(elementRef.nativeElement, `cdk-column-${columnDef.name}`);
renderer.addClass(elementRef.nativeElement, `cdk-column-${columnDef.cssClassFriendlyName}`);
}
}
32 changes: 32 additions & 0 deletions src/cdk/table/table.spec.ts
Expand Up @@ -29,6 +29,7 @@ describe('CdkTable', () => {
RowContextCdkTableApp,
DuplicateColumnDefNameCdkTableApp,
MissingColumnDefCdkTableApp,
CrazyColumnNameCdkTableApp,
],
}).compileComponents();
}));
Expand Down Expand Up @@ -97,6 +98,17 @@ describe('CdkTable', () => {
});
});

it('should be able to apply class-friendly css class names for the column cells', () => {
const crazyColumnNameAppFixture = TestBed.createComponent(CrazyColumnNameCdkTableApp);
const crazyColumnNameTableElement =
crazyColumnNameAppFixture.nativeElement.querySelector('cdk-table');
crazyColumnNameAppFixture.detectChanges();

// Column was named 'crazy-column-NAME-1!@#$%^-_&*()2'
expect(getHeaderCells(crazyColumnNameTableElement)[0].classList)
.toContain('cdk-column-crazy-column-NAME-1-------_----2');
});

it('should disconnect the data source when table is destroyed', () => {
expect(dataSource.isConnected).toBe(true);

Expand Down Expand Up @@ -682,6 +694,26 @@ class CustomRoleCdkTableApp {
@ViewChild(CdkTable) table: CdkTable<TestData>;
}

@Component({
template: `
<cdk-table [dataSource]="dataSource">
<ng-container [cdkColumnDef]="columnsToRender[0]">
<cdk-header-cell *cdkHeaderCellDef> Column A</cdk-header-cell>
<cdk-cell *cdkCellDef="let row"> {{row.a}}</cdk-cell>
</ng-container>
<cdk-header-row *cdkHeaderRowDef="columnsToRender"></cdk-header-row>
<cdk-row *cdkRowDef="let row; columns: columnsToRender"></cdk-row>
</cdk-table>
`
})
class CrazyColumnNameCdkTableApp {
dataSource: FakeDataSource = new FakeDataSource();
columnsToRender = ['crazy-column-NAME-1!@#$%^-_&*()2'];

@ViewChild(CdkTable) table: CdkTable<TestData>;
}

@Component({
template: `
<cdk-table [dataSource]="dataSource">
Expand Down
4 changes: 2 additions & 2 deletions src/lib/table/cell.ts
Expand Up @@ -68,7 +68,7 @@ export class MdHeaderCell extends _MdHeaderCell {
elementRef: ElementRef,
renderer: Renderer2) {
super(columnDef, elementRef, renderer);
renderer.addClass(elementRef.nativeElement, `mat-column-${columnDef.name}`);
renderer.addClass(elementRef.nativeElement, `mat-column-${columnDef.cssClassFriendlyName}`);
}
}

Expand All @@ -85,6 +85,6 @@ export class MdCell extends _MdCell {
elementRef: ElementRef,
renderer: Renderer2) {
super(columnDef, elementRef, renderer);
renderer.addClass(elementRef.nativeElement, `mat-column-${columnDef.name}`);
renderer.addClass(elementRef.nativeElement, `mat-column-${columnDef.cssClassFriendlyName}`);
}
}

0 comments on commit 1748397

Please sign in to comment.