Lightning Web Components – How to Slide an Element In and Out

I'm building a Lightning Web Component for a standalone Aura app where ShowToastEvent isn't available. I've seen an example of a custom LWC toast component that shows and hides itself using slds-show and slds-hide.

This component works OK, but it seems to appear and disappear kind of abruptly. What I'd like to do is have the element gracefully slide down from the top when it's shown, and slide up and out of view when it's hidden. I'm not expert enough in CSS to know the most elegant way to accomplish this that would play well with the existing SLDS framework.

Here's a playground link to get folks started. Thanks in advance!


2022 update

Since this post is frequently viewed and the LWC playground is no longer available, here is some code folks can use to get started with their custom animated toast components:

toast.html

<template>
    <div data-id="toastModel" class={className}>
        <div class="slds-notify_container">
            <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 data-id="title" class="slds-text-heading_small">
                        {title}
                    </h2>
                    <template if:true={message}>
                        <lightning-formatted-rich-text
                            data-id="message"
                            value={message}
                        ></lightning-formatted-rich-text>
                    </template>
                </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>

toast.js

import { LightningElement, api } from "lwc";

export default class Toast extends LightningElement {
    title;
    message;
    variant;
    className = "slds-hide";

    /**
     * Shows a toast message
     * @param {string} title - The title of the message
     * @param {string} message - The body of the message; can include HTML tags that are supported for lightning-formatted-rich-text
     * @param {string} variant - The theme of the message; available values include "error", "warning", "success", and "info"
     * @param {boolean} [autoClose=false] - (Optional) Determines whether the toast should close automatically after the default or
     * specified amount of time. Defaults to false.
     * @param {number} [autoCloseTime=5000] - (Optional) Amount of time in milliseconds before the toast auto-closes. Defaults
     * to 5000 ms.
     */
    @api
    showToast(
        title,
        message,
        variant,
        autoClose = false,
        autoCloseTime = 5000
    ) {
        this.title = title;
        this.message = message;
        this.variant = variant;
        this.className = "slds-show";

        if (autoClose) {
            // eslint-disable-next-line @lwc/lwc/no-async-operation
            setTimeout(() => {
                this.closeModel();
            }, autoCloseTime);
        }
    }

    closeModel() {
        this.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;
    }
}

toast.css

.slds-show .slds-notify_container {
    animation: 0.5s forwards enter;
}

@keyframes enter {
    from {
        top: 0rem;
        opacity: 0;
    }
    to {
        top: 1rem;
        opacity: 1;
    }
}

Best Answer

Taake a look at the changes I've made here: https://developer.salesforce.com/docs/component-library/tools/playground/c_TB0R6b/13/edit

I've removed the slds-is-relative class on line 3 of toast.html, and added a few rules to toast.css. Cheers!

Related Topic