@tencentcloud/ai-desk-customer-vue
Version:
Vue UIKit for AI Desk
123 lines (114 loc) • 3.4 kB
text/typescript
/* eslint-disable no-case-declarations */
import vue from '../../../adapter-vue';
import { TUIGlobal } from '@tencentcloud/universal-api';
import TOAST_TYPE from './type';
import MessageConstructor from './index-web.vue';
//@ts-ignore
import { vueVersion } from '../../../adapter-vue-web';
import { VNode } from 'vue';
//@ts-ignore
const { createVNode, render } = vue;
interface IToast {
message: string;
type: string;
offset?: number;
duration?: number;
onClose?(): void;
}
interface IToastReturnType {
close?(): void;
}
const instances: any[] = [];
let seed = 1;
const vueVersionInt = Math.trunc(vueVersion);
const appendTo: HTMLElement | null = document.body;
const Toast = function (options: IToast): IToastReturnType {
let verticalOffset = options.offset || 20;
instances.forEach(({ vm }: any) => {
verticalOffset += (vm?.el?.offsetHeight || vm?.$el?.offsetHeight || 0) + 20;
});
verticalOffset += 20;
const id = `message_${(seed += 1)}`;
const userOnClose = options.onClose;
const props: any = {
zIndex: 20 + seed,
offset: verticalOffset,
id,
...options,
onClose: () => {
Toast.close(id, userOnClose);
},
};
let vm: { component: any; props: any; data: any };
let container: HTMLDivElement;
switch (vueVersionInt) {
case 2:
const Vue = TUIGlobal?.Vue;
if (!Vue) {
return {};
}
const Constructor = Vue.extend(MessageConstructor);
const instance = new Constructor({ propsData: props });
instance.$mount();
appendTo.appendChild(instance.$el);
instance.$el.style.zIndex = props.zIndex;
instance.verticalOffset = props.verticalOffset;
instance.visible = true;
instances.push({ vm: instance });
return {
close: () => {
instance.visible = false;
},
};
case 3:
// @ts-ignore
vm = createVNode(MessageConstructor, props);
container = document.createElement('div');
vm?.props
&& (vm.props!.onDestroy = () => {
render(null, container);
});
vm?.data
&& (vm.data!.onDestroy = () => {
render(null, container);
});
// @ts-ignore
render(vm, container);
instances.push({ vm });
appendTo.appendChild(container.firstElementChild!);
return {
close: () => {
vm?.component?.proxy && (vm.component!.proxy.visible = false);
},
};
}
return {};
};
export function close(id: string, userOnClose?: (vm: VNode) => void): void {
const idx = instances?.findIndex(
({ vm }: any) => id === vm?.component?.props?.id || id === vm?._props?.id,
);
if (idx === -1) return;
const { vm } = instances[idx];
if (!vm) return;
userOnClose?.(vm);
const removedHeight = vm?.el?.offsetHeight || vm?.$el?.offsetHeight;
instances.splice(idx, 1);
// adjust other instances vertical offset
const len = instances.length;
if (len < 1) return;
for (let i = idx; i < len; i++) {
const pos
= Number.parseInt(
instances[i]?.vm?.el?.style?.top || instances[i]?.vm?.$el?.style?.top,
10,
)
- removedHeight
- 16;
instances[i]?.vm?.component?.props?.offset
&& (instances[i].vm.component!.props.offset = pos);
instances[i]?.vm?._props?.offset && (instances[i].vm._props.offset = pos);
}
}
Toast.close = close;
export { Toast, TOAST_TYPE };