Im trying to implement a responsive table directive in my angular app, which sets the min and max width and font-size of the columns in a MatTable.
These values are based on the parent containers width, and the number of columns.
The directive gets the column definitions as an input array of strings.(eg.[“ordernum”,”ordername”,”timestamp”])
Currently the code looks like this:
@Input('ResponsiveTable') columns: string[] = [];
...
constructor(
private el: ElementRef,
private host: MatTable<any>,
private breakpointObserver: BreakpointObserver
) {}
....
ngOnInit(): void {
//set table style props
this.el.nativeElement.style.minWidth =
minCellWidth * this.columns.length + 'px';
this.el.nativeElement.style.width = tableWidth + '%';
// //subscriptions
this.subscriptions.push(
this.host.contentChanged.subscribe(() =>
setTimeout(() => this.initStyle())
)
);
}
...
initStyle() {
//get tableSize
const parentWidth = this.el.nativeElement.parentNode.clientWidth;
this.maxColumnWidth =
parentWidth / this.columns.length > minCellWidth
? parentWidth / this.columns.length
: minCellWidth;
//set the headers, and maxWidth
this.el.nativeElement.querySelectorAll('th').forEach((header: any) => {
header.style.maxWidth = this.maxColumnWidth + 'px';
header.style.fontSize = `calc(8px + 0.25vw + 0.5vw / ${this.columns.length})`;
header.style.padding = '6px';
});
//set the table cells and maxWidth
this.el.nativeElement.querySelectorAll('td').forEach((cell: any) => {
cell.style.maxWidth = this.maxColumnWidth + 'px';
cell.style.fontSize = `calc(8px + 0.25vw + 0.5vw / ${this.columns.length})`;
});
this.initBreakpointObserver();
this.tableWidth = this.el.nativeElement.width;
}
I think this is not efficient, because every time a content change happens, I have to query all the cells and headers, to set their max and min width.
It would be nice to add some CSS to the parent element, that selects all its children mat-cells and mat-headers, and set their size. Sadly I cant use a classic CSS class beacause the size value is based on the number of table columns.
Is there a way to progmatically add a CSS class that selects all the children cells and applies the style to them, even if a new row is added?
Or what could be a better solution?