feat: initial commit - Phase 1 & 2 core features

This commit is contained in:
hiderfong
2026-04-22 17:07:33 +08:00
commit 1773bda06b
25005 changed files with 6252106 additions and 0 deletions
@@ -0,0 +1,8 @@
import { SFCInstallWithContext } from "../../utils/vue/typescript.js";
import "../../utils/index.js";
import { NotificationEmits, NotificationHandle, NotificationInstance, NotificationOptions, NotificationOptionsTyped, NotificationParams, NotificationParamsTyped, NotificationPosition, NotificationProps, NotificationPropsPublic, NotificationQueue, NotificationQueueItem, NotificationType, Notify, NotifyFn, NotifyTypedFn, notificationEmits, notificationProps, notificationTypes } from "./src/notification.js";
//#region ../../packages/components/notification/index.d.ts
declare const ElNotification: SFCInstallWithContext<Notify>;
//#endregion
export { ElNotification, ElNotification as default, NotificationEmits, NotificationHandle, NotificationInstance, NotificationOptions, NotificationOptionsTyped, NotificationParams, NotificationParamsTyped, NotificationPosition, NotificationProps, NotificationPropsPublic, NotificationQueue, NotificationQueueItem, NotificationType, Notify, NotifyFn, NotifyTypedFn, notificationEmits, notificationProps, notificationTypes };
@@ -0,0 +1,10 @@
import { withInstallFunction } from "../../utils/vue/install.mjs";
import { notificationEmits, notificationProps, notificationTypes } from "./src/notification.mjs";
import notify from "./src/notify.mjs";
//#region ../../packages/components/notification/index.ts
const ElNotification = withInstallFunction(notify, "$notify");
//#endregion
export { ElNotification, ElNotification as default, notificationEmits, notificationProps, notificationTypes };
//# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"index.mjs","names":["Notify"],"sources":["../../../../../packages/components/notification/index.ts"],"sourcesContent":["import { withInstallFunction } from '@element-plus/utils'\nimport Notify from './src/notify'\n\nexport const ElNotification = withInstallFunction(Notify, '$notify')\nexport default ElNotification\n\nexport * from './src/notification'\n"],"mappings":";;;;;AAGA,MAAa,iBAAiB,oBAAoBA,QAAQ,UAAU"}
@@ -0,0 +1,164 @@
import { IconPropType } from "../../../utils/vue/icon.js";
import { EpPropFinalized, EpPropMergeType } from "../../../utils/vue/props/types.js";
import "../../../utils/index.js";
import { _default } from "./notification.vue.js";
import * as vue from "vue";
import { AppContext, ExtractPublicPropTypes, VNode } from "vue";
//#region ../../packages/components/notification/src/notification.d.ts
declare const notificationTypes: readonly ["primary", "success", "info", "warning", "error"];
type NotificationType = (typeof notificationTypes)[number] | '';
type NotificationPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
interface NotificationProps {
/**
* @description custom class name for Notification
*/
customClass?: string;
/**
* @description whether `message` is treated as HTML string
*/
dangerouslyUseHTMLString?: boolean;
/**
* @description duration before close. It will not automatically close if set 0
*/
duration?: number;
/**
* @description custom icon component. It will be overridden by `type`
*/
icon?: IconPropType;
/**
* @description notification dom id
*/
id?: string;
/**
* @description description text
*/
message?: string | VNode | (() => VNode);
/**
* @description offset from the top edge of the screen. Every Notification instance of the same moment should have the same offset
*/
offset?: number;
/**
* @description callback function when notification clicked
*/
onClick?: () => void;
/**
* @description callback function when closed
*/
onClose: () => void;
/**
* @description custom position
*/
position?: NotificationPosition;
/**
* @description whether to show a close button
*/
showClose?: boolean;
/**
* @description title
*/
title?: string;
/**
* @description notification type
*/
type?: NotificationType;
/**
* @description initial zIndex
*/
zIndex?: number;
/**
* @description custom close icon, default is Close
*/
closeIcon?: IconPropType;
}
/**
* @deprecated Removed after 3.0.0, Use `NotificationProps` instead.
*/
declare const notificationProps: {
readonly customClass: EpPropFinalized<StringConstructor, unknown, unknown, "", boolean>;
readonly dangerouslyUseHTMLString: BooleanConstructor;
readonly duration: EpPropFinalized<NumberConstructor, unknown, unknown, 4500, boolean>;
readonly icon: {
readonly type: vue.PropType<EpPropMergeType<(new (...args: any[]) => (string | vue.Component) & {}) | (() => string | vue.Component) | (((new (...args: any[]) => (string | vue.Component) & {}) | (() => string | vue.Component)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly id: EpPropFinalized<StringConstructor, unknown, unknown, "", boolean>;
readonly message: EpPropFinalized<(new (...args: any[]) => string | VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}> | (() => VNode)) | (() => string | VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}> | (() => VNode)) | (((new (...args: any[]) => string | VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}> | (() => VNode)) | (() => string | VNode<vue.RendererNode, vue.RendererElement, {
[key: string]: any;
}> | (() => VNode))) | null)[], unknown, unknown, "", boolean>;
readonly offset: EpPropFinalized<NumberConstructor, unknown, unknown, 0, boolean>;
readonly onClick: EpPropFinalized<(new (...args: any[]) => () => void) | (() => () => void) | {
(): () => void;
new (): any;
readonly prototype: any;
} | (((new (...args: any[]) => () => void) | (() => () => void) | {
(): () => void;
new (): any;
readonly prototype: any;
}) | null)[], unknown, unknown, () => undefined, boolean>;
readonly onClose: {
readonly type: vue.PropType<() => void>;
readonly required: true;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly position: EpPropFinalized<StringConstructor, "top-left" | "top-right" | "bottom-left" | "bottom-right", unknown, "top-right", boolean>;
readonly showClose: EpPropFinalized<BooleanConstructor, unknown, unknown, true, boolean>;
readonly title: EpPropFinalized<StringConstructor, unknown, unknown, "", boolean>;
readonly type: EpPropFinalized<StringConstructor, "" | "error" | "info" | "primary" | "success" | "warning", unknown, "", boolean>;
readonly zIndex: NumberConstructor;
readonly closeIcon: EpPropFinalized<(new (...args: any[]) => (string | vue.Component) & {}) | (() => string | vue.Component) | (((new (...args: any[]) => (string | vue.Component) & {}) | (() => string | vue.Component)) | null)[], unknown, unknown, vue.DefineComponent<{}, void, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>, boolean>;
};
/**
* @deprecated Removed after 3.0.0, Use `NotificationProps` instead.
*/
type NotificationPropsPublic = ExtractPublicPropTypes<typeof notificationProps>;
declare const notificationEmits: {
destroy: () => boolean;
};
type NotificationEmits = typeof notificationEmits;
type NotificationInstance = InstanceType<typeof _default> & unknown;
type NotificationOptions = Omit<NotificationProps, 'id' | 'onClose'> & {
/**
* @description set the root element for the notification, default to `document.body`
*/
appendTo?: HTMLElement | string;
/**
* @description callback function when closed
*/
onClose?(vm: VNode): void;
};
type NotificationOptionsTyped = Omit<NotificationOptions, 'type'>;
interface NotificationHandle {
close: () => void;
}
type NotificationParams = Partial<NotificationOptions> | string | VNode;
type NotificationParamsTyped = Partial<NotificationOptionsTyped> | string | VNode;
interface NotifyFn {
(options?: NotificationParams, appContext?: null | AppContext): NotificationHandle;
closeAll(): void;
updateOffsets(position?: NotificationOptions['position']): void;
_context: AppContext | null;
}
type NotifyTypedFn = (options?: NotificationParamsTyped, appContext?: null | AppContext) => NotificationHandle;
interface Notify extends NotifyFn {
primary: NotifyTypedFn;
success: NotifyTypedFn;
warning: NotifyTypedFn;
error: NotifyTypedFn;
info: NotifyTypedFn;
}
interface NotificationQueueItem {
vm: VNode;
}
type NotificationQueue = NotificationQueueItem[];
//#endregion
export { NotificationEmits, NotificationHandle, NotificationInstance, NotificationOptions, NotificationOptionsTyped, NotificationParams, NotificationParamsTyped, NotificationPosition, NotificationProps, NotificationPropsPublic, NotificationQueue, NotificationQueueItem, NotificationType, Notify, NotifyFn, NotifyTypedFn, notificationEmits, notificationProps, notificationTypes };
@@ -0,0 +1,84 @@
import { buildProps, definePropType } from "../../../utils/vue/props/runtime.mjs";
import { iconPropType } from "../../../utils/vue/icon.mjs";
import { Close } from "@element-plus/icons-vue";
//#region ../../packages/components/notification/src/notification.ts
const notificationTypes = [
"primary",
"success",
"info",
"warning",
"error"
];
/**
* @deprecated Removed after 3.0.0, Use `NotificationProps` instead.
*/
const notificationProps = buildProps({
customClass: {
type: String,
default: ""
},
dangerouslyUseHTMLString: Boolean,
duration: {
type: Number,
default: 4500
},
icon: { type: iconPropType },
id: {
type: String,
default: ""
},
message: {
type: definePropType([
String,
Object,
Function
]),
default: ""
},
offset: {
type: Number,
default: 0
},
onClick: {
type: definePropType(Function),
default: () => void 0
},
onClose: {
type: definePropType(Function),
required: true
},
position: {
type: String,
values: [
"top-right",
"top-left",
"bottom-right",
"bottom-left"
],
default: "top-right"
},
showClose: {
type: Boolean,
default: true
},
title: {
type: String,
default: ""
},
type: {
type: String,
values: [...notificationTypes, ""],
default: ""
},
zIndex: Number,
closeIcon: {
type: iconPropType,
default: Close
}
});
const notificationEmits = { destroy: () => true };
//#endregion
export { notificationEmits, notificationProps, notificationTypes };
//# sourceMappingURL=notification.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,40 @@
import { IconPropType } from "../../../utils/vue/icon.js";
import "../../../utils/index.js";
import { NotificationPosition, NotificationProps, NotificationType } from "./notification.js";
import * as vue from "vue";
//#region ../../packages/components/notification/src/notification.vue.d.ts
declare function close(): void;
declare var __VLS_21: {};
type __VLS_Slots = {} & {
default?: (props: typeof __VLS_21) => any;
};
declare const __VLS_base: vue.DefineComponent<NotificationProps, {
visible: vue.Ref<boolean, boolean>; /** @description close notification */
close: typeof close;
}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
destroy: () => void;
}, string, vue.PublicProps, Readonly<NotificationProps> & Readonly<{
onDestroy?: (() => any) | undefined;
}>, {
offset: number;
position: NotificationPosition;
type: NotificationType;
title: string;
id: string;
onClick: () => void;
message: string | vue.VNode | (() => vue.VNode);
closeIcon: IconPropType;
showClose: boolean;
duration: number;
customClass: string;
}, {}, {}, {}, string, vue.ComponentProvideOptions, false, {}, any>;
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
declare const _default: typeof __VLS_export;
type __VLS_WithSlots<T, S> = T & {
new (): {
$slots: S;
};
};
//#endregion
export { _default };
@@ -0,0 +1,128 @@
import { EVENT_CODE } from "../../../constants/aria.mjs";
import { getEventCode } from "../../../utils/dom/event.mjs";
import { TypeComponentsMap } from "../../../utils/vue/icon.mjs";
import { ElIcon } from "../../icon/index.mjs";
import { useGlobalComponentSettings } from "../../config-provider/src/hooks/use-global-config.mjs";
import { notificationEmits, notificationProps } from "./notification.mjs";
import { useEventListener, useTimeoutFn } from "@vueuse/core";
import { Fragment, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, defineComponent, normalizeClass, normalizeStyle, onMounted, openBlock, ref, renderSlot, resolveDynamicComponent, toDisplayString, unref, vShow, withCtx, withDirectives, withModifiers } from "vue";
//#region ../../packages/components/notification/src/notification.vue?vue&type=script&setup=true&lang.ts
const _hoisted_1 = ["id"];
const _hoisted_2 = ["textContent"];
const _hoisted_3 = { key: 0 };
const _hoisted_4 = ["innerHTML"];
var notification_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
name: "ElNotification",
__name: "notification",
props: notificationProps,
emits: notificationEmits,
setup(__props, { expose: __expose }) {
const props = __props;
const { ns, zIndex } = useGlobalComponentSettings("notification");
const { nextZIndex, currentZIndex } = zIndex;
const visible = ref(false);
let timer = void 0;
const typeClass = computed(() => {
const type = props.type;
return type && TypeComponentsMap[props.type] ? ns.m(type) : "";
});
const iconComponent = computed(() => {
if (!props.type) return props.icon;
return TypeComponentsMap[props.type] || props.icon;
});
const horizontalClass = computed(() => props.position.endsWith("right") ? "right" : "left");
const verticalProperty = computed(() => props.position.startsWith("top") ? "top" : "bottom");
const positionStyle = computed(() => {
return {
[verticalProperty.value]: `${props.offset}px`,
zIndex: props.zIndex ?? currentZIndex.value
};
});
function startTimer() {
if (props.duration > 0) ({stop: timer} = useTimeoutFn(() => {
if (visible.value) close();
}, props.duration));
}
function clearTimer() {
timer?.();
}
function close() {
visible.value = false;
}
function onKeydown(event) {
switch (getEventCode(event)) {
case EVENT_CODE.delete:
case EVENT_CODE.backspace:
clearTimer();
break;
case EVENT_CODE.esc:
if (visible.value) close();
break;
default:
startTimer();
break;
}
}
onMounted(() => {
startTimer();
nextZIndex();
visible.value = true;
});
useEventListener(document, "keydown", onKeydown);
__expose({
visible,
close
});
return (_ctx, _cache) => {
return openBlock(), createBlock(Transition, {
name: unref(ns).b("fade"),
onBeforeLeave: __props.onClose,
onAfterLeave: _cache[1] || (_cache[1] = ($event) => _ctx.$emit("destroy")),
persisted: ""
}, {
default: withCtx(() => [withDirectives(createElementVNode("div", {
id: __props.id,
class: normalizeClass([
unref(ns).b(),
__props.customClass,
horizontalClass.value
]),
style: normalizeStyle(positionStyle.value),
role: "alert",
onMouseenter: clearTimer,
onMouseleave: startTimer,
onClick: _cache[0] || (_cache[0] = (...args) => __props.onClick && __props.onClick(...args))
}, [iconComponent.value ? (openBlock(), createBlock(unref(ElIcon), {
key: 0,
class: normalizeClass([unref(ns).e("icon"), typeClass.value])
}, {
default: withCtx(() => [(openBlock(), createBlock(resolveDynamicComponent(iconComponent.value)))]),
_: 1
}, 8, ["class"])) : createCommentVNode("v-if", true), createElementVNode("div", { class: normalizeClass(unref(ns).e("group")) }, [
createElementVNode("h2", {
class: normalizeClass(unref(ns).e("title")),
textContent: toDisplayString(__props.title)
}, null, 10, _hoisted_2),
withDirectives(createElementVNode("div", {
class: normalizeClass(unref(ns).e("content")),
style: normalizeStyle(!!__props.title ? void 0 : { margin: 0 })
}, [renderSlot(_ctx.$slots, "default", {}, () => [!__props.dangerouslyUseHTMLString ? (openBlock(), createElementBlock("p", _hoisted_3, toDisplayString(__props.message), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createCommentVNode(" Caution here, message could've been compromised, never use user's input as message "), createElementVNode("p", { innerHTML: __props.message }, null, 8, _hoisted_4)], 2112))])], 6), [[vShow, __props.message]]),
__props.showClose ? (openBlock(), createBlock(unref(ElIcon), {
key: 0,
class: normalizeClass(unref(ns).e("closeBtn")),
onClick: withModifiers(close, ["stop"])
}, {
default: withCtx(() => [(openBlock(), createBlock(resolveDynamicComponent(__props.closeIcon)))]),
_: 1
}, 8, ["class"])) : createCommentVNode("v-if", true)
], 2)], 46, _hoisted_1), [[vShow, visible.value]])]),
_: 3
}, 8, ["name", "onBeforeLeave"]);
};
}
});
//#endregion
export { notification_vue_vue_type_script_setup_true_lang_default as default };
//# sourceMappingURL=notification.vue_vue_type_script_setup_true_lang.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
import notification_vue_vue_type_script_setup_true_lang_default from "./notification.vue_vue_type_script_setup_true_lang.mjs";
//#region ../../packages/components/notification/src/notification.vue
var notification_default = notification_vue_vue_type_script_setup_true_lang_default;
//#endregion
export { notification_default as default };
//# sourceMappingURL=notification2.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"notification2.mjs","names":[],"sources":["../../../../../../packages/components/notification/src/notification.vue"],"sourcesContent":["<template>\n <transition\n :name=\"ns.b('fade')\"\n @before-leave=\"onClose\"\n @after-leave=\"$emit('destroy')\"\n >\n <div\n v-show=\"visible\"\n :id=\"id\"\n :class=\"[ns.b(), customClass, horizontalClass]\"\n :style=\"positionStyle\"\n role=\"alert\"\n @mouseenter=\"clearTimer\"\n @mouseleave=\"startTimer\"\n @click=\"onClick\"\n >\n <el-icon v-if=\"iconComponent\" :class=\"[ns.e('icon'), typeClass]\">\n <component :is=\"iconComponent\" />\n </el-icon>\n <div :class=\"ns.e('group')\">\n <h2 :class=\"ns.e('title')\" v-text=\"title\" />\n <div\n v-show=\"message\"\n :class=\"ns.e('content')\"\n :style=\"!!title ? undefined : { margin: 0 }\"\n >\n <slot>\n <p v-if=\"!dangerouslyUseHTMLString\">{{ message }}</p>\n <!-- Caution here, message could've been compromised, never use user's input as message -->\n <p v-else v-html=\"message\" />\n </slot>\n </div>\n <el-icon v-if=\"showClose\" :class=\"ns.e('closeBtn')\" @click.stop=\"close\">\n <component :is=\"closeIcon\" />\n </el-icon>\n </div>\n </div>\n </transition>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, markRaw, onMounted, ref } from 'vue'\nimport { useEventListener, useTimeoutFn } from '@vueuse/core'\nimport { TypeComponentsMap, getEventCode } from '@element-plus/utils'\nimport { EVENT_CODE } from '@element-plus/constants'\nimport { ElIcon } from '@element-plus/components/icon'\nimport { useGlobalComponentSettings } from '@element-plus/components/config-provider'\nimport { notificationEmits } from './notification'\nimport { Close } from '@element-plus/icons-vue'\n\nimport type { CSSProperties } from 'vue'\nimport type { NotificationProps } from './notification'\n\ndefineOptions({\n name: 'ElNotification',\n})\n\nconst props = withDefaults(defineProps<NotificationProps>(), {\n customClass: '',\n duration: 4500,\n id: '',\n message: '',\n offset: 0,\n onClick: () => undefined,\n position: 'top-right',\n showClose: true,\n title: '',\n type: '',\n closeIcon: markRaw(Close),\n})\ndefineEmits(notificationEmits)\n\nconst { ns, zIndex } = useGlobalComponentSettings('notification')\nconst { nextZIndex, currentZIndex } = zIndex\n\nconst visible = ref(false)\nlet timer: (() => void) | undefined = undefined\n\nconst typeClass = computed(() => {\n const type = props.type\n return type && TypeComponentsMap[props.type] ? ns.m(type) : ''\n})\n\nconst iconComponent = computed(() => {\n if (!props.type) return props.icon\n return TypeComponentsMap[props.type] || props.icon\n})\n\nconst horizontalClass = computed(() =>\n props.position.endsWith('right') ? 'right' : 'left'\n)\n\nconst verticalProperty = computed(() =>\n props.position.startsWith('top') ? 'top' : 'bottom'\n)\n\nconst positionStyle = computed<CSSProperties>(() => {\n return {\n [verticalProperty.value]: `${props.offset}px`,\n zIndex: props.zIndex ?? currentZIndex.value,\n }\n})\n\nfunction startTimer() {\n if (props.duration > 0) {\n ;({ stop: timer } = useTimeoutFn(() => {\n if (visible.value) close()\n }, props.duration))\n }\n}\n\nfunction clearTimer() {\n timer?.()\n}\n\nfunction close() {\n visible.value = false\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n const code = getEventCode(event)\n\n switch (code) {\n case EVENT_CODE.delete:\n case EVENT_CODE.backspace:\n clearTimer() // press delete/backspace clear timer\n break\n case EVENT_CODE.esc:\n // press esc to close the notification\n if (visible.value) {\n close()\n }\n break\n default: // resume timer\n startTimer()\n break\n }\n}\n\n// lifecycle\nonMounted(() => {\n startTimer()\n nextZIndex()\n visible.value = true\n})\n\nuseEventListener(document, 'keydown', onKeydown)\n\ndefineExpose({\n visible,\n /** @description close notification */\n close,\n})\n</script>\n"],"mappings":""}
@@ -0,0 +1,109 @@
import { isClient } from "../../../utils/browser.mjs";
import { isElement, isFunction, isString, isUndefined } from "../../../utils/types.mjs";
import { debugWarn } from "../../../utils/error.mjs";
import { notificationTypes } from "./notification.mjs";
import notification_default from "./notification2.mjs";
import { createVNode, isVNode, render } from "vue";
//#region ../../packages/components/notification/src/notify.ts
const notifications = {
"top-left": [],
"top-right": [],
"bottom-left": [],
"bottom-right": []
};
const GAP_SIZE = 16;
let seed = 1;
const notify = function(options = {}, context) {
if (!isClient) return { close: () => void 0 };
if (isString(options) || isVNode(options)) options = { message: options };
const position = options.position || "top-right";
let verticalOffset = options.offset || 0;
notifications[position].forEach(({ vm }) => {
verticalOffset += (vm.el?.offsetHeight || 0) + GAP_SIZE;
});
verticalOffset += GAP_SIZE;
const id = `notification_${seed++}`;
const userOnClose = options.onClose;
const props = {
...options,
offset: verticalOffset,
id,
onClose: () => {
close(id, position, userOnClose);
}
};
let appendTo = document.body;
if (isElement(options.appendTo)) appendTo = options.appendTo;
else if (isString(options.appendTo)) appendTo = document.querySelector(options.appendTo);
if (!isElement(appendTo)) {
debugWarn("ElNotification", "the appendTo option is not an HTMLElement. Falling back to document.body.");
appendTo = document.body;
}
const container = document.createElement("div");
const vm = createVNode(notification_default, props, isFunction(props.message) ? props.message : isVNode(props.message) ? () => props.message : null);
vm.appContext = isUndefined(context) ? notify._context : context;
vm.props.onDestroy = () => {
render(null, container);
};
render(vm, container);
notifications[position].push({ vm });
appendTo.appendChild(container.firstElementChild);
return { close: () => {
vm.component.exposed.visible.value = false;
} };
};
notificationTypes.forEach((type) => {
notify[type] = (options = {}, appContext) => {
if (isString(options) || isVNode(options)) options = { message: options };
return notify({
...options,
type
}, appContext);
};
});
/**
* This function gets called when user click `x` button or press `esc` or the time reached its limitation.
* Emitted by transition@before-leave event so that we can fetch the current notification.offsetHeight, if this was called
* by @after-leave the DOM element will be removed from the page thus we can no longer fetch the offsetHeight.
* @param {String} id notification id to be closed
* @param {Position} position the positioning strategy
* @param {Function} userOnClose the callback called when close passed by user
*/
function close(id, position, userOnClose) {
const orientedNotifications = notifications[position];
const idx = orientedNotifications.findIndex(({ vm }) => vm.component?.props.id === id);
if (idx === -1) return;
const { vm } = orientedNotifications[idx];
if (!vm) return;
userOnClose?.(vm);
const removedHeight = vm.el.offsetHeight;
const verticalPos = position.split("-")[0];
orientedNotifications.splice(idx, 1);
const len = orientedNotifications.length;
if (len < 1) return;
for (let i = idx; i < len; i++) {
const { el, component } = orientedNotifications[i].vm;
const pos = Number.parseInt(el.style[verticalPos], 10) - removedHeight - GAP_SIZE;
component.props.offset = pos;
}
}
function closeAll() {
for (const orientedNotifications of Object.values(notifications)) orientedNotifications.forEach(({ vm }) => {
vm.component.exposed.visible.value = false;
});
}
function updateOffsets(position = "top-right") {
let verticalOffset = notifications[position][0]?.vm.component?.props?.offset || 0;
for (const { vm } of notifications[position]) {
vm.component.props.offset = verticalOffset;
verticalOffset += (vm.el?.offsetHeight || 0) + GAP_SIZE;
}
}
notify.closeAll = closeAll;
notify.updateOffsets = updateOffsets;
notify._context = null;
//#endregion
export { close, closeAll, notify as default, updateOffsets };
//# sourceMappingURL=notify.mjs.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,2 @@
import "../../base/style/css.mjs";
import "element-plus/theme-chalk/el-notification.css";
@@ -0,0 +1,2 @@
import "../../base/style/index.mjs";
import "element-plus/theme-chalk/src/notification.scss";