Skip to content

Commit 4be5d42

Browse files
committed
fix(components): 修正以下几处与对话框相关的错误
- CancelButton 现在会注册对话框的 cancel 事件,保证对话框返回值的正确; - Dialog 下的 alert、confirm 和 prompt 不再注册多个 Promise 对象;
1 parent a9a8d14 commit 4be5d42

2 files changed

Lines changed: 70 additions & 11 deletions

File tree

packages/components/src/dialog/buttons.tsx

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ export function AcceptButton(props: ButtonProps): JSX.Element {
6262
export function CancelButton(props: ButtonProps): JSX.Element {
6363
const ref = useDialog();
6464
const [_, p] = splitProps(props, ['children', 'palette', 'onclick']);
65+
66+
// 注册 cancel 事件的返回值
67+
ref.dialog.root().addEventListener('cancel', () => (ref.dialog.root().returnValue = props.value ?? ''));
68+
6569
return (
6670
<Button.Root
6771
{...p}
@@ -85,10 +89,39 @@ export function CancelButton(props: ButtonProps): JSX.Element {
8589
}
8690

8791
export interface ActionsProps {
92+
/**
93+
* 所有按钮是否都圆角
94+
*/
8895
rounded?: boolean;
96+
97+
/**
98+
* 所有的按钮是否都是方形
99+
*/
89100
square?: boolean;
101+
102+
/**
103+
* OK 按钮上的点击事件
104+
*/
90105
accept?: ButtonProps['onclick'];
106+
107+
/**
108+
* cancel 按钮上的占击事件
109+
*/
91110
cancel?: ButtonProps['onclick'];
111+
112+
/**
113+
* OK 按钮上的值
114+
*
115+
* @defaultValue 'accept'
116+
*/
117+
acceptValue?: string;
118+
119+
/**
120+
* cancel 按钮上的值
121+
*
122+
* @defaultValue 'cancel'
123+
*/
124+
cancelValue?: string;
92125
}
93126

94127
/**
@@ -98,10 +131,20 @@ export function Actions(props: ActionsProps): JSX.Element {
98131
const l = useLocale();
99132
return (
100133
<footer class={styles.footer}>
101-
<CancelButton rounded={props.rounded} square={props.square} onclick={props.cancel} value="cancel">
134+
<CancelButton
135+
rounded={props.rounded}
136+
square={props.square}
137+
onclick={props.cancel}
138+
value={props.cancelValue ?? 'cancel'}
139+
>
102140
{l.t('_c.cancel')}
103141
</CancelButton>
104-
<AcceptButton rounded={props.rounded} square={props.square} onclick={props.accept} value="accept">
142+
<AcceptButton
143+
rounded={props.rounded}
144+
square={props.square}
145+
onclick={props.accept}
146+
value={props.acceptValue ?? 'accept'}
147+
>
105148
{l.t('_c.ok')}
106149
</AcceptButton>
107150
</footer>

packages/components/src/dialog/system.tsx

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import { Toolbar } from './toolbar';
1616

1717
export type Props = BaseProps & ParentProps & MountProps;
1818

19+
const acceptValue = 'accept';
20+
1921
/**
2022
* 提供了 {@link alert}、{@link confirm} 和 {@link prompt} 的方法,可用于替换对应的浏览器方法。
2123
*/
@@ -46,7 +48,12 @@ function AlertProvider(props: BaseProps): JSX.Element {
4648
dlg.root().showModal();
4749

4850
return new Promise<void>(resolve => {
49-
dlg.root().addEventListener('close', () => resolve());
51+
const close = () => {
52+
resolve();
53+
dlg.root().removeEventListener('close', close);
54+
};
55+
56+
dlg.root().addEventListener('close', close);
5057
});
5158
};
5259

@@ -95,9 +102,12 @@ function ConfirmProvider(props: BaseProps): JSX.Element {
95102
dlg.root().showModal();
96103

97104
return new Promise<boolean>(resolve => {
98-
dlg.root().addEventListener('close', () => {
99-
resolve(dlg.root().returnValue === 'true');
100-
});
105+
const close = () => {
106+
resolve(dlg.root().returnValue === acceptValue);
107+
dlg.root().removeEventListener('close', close);
108+
};
109+
110+
dlg.root().addEventListener('close', close);
101111
});
102112
};
103113

@@ -111,7 +121,7 @@ function ConfirmProvider(props: BaseProps): JSX.Element {
111121
}
112122
class="min-w-60"
113123
ref={el => (dlg = el)}
114-
footer={<Actions />}
124+
footer={<Actions acceptValue={acceptValue} />}
115125
>
116126
<p>{msg()}</p>
117127
</Root>
@@ -144,10 +154,16 @@ function PromptProvider(props: BaseProps): JSX.Element {
144154
dlg.root().showModal();
145155

146156
return new Promise<string | null>(resolve => {
147-
dlg.root().addEventListener('close', () => {
148-
resolve(dlg.root().returnValue ?? null);
157+
const close = () => {
158+
if (dlg.root().returnValue === acceptValue) {
159+
const v = access.getValue();
160+
resolve(v);
161+
}
149162
access.setValue('');
150-
});
163+
dlg.root().removeEventListener('close', close);
164+
};
165+
166+
dlg.root().addEventListener('close', close);
151167
});
152168
};
153169

@@ -161,7 +177,7 @@ function PromptProvider(props: BaseProps): JSX.Element {
161177
}
162178
ref={el => (dlg = el)}
163179
class="min-w-60"
164-
footer={<Actions />}
180+
footer={<Actions acceptValue={acceptValue} />}
165181
>
166182
<TextField.Root class="w-full" layout="vertical" label={msg()} accessor={access} />
167183
</Root>

0 commit comments

Comments
 (0)