(resolve => {
if (toastStack.parentElement === null) {
document.body.append(toastStack);
}
toastStack.appendChild(this);
// Wait for the toast stack to render
requestAnimationFrame(() => {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- force a reflow for the initial transition
this.clientWidth;
this.show();
});
this.addEventListener(
'sl-after-hide',
() => {
toastStack.removeChild(this);
resolve();
// Remove the toast stack from the DOM when there are no more alerts
if (toastStack.querySelector('sl-alert') === null) {
toastStack.remove();
}
},
{ once: true }
);
});
}
restartAutoHide() {
clearTimeout(this.autoHideTimeout);
if (this.open && this.duration < Infinity) {
this.autoHideTimeout = window.setTimeout(() => this.hide(), this.duration);
}
}
handleCloseClick() {
this.hide();
}
handleMouseMove() {
this.restartAutoHide();
}
@watch('open', { waitUntilFirstUpdate: true })
async handleOpenChange() {
if (this.open) {
// Show
emit(this, 'sl-show');
if (this.duration < Infinity) {
this.restartAutoHide();
}
await stopAnimations(this.base);
this.base.hidden = false;
const { keyframes, options } = getAnimation(this, 'alert.show');
await animateTo(this.base, keyframes, options);
emit(this, 'sl-after-show');
} else {
// Hide
emit(this, 'sl-hide');
clearTimeout(this.autoHideTimeout);
await stopAnimations(this.base);
const { keyframes, options } = getAnimation(this, 'alert.hide');
await animateTo(this.base, keyframes, options);
this.base.hidden = true;
emit(this, 'sl-after-hide');
}
}
@watch('duration')
handleDurationChange() {
this.restartAutoHide();
}
render() {
return html`
${this.closable
? html`
`
: ''}
`;
}
}
setDefaultAnimation('alert.show', {
keyframes: [
{ opacity: 0, transform: 'scale(0.8)' },
{ opacity: 1, transform: 'scale(1)' }
],
options: { duration: 250, easing: 'ease' }
});
setDefaultAnimation('alert.hide', {
keyframes: [
{ opacity: 1, transform: 'scale(1)' },
{ opacity: 0, transform: 'scale(0.8)' }
],
options: { duration: 250, easing: 'ease' }
});
declare global {
interface HTMLElementTagNameMap {
'sl-alert': SlAlert;
}
}