Angular Material 19 components, Material 3 theming, CDK with 2D drag-drop, timepicker, custom form controls, and dark mode...
Reference files (loaded on demand):
Material 3 is now the default design system. Key features:
--mat-* variableslight-dark() function — Native CSS for theme switchingmat-timepicker) — Native time selection → see timepicker.md// Forms
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatTimepickerModule } from '@angular/material/timepicker'; // NEW v19
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
// Buttons & Icons
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
// Layout
import { MatCardModule } from '@angular/material/card';
import { MatTabsModule } from '@angular/material/tabs';
import { MatExpansionModule } from '@angular/material/expansion';
// Data Display
import { MatTableModule } from '@angular/material/table';
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatSortModule } from '@angular/material/sort';
import { MatChipsModule } from '@angular/material/chips';
import { MatTooltipModule } from '@angular/material/tooltip';
// Feedback
import { MatDialogModule } from '@angular/material/dialog';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
// CDK
import { DragDropModule } from '@angular/cdk/drag-drop';
import { OverlayModule } from '@angular/cdk/overlay';
import { Component, inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef, MatDialogModule } from '@angular/material/dialog';
import { MatButtonModule } from '@angular/material/button';
@Component({
selector: 'confirm-dialog',
imports: [MatDialogModule, MatButtonModule],
template: `
<h2 mat-dialog-title>{{ data.title }}</h2>
<mat-dialog-content>
<p>{{ data.message }}</p>
</mat-dialog-content>
<mat-dialog-actions align="end">
<button mat-button mat-dialog-close>Cancel</button>
<button mat-flat-button color="warn" [mat-dialog-close]="true">
{{ data.confirmText ?? 'Confirm' }}
</button>
</mat-dialog-actions>
`,
})
export class ConfirmDialogComponent
{
readonly data = inject<{ title: string; message: string; confirmText?: string }>(MAT_DIALOG_DATA);
}
import { Component, signal, computed, viewChild } from '@angular/core';
import { MatTableModule } from '@angular/material/table';
import { MatSortModule, MatSort, Sort } from '@angular/material/sort';
import { MatPaginatorModule, MatPaginator, PageEvent } from '@angular/material/paginator';
@Component({
selector: 'app-data-table',
imports: [MatTableModule, MatSortModule, MatPaginatorModule],
template: `
<table [dataSource]="dataSource()" mat-table matSort
(matSortChange)="onSortChange($event)">
<!-- columns -->
<tr *matHeaderRowDef="displayedColumns" mat-header-row></tr>
<tr *matRowDef="let row; columns: displayedColumns" mat-row></tr>
</table>
<mat-paginator [length]="totalItems()" [pageSize]="pageSize()"
[pageSizeOptions]="[10, 25, 50]"
(page)="onPageChange($event)"></mat-paginator>
`,
})
export class DataTableComponent {
data = signal<any[]>([]);
totalItems = signal(0);
pageSize = signal(10);
sort = viewChild(MatSort);
paginator = viewChild(MatPaginator);
displayedColumns = ['name', 'email', 'actions'];
dataSource = computed(() => this.data());
onSortChange(sort: Sort): void { /* update & reload */ }
onPageChange(event: PageEvent): void { /* update & reload */ }
}
| Avoid | Do Instead |
|---|---|
@ViewChild(MatSort) decorator |
viewChild(MatSort) signal query |
Manual stateChanges.next() calls everywhere |
Use effect() to auto-emit on signal changes |
| Importing entire Material module | Import only needed component modules |
Using any for dialog data |
Create typed interfaces |
| Hardcoded colors in components | Use --mat-sys-* CSS variables |
@media (prefers-color-scheme) manually |
Use light-dark() function in theme |
| Custom dark mode class logic | Set color-scheme: light dark on html |
| Using third-party timepicker | Use native mat-timepicker (v19+) |
mat-timepicker@ViewChild queries to signal queriesmat.theme() mixinlight-dark() function| Skill | When to Use Together |
|---|---|
angular-19 |
Angular 19 patterns, signals, resource API |
tailwind |
Combined Tailwind + Material styling |
typescript |
TypeScript patterns for typed components |