-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathmodals.ts
154 lines (142 loc) · 3.59 KB
/
modals.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import { acceptHMRUpdate, defineStore } from "pinia";
import { ref } from "vue";
export type ModalType = "alert" | "confirm" | "prompt";
export interface Modal {
title: string;
message: string;
type: ModalType;
confirmText?: string;
cancelText?: string;
promptedValueName?: string;
response?: string;
onConfirm: () => void;
onCancel: () => void;
}
export const useModalsStore = defineStore("modals", () => {
const stack = ref<Modal[]>([]);
/**
* Show an alert modal.
*
* Usage:
*
* ```ts
* if (await alert("title", "message")) {
* // do something
* }
* ```
*
* @param title The title of the modal.
* @param message The message of the modal.
* @param confirmText The text of the confirm button.
* @returns A promise that resolves to true if the user confirms the modal, false otherwise.
*/
async function alert(title: string, message: string, confirmText = "ok") {
return new Promise<void>((resolve) => {
function handleConfirm() {
stack.value.shift();
resolve();
}
stack.value.push({
title,
message,
type: "alert",
confirmText,
onConfirm: () => handleConfirm(),
onCancel: () => handleConfirm(),
});
});
}
/**
* Show a confirm modal.
*
* Usage:
*
* ```ts
* if (await confirm("title", "message")) {
* // do something
* }
* ```
*
* @param title The title of the modal.
* @param message The message of the modal.
* @param confirmText The text of the confirm button.
* @param cancelText The text of the cancel button.
* @returns A promise that resolves to true if the user confirms the modal, false otherwise.
*/
async function confirm(
title: string,
message: string,
confirmText = "ok",
cancelText = "cancel"
) {
return new Promise<boolean>((resolve) => {
function handleConfirm(isConfirmed: boolean) {
stack.value.shift();
resolve(isConfirmed);
}
stack.value.push({
title,
message,
type: "confirm",
confirmText,
cancelText,
onConfirm: () => handleConfirm(true),
onCancel: () => handleConfirm(false),
});
});
}
/**
* Show a prompt modal.
*
* Usage:
*
* ```ts
* const response = await prompt("title", "message", "promptedValueName");
* if (response) {
* // do something
* }
* ```
*
* @param title The title of the modal.
* @param message The message of the modal.
* @param promptedValueName The name of the prompted value.
* @param confirmText The text of the confirm button.
* @param cancelText The text of the cancel button.
* @returns A promise that resolves to the prompted value.
*/
async function prompt(
title: string,
message: string,
promptedValueName: string,
confirmText = "ok",
cancelText = "cancel"
) {
return new Promise<string>((resolve) => {
function handleConfirm() {
const m = stack.value.shift();
resolve(m?.response ?? "");
}
stack.value.push({
title,
message,
type: "prompt",
promptedValueName,
confirmText,
cancelText,
onConfirm: () => handleConfirm(),
onCancel: () => handleConfirm(),
});
});
}
/**
* Get the current modal in the stack.
* @returns The current modal.
*/
function getCurrentModal() {
return stack.value[0];
}
return { alert, confirm, prompt, getCurrentModal };
});
if (import.meta.hot) {
import.meta.hot.accept(acceptHMRUpdate(useModalsStore, import.meta.hot));
}