@gitlab/ui
Version:
GitLab UI Components
67 lines (55 loc) • 1.79 kB
JavaScript
/* eslint-disable import/no-default-export */
import Vue from 'vue';
import { createNewChildComponent } from '../../../vendor/bootstrap-vue/src/utils/create-new-child-component';
import GlToaster from './toaster.vue';
let toastsCount = 0;
let toasterInstance = null;
function ensureToaster(vm) {
if (toasterInstance) {
const portalTarget = document.getElementById('gl-toaster');
if (portalTarget && document.body.contains(portalTarget)) {
return toasterInstance;
}
toasterInstance.$destroy();
toasterInstance = null;
}
const ToasterComponent = Vue.extend(GlToaster);
toasterInstance = createNewChildComponent(vm, ToasterComponent);
toasterInstance.$mount(document.createElement('div'));
return toasterInstance;
}
function showToast(message, options = {}) {
const toaster = ensureToaster(this);
// eslint-disable-next-line @gitlab/tailwind-no-interpolation -- Not a CSS utility
const id = `gl-toast-${toastsCount}`;
toastsCount += 1;
const hide = () => toaster.hideToast(id);
const toast = { id, hide };
const autoHideDelay = !Number.isNaN(options?.autoHideDelay) ? options.autoHideDelay : undefined;
toaster.addToast({
id,
message,
action: options.action || null,
autoHideDelay,
onComplete: options.onComplete || null,
});
return toast;
}
/**
* Note: This is not a typical Vue component and needs to be registered before instantiating a Vue app.
* Once registered, the toast will be globally available throughout your app.
*
* See https://design.gitlab.com/storybook for detailed documentation.
*/
export default {
install(V) {
V.mixin({
beforeCreate() {
if (this.$toast) {
return;
}
this.$toast = { show: showToast.bind(this) };
},
});
},
};