# Angular Components Examples ## Introduction This project provides a comprehensive collection of working examples for Angular Material components, Angular CDK (Component Dev Kit), and experimental features. It serves as the official example library for the Angular Components project, offering developers ready-to-use code snippets demonstrating proper implementation patterns for Material Design UI components in Angular applications. The package contains hundreds of standalone component examples that showcase everything from basic buttons and inputs to complex data tables, drag-and-drop interfaces, and accessibility features. The examples are designed to be directly importable and runnable, making them ideal for rapid prototyping, learning Angular Material patterns, and understanding best practices for component integration. Each example is self-contained with its TypeScript component, HTML template, and CSS styling, compiled as ES2022 modules with full TypeScript type definitions. The package supports modular imports, allowing developers to load specific examples without bundling the entire library, and includes examples for Material components, CDK utilities, ARIA-compliant components, and experimental features under active development. ## Key Functions and APIs ### Loading Examples Dynamically ```typescript import { loadExample, EXAMPLE_COMPONENTS } from '@angular/components-examples'; // Get metadata for a specific example const buttonExample = EXAMPLE_COMPONENTS['button-overview']; console.log(buttonExample.title); // "Button overview" console.log(buttonExample.componentName); // "ButtonOverviewExample" console.log(buttonExample.files); // Array of file paths // Dynamically load an example component const exampleModule = await loadExample('button-overview'); // Returns the module containing ButtonOverviewExample component // Iterate through all available examples Object.keys(EXAMPLE_COMPONENTS).forEach(exampleId => { const example = EXAMPLE_COMPONENTS[exampleId]; console.log(`${exampleId}: ${example.title}`); }); ``` ### Material Button Component ```typescript import { Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { MatIconModule } from '@angular/material/icon'; @Component({ selector: 'app-button-demo', template: ` Link Button `, imports: [MatButtonModule, MatIconModule], }) export class ButtonDemoComponent {} ``` ### Material Table Component ```typescript import { Component } from '@angular/core'; import { MatTableModule } from '@angular/material/table'; export interface PeriodicElement { name: string; position: number; weight: number; symbol: string; } const ELEMENT_DATA: PeriodicElement[] = [ { 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' }, ]; @Component({ selector: 'app-table-demo', template: `
No. {{element.position}} Name {{element.name}} Weight {{element.weight}} Symbol {{element.symbol}}
`, imports: [MatTableModule], }) export class TableDemoComponent { displayedColumns: string[] = ['position', 'name', 'weight', 'symbol']; dataSource = ELEMENT_DATA; } ``` ### Material Dialog Component ```typescript import { Component, inject, model, signal } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MAT_DIALOG_DATA, MatDialog, MatDialogActions, MatDialogClose, MatDialogContent, MatDialogRef, MatDialogTitle, } from '@angular/material/dialog'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; export interface DialogData { animal: string; name: string; } @Component({ selector: 'app-dialog-demo', template: ` Name

Favorite animal: {{animal()}}

`, imports: [MatFormFieldModule, MatInputModule, FormsModule, MatButtonModule], }) export class DialogDemoComponent { readonly animal = signal(''); readonly name = model(''); readonly dialog = inject(MatDialog); openDialog(): void { const dialogRef = this.dialog.open(DialogContentComponent, { data: { name: this.name(), animal: this.animal() }, }); dialogRef.afterClosed().subscribe(result => { if (result !== undefined) { this.animal.set(result); } }); } } @Component({ selector: 'app-dialog-content', template: `

Favorite Animal

What's your favorite animal? `, imports: [ MatFormFieldModule, MatInputModule, FormsModule, MatButtonModule, MatDialogTitle, MatDialogContent, MatDialogActions, MatDialogClose, ], }) export class DialogContentComponent { readonly dialogRef = inject(MatDialogRef); readonly data = inject(MAT_DIALOG_DATA); readonly animal = model(this.data.animal); onNoClick(): void { this.dialogRef.close(); } } ``` ### Material Form Field and Input ```typescript import { Component } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { MatInputModule } from '@angular/material/input'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatSelectModule } from '@angular/material/select'; @Component({ selector: 'app-form-demo', template: ` Enter your name Choose an option Option 1 Option 2 Option 3 Enter description

Name: {{name}}

Selected: {{selectedOption}}

`, imports: [FormsModule, MatFormFieldModule, MatInputModule, MatSelectModule], }) export class FormDemoComponent { name = ''; selectedOption = ''; description = ''; } ``` ### Material Autocomplete ```typescript import { Component } from '@angular/core'; import { FormControl, ReactiveFormsModule } from '@angular/forms'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatInputModule } from '@angular/material/input'; import { MatFormFieldModule } from '@angular/material/form-field'; import { Observable } from 'rxjs'; import { map, startWith } from 'rxjs/operators'; @Component({ selector: 'app-autocomplete-demo', template: ` Choose a state {{option}} `, imports: [ ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatAutocompleteModule, ], }) export class AutocompleteDemoComponent { myControl = new FormControl(''); options: string[] = ['California', 'Colorado', 'Connecticut', 'Florida']; filteredOptions: Observable; constructor() { this.filteredOptions = this.myControl.valueChanges.pipe( startWith(''), map(value => this._filter(value || '')), ); } private _filter(value: string): string[] { const filterValue = value.toLowerCase(); return this.options.filter(option => option.toLowerCase().includes(filterValue) ); } } ``` ### Material Datepicker ```typescript import { Component } from '@angular/core'; import { MatDatepickerModule } from '@angular/material/datepicker'; import { MatInputModule } from '@angular/material/input'; import { MatFormFieldModule } from '@angular/material/form-field'; import { provideNativeDateAdapter } from '@angular/material/core'; import { FormControl, ReactiveFormsModule } from '@angular/forms'; @Component({ selector: 'app-datepicker-demo', template: ` Choose a date Date range

Selected date: {{dateControl.value | date}}

`, providers: [provideNativeDateAdapter()], imports: [ ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatDatepickerModule, ], }) export class DatepickerDemoComponent { dateControl = new FormControl(new Date()); } ``` ### Material Snackbar (Toast Notifications) ```typescript import { Component, inject } from '@angular/core'; import { MatSnackBar } from '@angular/material/snack-bar'; import { MatButtonModule } from '@angular/material/button'; @Component({ selector: 'app-snackbar-demo', template: ` `, imports: [MatButtonModule], }) export class SnackbarDemoComponent { private _snackBar = inject(MatSnackBar); openSnackBar(message: string, action: string) { this._snackBar.open(message, action); } openSnackBarWithAction() { const snackBarRef = this._snackBar.open('Item deleted', 'Undo', { duration: 3000, }); snackBarRef.onAction().subscribe(() => { console.log('Undo action triggered'); }); } openSnackBarWithConfig() { this._snackBar.open('Connection error', 'Retry', { duration: 5000, horizontalPosition: 'end', verticalPosition: 'top', panelClass: ['error-snackbar'], }); } } ``` ### Material Checkbox ```typescript import { Component, signal, computed } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { MatCheckboxModule } from '@angular/material/checkbox'; export interface Task { name: string; completed: boolean; subtasks?: Task[]; } @Component({ selector: 'app-checkbox-demo', template: ` {{task().name}}
{{subtask.name}}
`, imports: [MatCheckboxModule, FormsModule], }) export class CheckboxDemoComponent { readonly task = signal({ name: 'Complete project', completed: false, subtasks: [ { name: 'Design mockups', completed: false }, { name: 'Implement features', completed: false }, { name: 'Write tests', completed: false }, ], }); readonly partiallyComplete = computed(() => { const task = this.task(); if (!task.subtasks) return false; return task.subtasks.some(t => t.completed) && !task.subtasks.every(t => t.completed); }); update(completed: boolean) { this.task.update(task => { task.completed = completed; task.subtasks?.forEach(t => (t.completed = completed)); return { ...task }; }); } updateSubtask(index: number) { this.task.update(task => { task.completed = task.subtasks?.every(t => t.completed) ?? true; return { ...task }; }); } } ``` ### Material Sidenav (Drawer) ```typescript import { Component } from '@angular/core'; import { MatSidenavModule } from '@angular/material/sidenav'; import { MatButtonModule } from '@angular/material/button'; @Component({ selector: 'app-sidenav-demo', template: `

Menu

  • Item 1
  • Item 2
  • Item 3

Main Content

Content goes here

`, imports: [MatSidenavModule, MatButtonModule], }) export class SidenavDemoComponent {} ``` ### Material Slider ```typescript import { Component } from '@angular/core'; import { MatSliderModule } from '@angular/material/slider'; import { FormsModule } from '@angular/forms'; @Component({ selector: 'app-slider-demo', template: `

Value: {{value}}

Range: {{rangeStart}} - {{rangeEnd}}

`, imports: [MatSliderModule, FormsModule], }) export class SliderDemoComponent { value = 50; rangeStart = 20; rangeEnd = 80; } ``` ### CDK Drag and Drop ```typescript import { Component } from '@angular/core'; import { CdkDrag, CdkDropList, CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; @Component({ selector: 'app-drag-drop-demo', template: `
{{item}}
`, imports: [CdkDrag, CdkDropList], }) export class DragDropDemoComponent { items = ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5']; drop(event: CdkDragDrop) { moveItemInArray(this.items, event.previousIndex, event.currentIndex); } } ``` ### CDK Clipboard ```typescript import { Component } from '@angular/core'; import { ClipboardModule, Clipboard } from '@angular/cdk/clipboard'; import { MatButtonModule } from '@angular/material/button'; import { inject } from '@angular/core'; @Component({ selector: 'app-clipboard-demo', template: ` `, imports: [ClipboardModule, MatButtonModule], }) export class ClipboardDemoComponent { private clipboard = inject(Clipboard); value = 'Text to copy'; copyProgrammatically() { const successful = this.clipboard.copy(this.value); console.log('Copy successful:', successful); } } ``` ### CDK Focus Monitor (Accessibility) ```typescript import { Component, ElementRef, ViewChild, AfterViewInit, OnDestroy, inject } from '@angular/core'; import { FocusMonitor, FocusOrigin } from '@angular/cdk/a11y'; @Component({ selector: 'app-focus-monitor-demo', template: `

Focus origin: {{elementOrigin}}

Subtree monitoring

Subtree focus origin: {{subtreeOrigin}}

`, }) export class FocusMonitorDemoComponent implements AfterViewInit, OnDestroy { private focusMonitor = inject(FocusMonitor); @ViewChild('monitoredButton') monitoredButton: ElementRef; @ViewChild('subtreeElement') subtreeElement: ElementRef; elementOrigin = 'none'; subtreeOrigin = 'none'; ngAfterViewInit() { // Monitor focus on a specific element this.focusMonitor.monitor(this.monitoredButton).subscribe(origin => { this.elementOrigin = this.formatOrigin(origin); }); // Monitor focus within a subtree this.focusMonitor.monitor(this.subtreeElement, true).subscribe(origin => { this.subtreeOrigin = this.formatOrigin(origin); }); } ngOnDestroy() { this.focusMonitor.stopMonitoring(this.monitoredButton); this.focusMonitor.stopMonitoring(this.subtreeElement); } formatOrigin(origin: FocusOrigin): string { return origin ? `${origin} focused` : 'blurred'; } } ``` ## Use Cases and Integration This package is primarily used as a reference library for Angular developers building applications with Angular Material. Developers can import individual examples into their documentation sites, use them as starting points for custom components, or study them to understand proper implementation patterns. The examples are particularly valuable for teams adopting Material Design principles, as they demonstrate not just component usage but also proper accessibility practices, responsive design patterns, and integration with Angular's reactive forms system. For integration into applications, developers can either copy code directly from the example source files or use the dynamic loading API to embed live examples in documentation sites. The modular structure allows selective imports, keeping bundle sizes small. Common integration patterns include using examples in component galleries, interactive documentation systems, prototyping tools, and educational materials. The package also serves as a test bed for the Angular Material library itself, with each example demonstrating stable, production-ready implementations that have been thoroughly tested across different Angular versions and browser environments.