bootstrap-vue
Version:
BootstrapVue, with over 40 plugins and more than 80 custom components, custom directives, and over 300 icons, provides one of the most comprehensive implementations of Bootstrap v4 components and grid system for Vue.js. With extensive and automated WAI-AR
150 lines (139 loc) • 3.84 kB
JavaScript
import Vue from '../../utils/vue';
import { PortalTarget, Wormhole } from 'portal-vue';
import { getComponentConfig } from '../../utils/config';
import { removeClass, requestAF } from '../../utils/dom';
import { warn } from '../../utils/warn'; // --- Constants ---
var NAME = 'BToaster';
export var props = {
name: {
type: String,
required: true
},
ariaLive: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'ariaLive');
}
},
ariaAtomic: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'ariaAtomic');
} // Allowed: 'true' or 'false' or null
},
role: {
// Aria role
type: String,
default: function _default() {
return getComponentConfig(NAME, 'role');
}
}
/*
transition: {
type: [Boolean, String, Object],
default: false
}
*/
}; // @vue/component
export var DefaultTransition =
/*#__PURE__*/
Vue.extend({
data: function data() {
return {
// Transition classes base name
name: 'b-toaster'
};
},
methods: {
onAfterEnter: function onAfterEnter(el) {
var _this = this;
// Handle bug where enter-to class is not removed.
// Bug is related to portal-vue and transition-groups.
requestAF(function () {
removeClass(el, "".concat(_this.name, "-enter-to")); // The *-move class is also stuck on elements that moved,
// but there are no javascript hooks to handle after move.
});
}
},
render: function render(h) {
return h('transition-group', {
props: {
tag: 'div',
name: this.name
},
on: {
afterEnter: this.onAfterEnter
}
}, this.$slots.default);
}
}); // @vue/component
export var BToaster =
/*#__PURE__*/
Vue.extend({
name: NAME,
props: props,
data: function data() {
return {
// We don't render on SSR or if a an existing target found
doRender: false,
dead: false,
// Toaster names cannot change once created
staticName: this.name
};
},
beforeMount: function beforeMount() {
var _this2 = this;
this.staticName = this.name;
/* istanbul ignore if */
if (Wormhole.hasTarget(this.staticName)) {
warn("A \"<portal-target>\" with name \"".concat(this.name, "\" already exists in the document."), 'BToaster');
this.dead = true;
} else {
this.doRender = true;
this.$once('hook:beforeDestroy', function () {
// Let toasts made with `this.$bvToast.toast()` know that this toaster
// is being destroyed and should should also destroy/hide themselves
_this2.$root.$emit('bv::toaster::destroyed', _this2.staticName);
});
}
},
destroyed: function destroyed() {
// Remove from DOM if needed
/* istanbul ignore next: difficult to test */
if (this.$el && this.$el.parentNode) {
this.$el.parentNode.removeChild(this.$el);
}
},
render: function render(h) {
var $toaster = h('div', {
class: ['d-none', {
'b-dead-toaster': this.dead
}]
});
if (this.doRender) {
var $target = h(PortalTarget, {
staticClass: 'b-toaster-slot',
props: {
name: this.staticName,
multiple: true,
tag: 'div',
slim: false,
// transition: this.transition || DefaultTransition
transition: DefaultTransition
}
});
$toaster = h('div', {
staticClass: 'b-toaster',
class: [this.staticName],
attrs: {
id: this.staticName,
role: this.role || null,
// Fallback to null to make sure attribute doesn't exist
'aria-live': this.ariaLive,
'aria-atomic': this.ariaAtomic
}
}, [$target]);
}
return $toaster;
}
});