Skip to content

Commit 02ed988

Browse files
committed
refactor: useMessage #6527
1 parent 6eb4d8f commit 02ed988

File tree

6 files changed

+114
-118
lines changed

6 files changed

+114
-118
lines changed

components/message/PurePanel.tsx

+11-14
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,11 @@ import Notice from '../vc-notification/Notice';
22
import type { NoticeProps } from '../vc-notification/Notice';
33
import useStyle from './style';
44
import type { NoticeType } from './interface';
5-
import {
6-
CheckCircleFilled,
7-
CloseCircleFilled,
8-
ExclamationCircleFilled,
9-
InfoCircleFilled,
10-
LoadingOutlined,
11-
} from '@ant-design/icons-vue';
5+
import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined';
6+
import ExclamationCircleFilled from '@ant-design/icons-vue/ExclamationCircleFilled';
7+
import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled';
8+
import CheckCircleFilled from '@ant-design/icons-vue/CheckCircleFilled';
9+
import InfoCircleFilled from '@ant-design/icons-vue/InfoCircleFilled';
1210
import type { VueNode } from '../_util/type';
1311
import classNames from '../_util/classNames';
1412
import { useConfigContextInject } from '../config-provider/context';
@@ -26,10 +24,9 @@ export interface PureContentProps {
2624
prefixCls: string;
2725
type?: NoticeType;
2826
icon?: VueNode;
29-
children: VueNode;
3027
}
3128

32-
export const PureContent = defineComponent({
29+
export const PureContent = defineComponent<PureContentProps>({
3330
name: 'PureContent',
3431
inheritAttrs: false,
3532
props: ['prefixCls', 'type', 'icon'] as any,
@@ -48,29 +45,29 @@ export const PureContent = defineComponent({
4845

4946
export interface PurePanelProps
5047
extends Omit<NoticeProps, 'prefixCls' | 'eventKey'>,
51-
Omit<PureContentProps, 'prefixCls' | 'children'> {
48+
Omit<PureContentProps, 'prefixCls'> {
5249
prefixCls?: string;
5350
}
5451

5552
/** @private Internal Component. Do not use in your production. */
5653

57-
export default defineComponent({
54+
export default defineComponent<PurePanelProps>({
5855
name: 'PurePanel',
5956
inheritAttrs: false,
6057
props: ['prefixCls', 'class', 'type', 'icon', 'content'] as any,
6158
setup(props, { slots, attrs }) {
6259
const { getPrefixCls } = useConfigContextInject();
63-
const prefixCls = computed(() => props.staticPrefixCls || getPrefixCls('message'));
60+
const prefixCls = computed(() => props.prefixCls || getPrefixCls('message'));
6461
const [, hashId] = useStyle(prefixCls);
6562
return (
6663
<Notice
6764
{...attrs}
6865
prefixCls={prefixCls.value}
69-
class={classNames(hashId, `${prefixCls.value}-notice-pure-panel`)}
66+
class={classNames(hashId.value, `${prefixCls.value}-notice-pure-panel`)}
7067
noticeKey="pure"
7168
duration={null}
7269
>
73-
<PureContent prefixCls={props.prefixCls} type={props.type} icon={props.icon}>
70+
<PureContent prefixCls={prefixCls.value} type={props.type} icon={props.icon}>
7471
{slots.default?.()}
7572
</PureContent>
7673
</Notice>

components/message/demo/hook.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Use `message.useMessage` to get `contextHolder` with context accessible issue. P
1717
</docs>
1818

1919
<template>
20-
<contextHolder />
20+
<context-holder />
2121
<a-button type="primary" @click="info">Display normal message</a-button>
2222
</template>
2323

@@ -26,6 +26,6 @@ import { message } from 'ant-design-vue';
2626
const [messageApi, contextHolder] = message.useMessage();
2727
2828
const info = () => {
29-
messageApi.info('Hello, Ant Design!');
29+
messageApi.info('Hello, Ant Design Vue!');
3030
};
3131
</script>

components/message/interface.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ export interface ConfigOptions {
1414
}
1515

1616
export interface ArgsProps {
17-
content: VueNode;
17+
content: string | (() => VueNode) | VueNode;
1818
duration?: number;
1919
type?: NoticeType;
2020
onClose?: () => void;
21-
icon?: VueNode;
21+
icon?: (() => VueNode) | VueNode;
2222
key?: string | number;
2323
style?: CSSProperties;
24-
className?: string;
24+
class?: string;
2525
onClick?: (e: Event) => void;
2626
}
2727

components/message/useMessage.tsx

+94-95
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ const Holder = defineComponent({
5959
const getStyles = () => ({
6060
left: '50%',
6161
transform: 'translateX(-50%)',
62-
top: top ?? DEFAULT_OFFSET,
62+
top: `${top ?? DEFAULT_OFFSET}px`,
6363
});
6464
const getClassName = () => classNames(hashId.value, props.rtl ? `${prefixCls.value}-rtl` : '');
6565

@@ -113,114 +113,113 @@ export function useInternalMessage(
113113
messageConfig?: HolderProps,
114114
): readonly [MessageInstance, () => VNode] {
115115
const holderRef = shallowRef<HolderRef>(null);
116+
const holderKey = Symbol('messageHolderKey');
116117
// ================================ API ================================
117-
const wrapAPI = computed(() => {
118-
// Wrap with notification content
119-
// >>> close
120-
const close = (key: Key) => {
121-
holderRef.value?.close(key);
122-
};
123-
124-
// >>> Open
125-
const open = (config: ArgsProps): MessageType => {
126-
if (!holderRef.value) {
127-
const fakeResult: any = () => {};
128-
fakeResult.then = () => {};
129-
return fakeResult;
130-
}
131118

132-
const { open: originOpen, prefixCls, hashId } = holderRef.value;
133-
const noticePrefixCls = `${prefixCls}-notice`;
134-
const { content, icon, type, key, className, onClose, ...restConfig } = config;
135-
136-
let mergedKey: Key = key!;
137-
if (mergedKey === undefined || mergedKey === null) {
138-
keyIndex += 1;
139-
mergedKey = `antd-message-${keyIndex}`;
140-
}
141-
142-
return wrapPromiseFn(resolve => {
143-
originOpen({
144-
...restConfig,
145-
key: mergedKey,
146-
content: (
147-
<PureContent prefixCls={prefixCls} type={type} icon={icon}>
148-
{content}
149-
</PureContent>
150-
),
151-
placement: 'top',
152-
// @ts-ignore
153-
class: classNames(type && `${noticePrefixCls}-${type}`, hashId, className),
154-
onClose: () => {
155-
onClose?.();
156-
resolve();
157-
},
158-
});
159-
160-
// Return close function
161-
return () => {
162-
close(mergedKey);
163-
};
119+
// Wrap with notification content
120+
// >>> close
121+
const close = (key: Key) => {
122+
holderRef.value?.close(key);
123+
};
124+
125+
// >>> Open
126+
const open = (config: ArgsProps): MessageType => {
127+
if (!holderRef.value) {
128+
const fakeResult: any = () => {};
129+
fakeResult.then = () => {};
130+
return fakeResult;
131+
}
132+
133+
const { open: originOpen, prefixCls, hashId } = holderRef.value;
134+
const noticePrefixCls = `${prefixCls}-notice`;
135+
const { content, icon, type, key, class: className, onClose, ...restConfig } = config;
136+
137+
let mergedKey: Key = key!;
138+
if (mergedKey === undefined || mergedKey === null) {
139+
keyIndex += 1;
140+
mergedKey = `antd-message-${keyIndex}`;
141+
}
142+
143+
return wrapPromiseFn(resolve => {
144+
originOpen({
145+
...restConfig,
146+
key: mergedKey,
147+
content: () => (
148+
<PureContent
149+
prefixCls={prefixCls}
150+
type={type}
151+
icon={typeof icon === 'function' ? icon() : icon}
152+
>
153+
{typeof content === 'function' ? content() : content}
154+
</PureContent>
155+
),
156+
placement: 'top',
157+
// @ts-ignore
158+
class: classNames(type && `${noticePrefixCls}-${type}`, hashId, className),
159+
onClose: () => {
160+
onClose?.();
161+
resolve();
162+
},
164163
});
165-
};
166164

167-
// >>> destroy
168-
const destroy = (key?: Key) => {
169-
if (key !== undefined) {
170-
close(key);
165+
// Return close function
166+
return () => {
167+
close(mergedKey);
168+
};
169+
});
170+
};
171+
172+
// >>> destroy
173+
const destroy = (key?: Key) => {
174+
if (key !== undefined) {
175+
close(key);
176+
} else {
177+
holderRef.value?.destroy();
178+
}
179+
};
180+
181+
const wrapAPI = {
182+
open,
183+
destroy,
184+
} as MessageInstance;
185+
186+
const keys: NoticeType[] = ['info', 'success', 'warning', 'error', 'loading'];
187+
keys.forEach(type => {
188+
const typeOpen: TypeOpen = (jointContent, duration, onClose) => {
189+
let config: ArgsProps;
190+
if (jointContent && typeof jointContent === 'object' && 'content' in jointContent) {
191+
config = jointContent;
171192
} else {
172-
holderRef.value?.destroy();
193+
config = {
194+
content: jointContent as VNode,
195+
};
173196
}
174-
};
175197

176-
const clone = {
177-
open,
178-
destroy,
179-
} as MessageInstance;
180-
181-
const keys: NoticeType[] = ['info', 'success', 'warning', 'error', 'loading'];
182-
keys.forEach(type => {
183-
const typeOpen: TypeOpen = (jointContent, duration, onClose) => {
184-
let config: ArgsProps;
185-
if (jointContent && typeof jointContent === 'object' && 'content' in jointContent) {
186-
config = jointContent;
187-
} else {
188-
config = {
189-
content: jointContent as VNode,
190-
};
191-
}
192-
193-
// Params
194-
let mergedDuration: number | undefined;
195-
let mergedOnClose: VoidFunction | undefined;
196-
if (typeof duration === 'function') {
197-
mergedOnClose = duration;
198-
} else {
199-
mergedDuration = duration;
200-
mergedOnClose = onClose;
201-
}
202-
203-
const mergedConfig = {
204-
onClose: mergedOnClose,
205-
duration: mergedDuration,
206-
...config,
207-
type,
208-
};
198+
// Params
199+
let mergedDuration: number | undefined;
200+
let mergedOnClose: VoidFunction | undefined;
201+
if (typeof duration === 'function') {
202+
mergedOnClose = duration;
203+
} else {
204+
mergedDuration = duration;
205+
mergedOnClose = onClose;
206+
}
209207

210-
return open(mergedConfig);
208+
const mergedConfig = {
209+
onClose: mergedOnClose,
210+
duration: mergedDuration,
211+
...config,
212+
type,
211213
};
212214

213-
clone[type] = typeOpen;
214-
});
215+
return open(mergedConfig);
216+
};
215217

216-
return clone;
218+
wrapAPI[type] = typeOpen;
217219
});
218220

219221
// ============================== Return ===============================
220-
return [
221-
wrapAPI.value,
222-
() => <Holder key="message-holder" {...messageConfig} ref={holderRef} />,
223-
] as const;
222+
return [wrapAPI, () => <Holder key={holderKey} {...messageConfig} ref={holderRef} />] as const;
224223
}
225224

226225
export default function useMessage(messageConfig?: ConfigOptions) {

components/modal/useModal/index.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,8 @@ function useModal(): readonly [
144144
warning: getConfirmFunc(withWarn),
145145
confirm: getConfirmFunc(withConfirm),
146146
}));
147-
148-
return [fns.value, () => <ElementsHolder key="modal-holder" ref={holderRef} />] as const;
147+
const holderKey = Symbol('modalHolderKey');
148+
return [fns.value, () => <ElementsHolder key={holderKey} ref={holderRef} />] as const;
149149
}
150150

151151
export default useModal;

components/vc-notification/Notification.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export type Placement = 'top' | 'topLeft' | 'topRight' | 'bottom' | 'bottomLeft'
3939
export interface OpenConfig extends NoticeProps {
4040
key: Key;
4141
placement?: Placement;
42-
content?: VueNode;
42+
content?: string | (() => VueNode) | VueNode;
4343
duration?: number | null;
4444
}
4545

@@ -254,7 +254,7 @@ Notification.newInstance = function newNotificationInstance(properties, callback
254254
const rootPrefixCls = global.getRootPrefixCls(customRootPrefixCls, prefixCls.value);
255255
const transitionName = hasTransitionName
256256
? customTransitionName
257-
: `${rootPrefixCls}-${customTransitionName}`;
257+
: `${prefixCls.value}-${customTransitionName}`;
258258
return (
259259
<ConfigProvider {...global} prefixCls={rootPrefixCls}>
260260
<Notification

0 commit comments

Comments
 (0)