Skip to content

Commit ca70677

Browse files
committed
refactor(components): Notify 下的所有通知现在都返回 Promise 对象
1 parent 4db1de0 commit ca70677

6 files changed

Lines changed: 83 additions & 51 deletions

File tree

apps/docs/src/components/demo/notify/api.zh-Hans.json

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
"name": "duration",
6060
"summary": "持续时间,单位毫秒。\n\n",
6161
"type": "number | undefined",
62-
"reactive": true
62+
"readonly": true
6363
},
6464
{
6565
"name": "onAccept",
@@ -113,7 +113,7 @@
113113
"kind": "function",
114114
"name": "Notify.notify",
115115
"summary": "发送一条通知给用户\n\n",
116-
"type": "declare function notify(title: string, o?: NotifyOptions): Promise<void>",
116+
"type": "declare function notify(title: string, o?: NotifyOptions): Promise<boolean>",
117117
"params": [
118118
{
119119
"name": "title",
@@ -127,15 +127,15 @@
127127
}
128128
],
129129
"return": {
130-
"type": "Promise<void>"
130+
"type": "Promise<boolean>"
131131
},
132132
"pkg": "@cmfx/components"
133133
},
134134
{
135135
"kind": "function",
136136
"name": "Notify.info",
137137
"summary": "`notify`\n的快捷方式,用于显示普通信息。\n\n",
138-
"type": "declare function info(title: string, o?: Omit<NotifyOptions, 'type'>): Promise<void>",
138+
"type": "declare function info(title: string, o?: Omit<NotifyOptions, 'type'>): Promise<boolean>",
139139
"params": [
140140
{
141141
"name": "title",
@@ -147,15 +147,15 @@
147147
}
148148
],
149149
"return": {
150-
"type": "Promise<void>"
150+
"type": "Promise<boolean>"
151151
},
152152
"pkg": "@cmfx/components"
153153
},
154154
{
155155
"kind": "function",
156156
"name": "Notify.warning",
157157
"summary": "`notify`\n的快捷方式,用于显示警告信息。\n\n",
158-
"type": "declare function warning(title: string, o?: Omit<NotifyOptions, 'type'>): Promise<void>",
158+
"type": "declare function warning(title: string, o?: Omit<NotifyOptions, 'type'>): Promise<boolean>",
159159
"params": [
160160
{
161161
"name": "title",
@@ -167,15 +167,15 @@
167167
}
168168
],
169169
"return": {
170-
"type": "Promise<void>"
170+
"type": "Promise<boolean>"
171171
},
172172
"pkg": "@cmfx/components"
173173
},
174174
{
175175
"kind": "function",
176176
"name": "Notify.success",
177177
"summary": "`notify`\n的快捷方式,用于显示成功信息。\n\n",
178-
"type": "declare function success(title: string, o?: Omit<NotifyOptions, 'type'>): Promise<void>",
178+
"type": "declare function success(title: string, o?: Omit<NotifyOptions, 'type'>): Promise<boolean>",
179179
"params": [
180180
{
181181
"name": "title",
@@ -187,15 +187,15 @@
187187
}
188188
],
189189
"return": {
190-
"type": "Promise<void>"
190+
"type": "Promise<boolean>"
191191
},
192192
"pkg": "@cmfx/components"
193193
},
194194
{
195195
"kind": "function",
196196
"name": "Notify.error",
197197
"summary": "`notify`\n的快捷方式,用于显示错误信息。\n\n",
198-
"type": "declare function error(title: string, o?: Omit<NotifyOptions, 'type'>): Promise<void>",
198+
"type": "declare function error(title: string, o?: Omit<NotifyOptions, 'type'>): Promise<boolean>",
199199
"params": [
200200
{
201201
"name": "title",
@@ -207,7 +207,7 @@
207207
}
208208
],
209209
"return": {
210-
"type": "Promise<void>"
210+
"type": "Promise<boolean>"
211211
},
212212
"pkg": "@cmfx/components"
213213
},

apps/docs/src/components/demo/notify/notify.tsx

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,41 @@
44

55
import { Alert, Button, Checkbox, Choice, InputNumber, InputText, Notify } from '@cmfx/components';
66
import { sleep } from '@cmfx/core';
7-
import { createSignal, type JSX } from 'solid-js';
7+
import { createMemo, createSignal, type JSX } from 'solid-js';
88

99
export default function (): JSX.Element {
1010
const [typ, setTyp] = createSignal<Alert.Type>('success');
1111
const [pos, setPos] = createSignal<Notify.Position>('top');
1212
const [timeout, setTimeout] = createSignal(5000);
1313
const [title, setTitle] = createSignal('title');
14-
const [accept, setAccept] = createSignal('accept');
14+
const [accept, setAccept] = createSignal(true);
15+
const [cancel, setCancel] = createSignal(true);
1516
const [body, setBody] = createSignal('');
1617
const [bodyType, setBodyType] = createSignal<'empty' | 'line' | 'multiple'>('empty');
1718

19+
const actions = createMemo(() => {
20+
const list: Notify.Param['actions'] = [];
21+
const a = accept();
22+
const c = cancel();
23+
24+
if (a) {
25+
list.push('accept');
26+
}
27+
if (c) {
28+
list.push('cancel');
29+
}
30+
return list;
31+
});
1832
const click = async (): Promise<void> => {
19-
await Notify.notify(title(), {
33+
const ret = await Notify.notify(title(), {
2034
body: body(),
2135
type: typ(),
2236
duration: timeout(),
2337
system: false,
2438
pos: pos(),
25-
accept: accept() ? (): Promise<boolean | undefined> => Promise.resolve(false) : undefined,
39+
actions: actions(),
2640
});
41+
console.log(ret);
2742
};
2843

2944
return (
@@ -74,7 +89,8 @@ export default function (): JSX.Element {
7489
<InputNumber step={500} placeholder="timeout" value={timeout()} onChange={setTimeout} />
7590
<InputText placeholder="title" value={title()} onChange={setTitle} />
7691
<InputText placeholder="body" value={body()} onChange={setBody} />
77-
<Checkbox label="accept" onChange={setAccept} />
92+
<Checkbox label="accept" onChange={setAccept} checked={accept()} />
93+
<Checkbox label="cancel" onChange={setCancel} checked={cancel()} />
7894
<Button palette="primary" onclick={click}>
7995
notify
8096
</Button>

apps/docs/src/components/demo/upload/api.zh-Hans.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -240,16 +240,16 @@
240240
"type": "boolean | undefined",
241241
"reactive": true
242242
},
243-
{
244-
"name": "accept",
245-
"summary": "支持的文件列表,同 https://developer.mozilla.org/zh-CN/docs/Web/HTML/Attributes/accept,但改为数组类型。\n\n",
246-
"type": "string[] | undefined"
247-
},
248243
{
249244
"name": "fieldName",
250245
"summary": "上传文件在表单中的名称\n\n",
251246
"type": "string"
252247
},
248+
{
249+
"name": "accept",
250+
"summary": "支持的文件列表,同 https://developer.mozilla.org/zh-CN/docs/Web/HTML/Attributes/accept,但改为数组类型。\n\n",
251+
"type": "string[] | undefined"
252+
},
253253
{
254254
"name": "upload",
255255
"summary": "执行上传操作\n\n",

packages/components/src/notify/message/message.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ export function Message(props: MessageProps): JSX.Element {
126126
rootRef.remove();
127127
};
128128

129-
const close = async () => {
129+
const cancel = async () => {
130130
if (typeof props.onCancel === 'function') {
131131
await props.onCancel();
132132
}
@@ -148,7 +148,7 @@ export function Message(props: MessageProps): JSX.Element {
148148
const p = ((timeout - t) / timeout) * 100;
149149
rootRef.style.background = `linear-gradient(to right, var(--palette-bg) 0% ${p}%, var(--palette-bg-low) ${p}% 100%)`;
150150
if (t <= 0) {
151-
await remove();
151+
await cancel();
152152
}
153153
});
154154
timer.start();
@@ -194,7 +194,7 @@ export function Message(props: MessageProps): JSX.Element {
194194
if (props.ref) {
195195
props.ref({
196196
root: () => el,
197-
cancel: close,
197+
cancel,
198198
accept,
199199
});
200200
}
@@ -227,7 +227,7 @@ export function Message(props: MessageProps): JSX.Element {
227227
<Show when={props.onCancel || props.onAccept}>
228228
<div class={styles.actions}>
229229
<Show when={props.onCancel}>
230-
<Button square kind="fill" onclick={close} class={styles.btn} palette="error">
230+
<Button square kind="fill" onclick={cancel} class={styles.btn} palette="error">
231231
<IconClose />
232232
</Button>
233233
</Show>

packages/components/src/notify/notify/notify.tsx

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type { MountProps } from '@components/base';
1111
import { useOptions } from '@components/context';
1212
import { type NotifyPosition, notifyPositions } from '@components/context/options/options';
1313
import { Message, type MessageProps, type MessageType } from '@components/notify/message';
14+
import { createDeferred } from './promise';
1415
import styles from './style.module.css';
1516

1617
let notifyInst: typeof notify;
@@ -45,48 +46,39 @@ export interface NotifyOptions {
4546
pos?: NotifyPosition;
4647

4748
/**
48-
* 点击确认按钮时触发的回调
49+
* 显示的操作按钮
4950
*
50-
* @remarks
51-
* 只有指定该值,才会显示确定按钮。该操作会关闭整个消息框,但是返回 true 可以取消关闭通知框。
51+
* @reactive
5252
*/
53-
accept?: MessageProps['onAccept'];
54-
55-
/**
56-
* 点击取消按钮时触发的回调
57-
*
58-
* @remarks
59-
* 只有指定该值,才会显示取消按钮。该操作会关闭整个消息框,但是返回 true 可以取消关闭通知框。
60-
*/
61-
cancel?: MessageProps['onCancel'];
53+
actions?: Array<'accept' | 'cancel'>;
6254
}
6355

6456
/**
6557
* {@link notify} 的快捷方式,用于显示成功信息。
6658
*/
67-
export async function success(title: string, o?: Omit<NotifyOptions, 'type'>): Promise<void> {
68-
await notify(title, o ? { ...o, type: 'success' } : { type: 'success' });
59+
export async function success(title: string, o?: Omit<NotifyOptions, 'type'>): Promise<boolean> {
60+
return await notify(title, o ? { ...o, type: 'success' } : { type: 'success' });
6961
}
7062

7163
/**
7264
* {@link notify} 的快捷方式,用于显示普通信息。
7365
*/
74-
export async function info(title: string, o?: Omit<NotifyOptions, 'type'>): Promise<void> {
75-
await notify(title, o ? { ...o, type: 'info' } : { type: 'info' });
66+
export async function info(title: string, o?: Omit<NotifyOptions, 'type'>): Promise<boolean> {
67+
return await notify(title, o ? { ...o, type: 'info' } : { type: 'info' });
7668
}
7769

7870
/**
7971
* {@link notify} 的快捷方式,用于显示警告信息。
8072
*/
81-
export async function warning(title: string, o?: Omit<NotifyOptions, 'type'>): Promise<void> {
82-
await notify(title, o ? { ...o, type: 'warning' } : { type: 'warning' });
73+
export async function warning(title: string, o?: Omit<NotifyOptions, 'type'>): Promise<boolean> {
74+
return await notify(title, o ? { ...o, type: 'warning' } : { type: 'warning' });
8375
}
8476

8577
/**
8678
* {@link notify} 的快捷方式,用于显示错误信息。
8779
*/
88-
export async function error(title: string, o?: Omit<NotifyOptions, 'type'>): Promise<void> {
89-
await notify(title, o ? { ...o, type: 'error' } : { type: 'error' });
80+
export async function error(title: string, o?: Omit<NotifyOptions, 'type'>): Promise<boolean> {
81+
return await notify(title, o ? { ...o, type: 'error' } : { type: 'error' });
9082
}
9183

9284
/**
@@ -95,8 +87,8 @@ export async function error(title: string, o?: Omit<NotifyOptions, 'type'>): Pro
9587
* @param title - 通知标题;
9688
* @param o - 其他选项;
9789
*/
98-
export async function notify(title: string, o?: NotifyOptions): Promise<void> {
99-
await notifyInst(title, o);
90+
export async function notify(title: string, o?: NotifyOptions): Promise<boolean> {
91+
return await notifyInst(title, o);
10092
}
10193

10294
/**
@@ -134,24 +126,26 @@ function init(): JSX.Element {
134126
let bottomRef: HTMLDivElement;
135127
const owner = getOwner();
136128

137-
notifyInst = async (title: string, o?: NotifyOptions): Promise<void> => {
129+
notifyInst = async (title: string, o?: NotifyOptions): Promise<boolean> => {
138130
if (o?.system && document.visibilityState === 'hidden') {
139131
const n = await system(title, { body: o?.body });
140132

141133
if (o?.duration && n) {
142134
await sleep(o.duration);
143135
n.close();
144136
}
145-
return;
137+
return new Promise<boolean>(resolve => resolve(false));
146138
}
147139

140+
const [p, resolve] = createDeferred<boolean>();
141+
148142
const props: MessageProps = {
149143
title: title,
150144
body: o?.body,
151145
type: o?.type,
152146
duration: o?.duration ?? opt.getStays(),
153-
onAccept: o?.accept,
154-
onCancel: o?.cancel,
147+
onAccept: o?.actions?.includes('accept') ? async () => resolve(true) : undefined,
148+
onCancel: o?.actions?.includes('cancel') ? async () => resolve(false) : undefined,
155149
};
156150

157151
const pos = o?.pos ?? opt.getNotifyPosition();
@@ -162,6 +156,8 @@ function init(): JSX.Element {
162156
case 'bottom':
163157
runWithOwner(owner, () => render(() => <Message {...props} />, bottomRef));
164158
}
159+
160+
return p;
165161
};
166162

167163
systemInst = async (title: string, o?: NotificationOptions): Promise<Notification | undefined> => {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// SPDX-FileCopyrightText: 2026 caixw
2+
//
3+
// SPDX-License-Identifier: MIT
4+
5+
type Resolve<T> = (value: T) => void;
6+
7+
// biome-ignore lint/suspicious/noExplicitAny: Promise.reject
8+
type Reject = (reason: any) => void;
9+
10+
export function createDeferred<T>(): [Promise<T>, Resolve<T>, Reject] {
11+
let resolve!: Reject;
12+
let reject!: Reject;
13+
14+
const promise = new Promise<T>((res, rej) => {
15+
resolve = res;
16+
reject = rej;
17+
});
18+
19+
return [promise, resolve, reject];
20+
}

0 commit comments

Comments
 (0)