Custom Toast Component in Lightning Web Components

In my previous post I have shared toast component in lightning. Now we will convert that component in Lightning Web Components ( LWC ). LWC also provide standard toast event. But they are not supported everywhere, So today we will create an component which support all UI experience.

We will also call child component method from parent component. In Lightning we use Aura:method for this but as in LWC we don’t have Aura:method so we will use different approach.

In our current component we will use both standard and custom code, so you can use any one of them as per your requirement. This is how our output will look.

Lightning Web Component LWC toastcomponent

Now we check the code

lwcCustomToast.html

<template>

    <!-- Comment this code if you want to hide this-->
    <lightning-card title="Custom Toast Notification" icon-name="custom:custom19">
        <div class="slds-m-around_medium">
            <lightning-input label="Title" value={title} onchange={titleChange}></lightning-input>
            <lightning-input label="Message" value={message} onchange={messageChange}></lightning-input>
            <lightning-combobox
                label="Variant"
                value={variant}
                onchange={variantChange}
                options={variantOptions}>
            </lightning-combobox>
            <p class="slds-m-vertical_small"><lightning-button label="Show Standard Notification" onclick={showNotification}></lightning-button></p>
            <p class="slds-m-vertical_small"><lightning-button label="Show Custom Notification" onclick={showCustomNotice}></lightning-button></p>
        </div>
    </lightning-card>
    <!-- Comment this code if you want to hide this-->

    
    <div data-id="toastModel" style="height: 4rem;" class="slds-hide">
        <div class="slds-notify_container slds-is-relative">
            <div class={mainDivClass} role="status">
                <span class="slds-assistive-text">{variant}</span>
              	<span class={messageDivClass} title={message}>
                  <lightning-icon icon-name={iconName} size="small" variant="inverse"></lightning-icon>
                </span>
                <div class="slds-notify__content">
                    <h2 class="slds-text-heading_small ">{message}</h2>
                </div>
                <div class="slds-notify__close">
                    <button class="slds-button slds-button_icon slds-button_icon-inverse" title="Close" onclick={closeModel}>
                        <lightning-icon icon-name="utility:close" size="small" variant="inverse"> </lightning-icon>
                        <span class="slds-assistive-text">Close</span>
                    </button>
                </div> 
            </div>
        </div>
    </div>
</template>

lwcCustomToast.js

import { LightningElement, api } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

export default class MiscNotification extends LightningElement {
    @api title = 'Sample Title';
    @api message = 'Sample Message';
    @api variant = 'error';
    @api autoCloseTime = 5000;
    @api autoClose = false;
    @api autoCloseErrorWarning = false;

    variantOptions = [
        { label: 'error', value: 'error' },
        { label: 'warning', value: 'warning' },
        { label: 'success', value: 'success' },
        { label: 'info', value: 'info' },
    ];

    titleChange(event) {
        this.title = event.target.value;
    }

    messageChange(event) {
        this.message = event.target.value;
    }

    variantChange(event) {
        this.variant = event.target.value;
    }

    showNotification() {

        if(ShowToastEvent) {
            
            const evt = new ShowToastEvent({
                title: this.title,
                message: this.message,
                variant: this.variant,
            });

            this.dispatchEvent(evt);

        }
    }

    @api
    showCustomNotice() {
        
        const toastModel = this.template.querySelector('[data-id="toastModel"]');
        toastModel.className = 'slds-show';
        
        if(this.autoClose)
            if( (this.autoCloseErrorWarning && this.variant !== 'success') || this.variant === 'success') {
                this.delayTimeout = setTimeout(() => {
                    const toastModel = this.template.querySelector('[data-id="toastModel"]');
                    toastModel.className = 'slds-hide';
                }, this.autoCloseTime);
                
        }
    }

    closeModel() {
        const toastModel = this.template.querySelector('[data-id="toastModel"]');
        toastModel.className = 'slds-hide';
    }

    get mainDivClass() { 
        return 'slds-notify slds-notify_toast slds-theme_'+this.variant;
      }

    get messageDivClass() { 
        return 'slds-icon_container slds-icon-utility-'+this.variant+' slds-icon-utility-success slds-m-right_small slds-no-flex slds-align-top';
    }
    get iconName() {
        return 'utility:'+this.variant;
    }
}

Here we have declared method with @api so that we can call it from parent component. we are also using getter method to dynamically set the name. We are using this.template.querySelector to find the element and set and remove the css class.

We should not use Id here as when rendering the component Salesforce can change the id to make it globally unique. Thats why in our code we have used data-id attribute.

Now to call this component is very easy.

lwcToastContainer.html

<template>
    <c-lwc-custom-toast title = "Hello NewsTechnologyStuff" message = "We have created custom Toast component in LWC"
    variant="success" auto-close="true" ></c-lwc-custom-toast>
<!-- define component with all attributes values -->
    <p class="slds-m-vertical_small"><lightning-button label="Show Toast from Outer Comp" onclick={showCustomNotice}></lightning-button></p>
</template>

lwcToastContainer.js

import { LightningElement } from 'lwc';

export default class LwcToastContainer extends LightningElement {

    showCustomNotice() {
        //Here we are calling  child component method
        this.template.querySelector('c-lwc-custom-toast').showCustomNotice();
    }
}

So now our component is ready and we can use it. As Salesforce is pushing LWC so it will be great if we convert our component from lightning to LWC.

Did you like the post or wants to add anything let me know in comments sections. Happy programming 🙂

Advertisements

2 thoughts on “Custom Toast Component in Lightning Web Components

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.