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;
}
}