naive-ui
Version:
A Vue 3 Component Library. Fairly Complete, Theme Customizable, Uses TypeScript, Fast
150 lines • 5.1 kB
JavaScript
import { createId } from 'seemly';
import { defineComponent, Fragment, h, provide, reactive, ref, Teleport } from 'vue';
import { useConfig, useTheme } from "../../_mixins/index.mjs";
import { createInjectionKey, omit } from "../../_utils/index.mjs";
import { notificationLight } from "../styles/index.mjs";
import { notificationProviderInjectionKey } from "./context.mjs";
import { NotificationContainer } from "./NotificationContainer.mjs";
import { NotificationEnvironment } from "./NotificationEnvironment.mjs";
import style from "./styles/index.cssr.mjs";
export const notificationApiInjectionKey = createInjectionKey('n-notification-api');
export const notificationProviderProps = Object.assign(Object.assign({}, useTheme.props), {
containerClass: String,
containerStyle: [String, Object],
to: [String, Object],
scrollable: {
type: Boolean,
default: true
},
max: Number,
placement: {
type: String,
default: 'top-right'
},
keepAliveOnHover: Boolean
});
export default defineComponent({
name: 'NotificationProvider',
props: notificationProviderProps,
setup(props) {
const {
mergedClsPrefixRef
} = useConfig(props);
const notificationListRef = ref([]);
const notificationRefs = {};
const leavingKeySet = new Set();
function create(options) {
const key = createId();
const destroy = () => {
leavingKeySet.add(key);
// If you push n + 1 message when max is n, notificationRefs[key] maybe not be set
if (notificationRefs[key]) {
notificationRefs[key].hide();
}
};
const notificationReactive = reactive(Object.assign(Object.assign({}, options), {
key,
destroy,
hide: destroy,
deactivate: destroy
}));
const {
max
} = props;
if (max && notificationListRef.value.length - leavingKeySet.size >= max) {
let someoneMountedRemoved = false;
let index = 0;
for (const notification of notificationListRef.value) {
if (!leavingKeySet.has(notification.key)) {
if (notificationRefs[notification.key]) {
notification.destroy();
someoneMountedRemoved = true;
}
break;
}
index++;
}
if (!someoneMountedRemoved) {
notificationListRef.value.splice(index, 1);
}
}
notificationListRef.value.push(notificationReactive);
return notificationReactive;
}
const apis = ['info', 'success', 'warning', 'error'].map(type => {
return options => create(Object.assign(Object.assign({}, options), {
type
}));
});
function handleAfterLeave(key) {
leavingKeySet.delete(key);
notificationListRef.value.splice(notificationListRef.value.findIndex(notification => notification.key === key), 1);
}
const themeRef = useTheme('Notification', '-notification', style, notificationLight, props, mergedClsPrefixRef);
const api = {
create,
info: apis[0],
success: apis[1],
warning: apis[2],
error: apis[3],
open,
destroyAll
};
const wipTransitionCountRef = ref(0);
provide(notificationApiInjectionKey, api);
provide(notificationProviderInjectionKey, {
props,
mergedClsPrefixRef,
mergedThemeRef: themeRef,
wipTransitionCountRef
});
// deprecated
function open(options) {
return create(options);
}
function destroyAll() {
Object.values(notificationListRef.value).forEach(notification => {
notification.hide();
});
}
return Object.assign({
mergedClsPrefix: mergedClsPrefixRef,
notificationList: notificationListRef,
notificationRefs,
handleAfterLeave
}, api);
},
render() {
var _a, _b, _c;
const {
placement
} = this;
return h(Fragment, null, (_b = (_a = this.$slots).default) === null || _b === void 0 ? void 0 : _b.call(_a), this.notificationList.length ? h(Teleport, {
to: (_c = this.to) !== null && _c !== void 0 ? _c : 'body'
}, h(NotificationContainer, {
class: this.containerClass,
style: this.containerStyle,
scrollable: this.scrollable && placement !== 'top' && placement !== 'bottom',
placement: placement
}, {
default: () => {
return this.notificationList.map(notification => {
return h(NotificationEnvironment, Object.assign({
ref: inst => {
const refKey = notification.key;
if (inst === null) {
delete this.notificationRefs[refKey];
} else {
this.notificationRefs[refKey] = inst;
}
}
}, omit(notification, ['destroy', 'hide', 'deactivate']), {
internalKey: notification.key,
onInternalAfterLeave: this.handleAfterLeave,
keepAliveOnHover: notification.keepAliveOnHover === undefined ? this.keepAliveOnHover : notification.keepAliveOnHover
}));
});
}
})) : null);
}
});