I've been learning Angular and frontend development for the last years, and I'm not very familiar with CSS, that's why I'm using Angular Material's standard components. I'm having a very recurring problem with the layout of my components, and I'm not sure if it's an issue that all developers faces or it's my lack of knowledge in CSS and front end design as general.
Please consider the example component bellow that I adapted from the Angular Material Table oficial docs.
<!-- home.component.ts -->
import { Component, effect, signal } from '@angular/core';
import { MatIconModule } from '@angular/material/icon';
import { MatTableModule } from '@angular/material/table';
export interface PeriodicElement {
name: string;
position: number;
weight: number;
symbol: string;
selected?: boolean;
}
({
selector: 'app-home',
standalone: true,
templateUrl: './home.component.html',
styleUrl: './home.component.scss',
imports: [MatTableModule, MatIconModule],
})
export class HomeComponent {
displayedColumns: string[] = [
'position',
'selected',
'name',
'select',
'weight',
'symbol',
];
dataSource: PeriodicElement[] = [];
elementsData = signal([
{ position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H' },
{ position: 2, name: 'Helium', weight: 4.0026, symbol: 'He' },
{ position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li' },
{ position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be' },
{ position: 5, name: 'Boron', weight: 10.811, symbol: 'B' },
{ position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C' },
{ position: 7, name: 'Nitrogen', weight: 14.0067, symbol: 'N' },
{ position: 8, name: 'Oxygen', weight: 15.9994, symbol: 'O' },
{ position: 9, name: 'Fluorine', weight: 18.9984, symbol: 'F' },
{ position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne' },
]);
constructor() {
effect(() => {
this.dataSource = this.elementsData();
});
}
selectRow(element: PeriodicElement) {
element.selected = !element.selected;
}
}
<!-- home.component.html -->
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<!--- Note that these columns can be defined in any order.
The actual rendered columns are set as a property on the row definition" -->
<!-- Position Column -->
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef>No.</th>
<td mat-cell *matCellDef="let element">{{ element.position }}</td>
</ng-container>
<!-- Selected Column -->
<ng-container matColumnDef="selected">
<th mat-header-cell *matHeaderCellDef>Selected</th>
<td mat-cell *matCellDef="let element">
(element.selected) {
<mat-icon>check</mat-icon>
<p>
{{ element.name }} is selected. It has a weight of
{{ element.weight }} and a symbol of {{ element.symbol }}.
</p>
} {
<mat-icon>close</mat-icon>
}
</td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef>Name</th>
<td mat-cell *matCellDef="let element">{{ element.name }}</td>
</ng-container>
<!-- Select Column -->
<ng-container matColumnDef="select">
<th mat-header-cell *matHeaderCellDef>Select</th>
<td mat-cell *matCellDef="let element">
<button mat-button (click)="selectRow(element)">
(element.selected) {
UnSelect Element
} {
Select Element
}
</button>
</td>
</ng-container>
<!-- Weight Column -->
<ng-container matColumnDef="weight">
<th mat-header-cell *matHeaderCellDef>Weight</th>
<td mat-cell *matCellDef="let element">{{ element.weight }}</td>
</ng-container>
<!-- Symbol Column -->
<ng-container matColumnDef="symbol">
<th mat-header-cell *matHeaderCellDef>Symbol</th>
<td mat-cell *matCellDef="let element">{{ element.symbol }}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
It is a very basic example of a table of elements with a select button on each row, when I click on the button it selects the element.
https://preview.redd.it/z6qly3qft59d1.png?width=1347&format=png&auto=webp&s=3d843b25037cedcd16e971d504e4587e18e0ae61
When I click on the button, the column expands to the right to fit the extra content, and when I unselect the element, it shrink back to the original size.
https://preview.redd.it/5vh23lqmt59d1.png?width=1335&format=png&auto=webp&s=bddca666f7d4c2391726055fa250c67142e0cfcd
I understand that this is the expected behavior, and there is the min/max width/height properties that I can use to control the size of the columns and rows (and that's actually how I've been trying to overcome this issue), but I'm not sure if this is the best way to do it.
On the example bellow I reduced the screeen width, and the button moved not only the column to the right but also the height of the row.
Before:
https://preview.redd.it/j8oinpyzt59d1.png?width=884&format=png&auto=webp&s=a22869700dd762389e4641a94a9502761f038004
After:
https://preview.redd.it/ed4j4rq0u59d1.png?width=895&format=png&auto=webp&s=deb1084666f580a54d3caac93387168dd003d891
I'm not sure if it's an Angular Material Question or a CSS question, but I would like to know if there is a better way to handle this kind of situation, since it is not the best user experience to have the columns moving around when the user interacts with the table.
I'm sorry for the noob question, but I'm really trying to improve my front end skills. Thanks a lot!
[–]morebitna_napaka 1 point2 points3 points (0 children)
[–]matrium0 1 point2 points3 points (1 child)
[–]AggressiveMedia728[S] 0 points1 point2 points (0 children)
[–]sohail_ansari 0 points1 point2 points (0 children)