Files
TeyvatGuide/src/components/func/dialog.ts
2026-05-19 18:46:12 +08:00

156 lines
3.9 KiB
TypeScript

/**
* dialog 组件封装,函数式调用
* @since Beta v0.10.2
*/
import type { ComponentInternalInstance, VNode } from "vue";
import { h, render } from "vue";
import dialog from "./dialog.vue";
const dialogId = "tg-func-dialog";
export type DialogParams = DialogCheckParams | DialogInputParams;
/** 基础弹窗参数 */
type DialogBaseParams = {
/** 标题 */
title: string;
/** 文本 */
text?: string;
/** 点击外部取消 */
otcancel?: boolean;
/** 确认label */
confirmLabel?: string;
/** 取消label */
cancelLabel?: string;
};
/** 确认弹窗 */
export type DialogCheckParams = DialogBaseParams & {
/** 模式:确认 */
mode: "check";
};
/** 输入弹窗 */
export type DialogInputParams = DialogBaseParams & {
/** 模式:输入 */
mode: "input";
/** 默认值 */
input?: string;
/** 输入类型 */
type?: string;
};
/**
* 自定义 confirm 组件
* @since Beta v0.6.3
*/
type DialogInstance = {
exposeProxy: {
displayCheckBox: (props: DialogCheckParams) => Promise<boolean | undefined>;
displayInputBox: (props: DialogInputParams) => Promise<string | false | undefined>;
};
} & ComponentInternalInstance;
function renderBox(props: DialogParams): VNode {
const container = document.createElement("div");
container.id = dialogId;
const boxVNode: VNode = h(dialog, props);
render(boxVNode, container);
document.body.appendChild(container);
return boxVNode;
}
let dialogInstance: VNode;
async function showDialogFull(
mode: "check" | "input",
title: string,
text?: string,
input?: string,
otcancel?: boolean,
): Promise<boolean | string | undefined> {
if (mode === "check") return await showDialogCheck(title, text, otcancel);
return await showDialogInput(title, text, input, otcancel);
}
async function showDialogCheck(
title: string,
text?: string,
otcancel?: boolean,
): Promise<boolean | undefined> {
const params: DialogCheckParams = {
mode: "check",
title: title,
text: text,
otcancel: otcancel,
};
if (dialogInstance !== undefined) {
const boxVue = <DialogInstance>dialogInstance.component;
return await boxVue.exposeProxy.displayCheckBox(params);
} else {
dialogInstance = renderBox(params);
return await showDialogCheck(title, text, otcancel);
}
}
async function showDialogCheckFull(opts: DialogBaseParams): Promise<boolean | undefined> {
const params: DialogCheckParams = { mode: "check", ...opts };
if (dialogInstance !== undefined) {
const boxVue = <DialogInstance>dialogInstance.component;
return await boxVue.exposeProxy.displayCheckBox(params);
} else {
dialogInstance = renderBox(params);
return await showDialogCheckFull(opts);
}
}
async function showDialogInput(
title: string,
text?: string,
input?: string,
otcancel?: boolean,
): Promise<string | false | undefined> {
const params: DialogInputParams = {
mode: "input",
title: title,
text: text,
input: input,
otcancel: otcancel,
};
if (dialogInstance !== undefined) {
const boxVue = <DialogInstance>dialogInstance.component;
return await boxVue.exposeProxy.displayInputBox(params);
} else {
dialogInstance = renderBox(params);
return await showDialogInput(title, text, input, otcancel);
}
}
/**
* Input Mode 封装
* @since Beta v0.10.2
* @param opts - 参数
* @returns 输入模式值
*/
async function showDialogInputFull(
opts: Omit<DialogInputParams, "mode">,
): Promise<string | false | undefined> {
const params: DialogInputParams = { mode: "input", ...opts };
if (dialogInstance !== undefined) {
const boxVue = <DialogInstance>dialogInstance.component;
return await boxVue.exposeProxy.displayInputBox(params);
} else {
dialogInstance = renderBox(params);
return await showDialogInputFull(opts);
}
}
const showDialog = {
_: showDialogFull,
check: showDialogCheck,
input: showDialogInput,
inputF: showDialogInputFull,
checkF: showDialogCheckFull,
};
export default showDialog;