Creating Angular Components with Material Components Web
Creating Angular Components with Material Components Web

Creating Angular Components with Material Components Web

# Creating Banner: Simple Approach In this approach we will create [banner](https://m2.material.io/components/banners) component in Angular using Material Components Web using simple approach. The straightforward procedure can be summarized as follows: 1. Incorporate the Component's CSS on the webpage in any preferred manner. 2. Construct a **wrapper component** for Angular, and add a property that will be assigned the value of the MDC Web Component. Let's refer to this as `mdcComponent`. 3. Upon **initialization** of the wrapper component (for instance, when it's instantiated and connected to the DOM), instantiate the MDC Web component with a root element, and assign it to the mdcComponent property. 4. When the wrapper component is **destroyed** (like when it's unbound and detached from the DOM), invoke `mdcComponent.destroy()` to clean up the MDC Web component. Let's get started! ## 1. Create a wrapper component ```bash ng g c shared/components/banner-simple ``` ## 2 Component template Let's keep the simple template from [official docs](https://m2.material.io/components/banners/web#using-banners): ```html ``` ## 3 Component implementation It's time to make changes so that `MDCBanner` is initialized and works as expected: ```ts @Component({ selector: 'app-banner-simple', standalone: true, imports: [CommonModule], templateUrl: './banner-simple.component.html' }) export class BannerSimpleComponent implements OnDestroy { private _elementRef = inject(ElementRef); mdcBanner: MDCBanner | undefined; constructor() { afterNextRender( () => { if (this.elementRef) { const element = this.elementRef.nativeElement.querySelector('.mdc-banner'); if (element) { // 1. Render banner this.banner = new MDCBanner(element); // 2. Render buttons element.querySelectorAll('.mdc-button').forEach((btnEle) => { this.mdcButtons.push(new MDCRipple(btnEle)); }); } } }, { phase: AfterRenderPhase.Write } ); } ngOnDestroy(): void { this.mdcBanner?.destroy(); } } ``` Below are few things to note in above code: 1. We are using `afterNextRender` hook, so that code builds fine even when SSR is enabled 2. As you can see, we are simply using `MDCBanner` constructor to create the banner. 3. We are also calling `mdcBanner.open()` so that banner is opened and visible. ## 4. Component styles Now, for styling we will import needed styles in `src/styles/_banner.scss`: ```scss // src/styles/_banner.scss @use "@material/banner/styles"; @use "@material/button/styles" as mdcButtonStyles; ``` And we will use that in main `styles.scss`: ```scss // src/styles.scss @use "./styles/banner"; ``` ## 5. Component usage Now we can simply use `app-banner-simple` like below: ```html ``` ## 6. Making it better We can even make the component better to support all options of [banner](https://m2.material.io/components/banners/web#banners) with `@Input`s and providing more methods to interact with banner. Below is the full code: ```html
{{ text }}
{{ secondaryAction }}
{{ primaryAction }}
``` ```ts // src/app/shared/components/banner-simple/banner-simple.component.ts import { AfterRenderPhase, AfterViewInit, Component, ElementRef, Input, OnDestroy, ViewChild, afterNextRender, afterRender, inject, } from '@angular/core'; import { CommonModule } from '@angular/common'; import { CloseReason, MDCBanner } from '@material/banner'; import { MDCRipple } from '@material/ripple'; @Component({ selector: 'app-banner-simple', standalone: true, imports: [CommonModule], templateUrl: './banner-simple.component.html', }) export class BannerSimpleComponent implements OnDestroy { @Input() primaryAction: string = ''; @Input() secondaryAction: string = ''; @Input({ required: true }) text!: string; @Input() centered: boolean = false; @Input() fixed: boolean = false; @Input() mobileStacked: boolean = false; banner!: MDCBanner; @ViewChild('mdcBanner') mdcBanner!: ElementRef; elementRef = inject>(ElementRef); mdcButtons: MDCRipple[] = []; constructor() { afterNextRender( () => { if (this.elementRef) { const element = this.elementRef.nativeElement.querySelector('.mdc-banner'); if (element) { // 1. Render banner this.banner = new MDCBanner(element); // 2. Render buttons element.querySelectorAll('.mdc-button').forEach((btnEle) => { this.mdcButtons.push(new MDCRipple(btnEle)); }); } } }, { phase: AfterRenderPhase.Write } ); } ngOnDestroy(): void { this.mdcButtons.forEach((btn) => btn.destroy()); this.banner?.destroy(); } open() { this.banner.open(); } close(reason: CloseReason = CloseReason.UNSPECIFIED) { this.banner.close(reason); } } ```
Support Free Content Creation

Contributions & Support

Even though the courses and articles are available at no cost, your support in my endeavor to deliver top-notch educational content would be highly valued. Your decision to contribute aids me in persistently improving the course, creating additional resources, and maintaining the accessibility of these materials for all. I'm grateful for your consideration to contribute and make a meaningful difference!

Envelop
Don't miss any update

Stay up to date

Subscribe to the newsletter to stay up to date with articles, courses and much more!

Angular Material Dev

Angular Material Dev is one place stop for developers to learn about integrating Material Design in Angular applications like a pro.

Find us on X (Twitter) and LinkedIn