@rainbow-oh/yee-c 0.8.2 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Input/style/index.less +1 -0
- package/dist/cjs/Selector/style/index.less +1 -0
- package/dist/cjs/Table/icon/arrow-icon.js +1 -1
- package/dist/cjs/Table/theader/cell.js +6 -3
- package/dist/cjs/TextArea/style/index.less +1 -0
- package/dist/cjs/VerificationCode/style/index.less +1 -0
- package/dist/cjs/hooks/useCountdown.d.ts +2 -1
- package/dist/cjs/hooks/useCountdown.js +46 -23
- package/dist/cjs/locale/interface.d.ts +3 -0
- package/dist/cjs/locale/lang/en_US.js +4 -1
- package/dist/cjs/locale/lang/ja_JP.js +4 -1
- package/dist/cjs/locale/lang/zh_CN.js +4 -1
- package/dist/cjs/locale/lang/zh_TW.js +4 -1
- package/dist/cjs/message/demo/base.js +1 -1
- package/dist/cjs/message/index.d.ts +1 -1
- package/dist/cjs/message/interface.d.ts +16 -7
- package/dist/cjs/message/message-provider.d.ts +2 -1
- package/dist/cjs/message/message-provider.js +1 -1
- package/dist/cjs/message/message.js +14 -9
- package/dist/cjs/message/style/index.less +3 -1
- package/dist/cjs/message/use-message.d.ts +3 -12
- package/dist/cjs/message/use-message.js +103 -45
- package/dist/cjs/message/wrapper.d.ts +21 -27
- package/dist/cjs/message/wrapper.js +49 -19
- package/dist/cjs/notice/index.d.ts +1 -1
- package/dist/cjs/notice/interface.d.ts +17 -7
- package/dist/cjs/notice/notice-list.d.ts +3 -3
- package/dist/cjs/notice/notice-provider.d.ts +2 -1
- package/dist/cjs/notice/notice-provider.js +1 -1
- package/dist/cjs/notice/notice.js +63 -20
- package/dist/cjs/notice/style/index.less +13 -1
- package/dist/cjs/notice/use-notice.d.ts +2 -11
- package/dist/cjs/notice/use-notice.js +156 -71
- package/dist/cjs/notice/wrapper.d.ts +19 -15
- package/dist/cjs/notice/wrapper.js +122 -52
- package/dist/cjs/style/size.css +3 -3
- package/dist/cjs/style/themes.css +1 -1
- package/dist/cjs/style/variables.css +4 -4
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/Input/style/index.less +1 -0
- package/dist/esm/Selector/style/index.less +1 -0
- package/dist/esm/Table/icon/arrow-icon.js +1 -1
- package/dist/esm/Table/theader/cell.js +7 -3
- package/dist/esm/TextArea/style/index.less +1 -0
- package/dist/esm/VerificationCode/style/index.less +1 -0
- package/dist/esm/hooks/useCountdown.d.ts +2 -1
- package/dist/esm/hooks/useCountdown.js +44 -14
- package/dist/esm/locale/interface.d.ts +3 -0
- package/dist/esm/locale/lang/en_US.js +4 -1
- package/dist/esm/locale/lang/ja_JP.js +4 -1
- package/dist/esm/locale/lang/zh_CN.js +4 -1
- package/dist/esm/locale/lang/zh_TW.js +4 -1
- package/dist/esm/message/demo/base.js +4 -1
- package/dist/esm/message/index.d.ts +1 -1
- package/dist/esm/message/interface.d.ts +16 -7
- package/dist/esm/message/message-provider.d.ts +2 -1
- package/dist/esm/message/message-provider.js +1 -1
- package/dist/esm/message/message.js +22 -9
- package/dist/esm/message/style/index.less +3 -1
- package/dist/esm/message/use-message.d.ts +3 -12
- package/dist/esm/message/use-message.js +129 -79
- package/dist/esm/message/wrapper.d.ts +21 -27
- package/dist/esm/message/wrapper.js +60 -18
- package/dist/esm/notice/index.d.ts +1 -1
- package/dist/esm/notice/interface.d.ts +17 -7
- package/dist/esm/notice/notice-list.d.ts +3 -3
- package/dist/esm/notice/notice-provider.d.ts +2 -1
- package/dist/esm/notice/notice-provider.js +1 -1
- package/dist/esm/notice/notice.js +73 -21
- package/dist/esm/notice/style/index.less +13 -1
- package/dist/esm/notice/use-notice.d.ts +2 -11
- package/dist/esm/notice/use-notice.js +180 -100
- package/dist/esm/notice/wrapper.d.ts +19 -15
- package/dist/esm/notice/wrapper.js +144 -62
- package/dist/esm/style/size.css +3 -3
- package/dist/esm/style/themes.css +1 -1
- package/dist/esm/style/variables.css +4 -4
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/umd/yee-c.min.css +2 -2
- package/dist/umd/yee-c.min.js +1 -1
- package/package.json +1 -1
- package/src/Input/style/index.less +1 -0
- package/src/Selector/style/index.less +1 -0
- package/src/Table/icon/arrow-icon.tsx +1 -1
- package/src/Table/theader/cell.tsx +6 -3
- package/src/TextArea/style/index.less +1 -0
- package/src/VerificationCode/style/index.less +1 -0
- package/src/hooks/useCountdown.ts +52 -21
- package/src/locale/interface.ts +3 -0
- package/src/locale/lang/en_US.ts +3 -0
- package/src/locale/lang/ja_JP.ts +3 -0
- package/src/locale/lang/zh_CN.ts +3 -0
- package/src/locale/lang/zh_TW.ts +3 -0
- package/src/message/demo/base.tsx +1 -1
- package/src/message/index.ts +1 -1
- package/src/message/interface.ts +22 -7
- package/src/message/message-provider.tsx +3 -2
- package/src/message/message.test.tsx +283 -0
- package/src/message/message.tsx +14 -9
- package/src/message/style/index.less +3 -1
- package/src/message/use-message.tsx +144 -67
- package/src/message/wrapper.tsx +62 -20
- package/src/notice/index.en-US.md +76 -75
- package/src/notice/index.ts +6 -1
- package/src/notice/index.zh-CN.md +3 -2
- package/src/notice/interface.ts +31 -14
- package/src/notice/notice-list.tsx +3 -9
- package/src/notice/notice-provider.tsx +3 -2
- package/src/notice/notice.test.tsx +450 -0
- package/src/notice/notice.tsx +69 -21
- package/src/notice/style/index.less +13 -1
- package/src/notice/use-notice.tsx +210 -94
- package/src/notice/wrapper.tsx +159 -71
- package/src/style/size.css +3 -3
- package/src/version.ts +1 -1
package/src/message/message.tsx
CHANGED
|
@@ -5,10 +5,10 @@ import Spin from '../Spin';
|
|
|
5
5
|
import type { MessageProps } from './interface';
|
|
6
6
|
|
|
7
7
|
const icons = {
|
|
8
|
-
info: <Info size={
|
|
9
|
-
success: <CircleCheck size={
|
|
10
|
-
warning: <CircleAlert size={
|
|
11
|
-
error: <CircleX size={
|
|
8
|
+
info: <Info size={22} fill='currentColor' stroke="#FFF" strokeWidth={2} />,
|
|
9
|
+
success: <CircleCheck size={22} fill='currentColor' stroke="#FFF" strokeWidth={2} />,
|
|
10
|
+
warning: <CircleAlert size={22} fill='currentColor' stroke="#FFF" strokeWidth={2} />,
|
|
11
|
+
error: <CircleX size={22} fill='currentColor' stroke="#FFF" strokeWidth={2} />,
|
|
12
12
|
loading: <Spin className="loading" type="spin" size="small" height="auto" />,
|
|
13
13
|
};
|
|
14
14
|
|
|
@@ -16,6 +16,7 @@ const Message: React.FC<MessageProps & { id: string | number }> = (props) => {
|
|
|
16
16
|
const {
|
|
17
17
|
prefixCls = 'yee-message',
|
|
18
18
|
id: key,
|
|
19
|
+
timerGeneration,
|
|
19
20
|
status,
|
|
20
21
|
content,
|
|
21
22
|
style,
|
|
@@ -32,15 +33,14 @@ const Message: React.FC<MessageProps & { id: string | number }> = (props) => {
|
|
|
32
33
|
useEffect(() => {
|
|
33
34
|
if (duration && duration > 0) {
|
|
34
35
|
const timer = setTimeout(() => {
|
|
35
|
-
onDestroy?.(key);
|
|
36
|
-
onClose?.();
|
|
36
|
+
onDestroy?.(key, timerGeneration);
|
|
37
37
|
}, duration * 1000);
|
|
38
38
|
|
|
39
39
|
return () => {
|
|
40
40
|
clearTimeout(timer);
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
|
-
}, [duration, key, onDestroy, onClose]);
|
|
43
|
+
}, [duration, key, onDestroy, onClose, timerGeneration]);
|
|
44
44
|
|
|
45
45
|
const renderIcon = () => {
|
|
46
46
|
if (!icon && !status) {
|
|
@@ -48,22 +48,27 @@ const Message: React.FC<MessageProps & { id: string | number }> = (props) => {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
return (
|
|
51
|
-
<span className={`${prefixCls}-icon`}>
|
|
51
|
+
<span aria-hidden="true" className={`${prefixCls}-icon`}>
|
|
52
52
|
{icon ? icon : status ? icons[status] : null}
|
|
53
53
|
</span>
|
|
54
54
|
);
|
|
55
55
|
};
|
|
56
56
|
|
|
57
|
+
const isAssertive = status === 'error' || status === 'warning';
|
|
58
|
+
|
|
57
59
|
return (
|
|
58
60
|
<div
|
|
59
61
|
{...rest}
|
|
62
|
+
aria-atomic="true"
|
|
63
|
+
aria-live={isAssertive ? 'assertive' : 'polite'}
|
|
64
|
+
role={isAssertive ? 'alert' : 'status'}
|
|
60
65
|
data-testid={dataTestId}
|
|
61
66
|
className={clsx(prefixCls, [`${prefixCls}-${status}`], className)}
|
|
62
67
|
style={style}
|
|
63
68
|
onClick={onClick}
|
|
64
69
|
>
|
|
65
70
|
{renderIcon()}
|
|
66
|
-
<
|
|
71
|
+
<div className={`${prefixCls}-content`}>{content}</div>
|
|
67
72
|
</div>
|
|
68
73
|
);
|
|
69
74
|
};
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
align-items: center;
|
|
7
7
|
width: fit-content;
|
|
8
8
|
padding: var(--yee-message-padding);
|
|
9
|
+
pointer-events: auto;
|
|
9
10
|
background-color: var(--yee-message-bg-color);
|
|
10
11
|
border-radius: var(--yee-message-border-radius);
|
|
11
12
|
box-shadow: var(--yee-message-box-shadow);
|
|
@@ -30,12 +31,13 @@
|
|
|
30
31
|
align-items: center;
|
|
31
32
|
justify-content: center;
|
|
32
33
|
width: 100vw;
|
|
34
|
+
pointer-events: none;
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
// status
|
|
36
38
|
&-success {
|
|
37
39
|
@{pls}-icon {
|
|
38
|
-
color: var(--yee-
|
|
40
|
+
color: var(--yee-success-color);
|
|
39
41
|
}
|
|
40
42
|
}
|
|
41
43
|
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
useCallback,
|
|
3
|
+
useEffect,
|
|
4
|
+
useMemo,
|
|
5
|
+
useRef,
|
|
6
|
+
useState,
|
|
7
|
+
} from 'react';
|
|
2
8
|
import { createPortal } from 'react-dom';
|
|
3
9
|
import {
|
|
4
|
-
|
|
10
|
+
MessageApi,
|
|
5
11
|
MessageType,
|
|
6
12
|
WrapperedMessageConfig,
|
|
7
13
|
} from './interface';
|
|
@@ -9,82 +15,153 @@ import Message from './message';
|
|
|
9
15
|
|
|
10
16
|
const useMessage = () => {
|
|
11
17
|
const [messages, setMessages] = useState<MessageType[]>([]);
|
|
18
|
+
const [portalContainer, setPortalContainer] = useState<HTMLElement | null>(
|
|
19
|
+
null,
|
|
20
|
+
);
|
|
21
|
+
const messagesRef = useRef<MessageType[]>([]);
|
|
22
|
+
const generationByKey = useRef(new Map<string | number, number>());
|
|
23
|
+
const generation = useRef(0);
|
|
24
|
+
const timerGeneration = useRef(0);
|
|
12
25
|
const count = useRef(0);
|
|
13
26
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
...prevMessage.filter((msg) => msg.key !== key),
|
|
17
|
-
]);
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const add = useCallback((props: WrapperedMessageConfig) => {
|
|
21
|
-
const id = count.current++;
|
|
22
|
-
setMessages((prevMessages) => [...prevMessages, { key: id, ...props }]);
|
|
23
|
-
return () => onDestroy(id);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
setPortalContainer(document.body);
|
|
24
29
|
}, []);
|
|
25
30
|
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
: { status: 'info', ...props },
|
|
32
|
-
);
|
|
33
|
-
},
|
|
34
|
-
info: (props: string | MessageConfig) => {
|
|
35
|
-
return add(
|
|
36
|
-
typeof props === 'string'
|
|
37
|
-
? { content: props, status: 'info' }
|
|
38
|
-
: { status: 'info', ...props },
|
|
39
|
-
);
|
|
40
|
-
},
|
|
41
|
-
success: (props: string | MessageConfig) => {
|
|
42
|
-
return add(
|
|
43
|
-
typeof props === 'string'
|
|
44
|
-
? { content: props, status: 'success' }
|
|
45
|
-
: { ...props, status: 'success' },
|
|
46
|
-
);
|
|
47
|
-
},
|
|
48
|
-
error: (props: string | MessageConfig) => {
|
|
49
|
-
return add(
|
|
50
|
-
typeof props === 'string'
|
|
51
|
-
? { content: props, status: 'error' }
|
|
52
|
-
: { ...props, status: 'error' },
|
|
53
|
-
);
|
|
54
|
-
},
|
|
55
|
-
warning: (props: string | MessageConfig) => {
|
|
56
|
-
return add(
|
|
57
|
-
typeof props === 'string'
|
|
58
|
-
? { content: props, status: 'warning' }
|
|
59
|
-
: { ...props, status: 'warning' },
|
|
60
|
-
);
|
|
61
|
-
},
|
|
62
|
-
loading: (props: string | MessageConfig) => {
|
|
63
|
-
return add(
|
|
64
|
-
typeof props === 'string'
|
|
65
|
-
? { content: props, status: 'loading' }
|
|
66
|
-
: { ...props, status: 'loading' },
|
|
67
|
-
);
|
|
31
|
+
const updateMessages = useCallback(
|
|
32
|
+
(updater: (current: MessageType[]) => MessageType[]) => {
|
|
33
|
+
const nextMessages = updater(messagesRef.current);
|
|
34
|
+
messagesRef.current = nextMessages;
|
|
35
|
+
setMessages(nextMessages);
|
|
68
36
|
},
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
37
|
+
[],
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const onDestroy = useCallback(
|
|
41
|
+
(key: string | number, expectedTimerGeneration?: number) => {
|
|
42
|
+
const target = messagesRef.current.find((message) => message.key === key);
|
|
43
|
+
if (
|
|
44
|
+
expectedTimerGeneration !== undefined &&
|
|
45
|
+
target?.timerGeneration !== expectedTimerGeneration
|
|
46
|
+
) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (!target) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
generationByKey.current.delete(key);
|
|
55
|
+
updateMessages((current) =>
|
|
56
|
+
current.filter((message) => message.key !== key),
|
|
72
57
|
);
|
|
58
|
+
target.onClose?.();
|
|
73
59
|
},
|
|
74
|
-
|
|
75
|
-
|
|
60
|
+
[updateMessages],
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const add = useCallback(
|
|
64
|
+
(props: WrapperedMessageConfig) => {
|
|
65
|
+
const key = props.key ?? count.current++;
|
|
66
|
+
if (typeof key === 'number' && key >= count.current) {
|
|
67
|
+
count.current = key + 1;
|
|
68
|
+
}
|
|
69
|
+
const keyGeneration =
|
|
70
|
+
generationByKey.current.get(key) ?? generation.current++;
|
|
71
|
+
generationByKey.current.set(key, keyGeneration);
|
|
72
|
+
const nextMessage = {
|
|
73
|
+
...props,
|
|
74
|
+
key,
|
|
75
|
+
timerGeneration: timerGeneration.current++,
|
|
76
|
+
} as MessageType;
|
|
77
|
+
|
|
78
|
+
updateMessages((current) => {
|
|
79
|
+
const exists = current.some((item) => item.key === key);
|
|
80
|
+
if (exists) {
|
|
81
|
+
return current.map((item) =>
|
|
82
|
+
item.key === key ? nextMessage : item,
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
return [...current, nextMessage];
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
return () => {
|
|
89
|
+
if (generationByKey.current.get(key) === keyGeneration) {
|
|
90
|
+
onDestroy(key);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
76
93
|
},
|
|
77
|
-
|
|
94
|
+
[onDestroy, updateMessages],
|
|
95
|
+
);
|
|
78
96
|
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
97
|
+
const clear = useCallback(() => {
|
|
98
|
+
const currentMessages = messagesRef.current;
|
|
99
|
+
generationByKey.current.clear();
|
|
100
|
+
messagesRef.current = [];
|
|
101
|
+
setMessages([]);
|
|
102
|
+
currentMessages.forEach((message) => message.onClose?.());
|
|
103
|
+
}, []);
|
|
104
|
+
|
|
105
|
+
const messageApi = useMemo<MessageApi>(
|
|
106
|
+
() => ({
|
|
107
|
+
open: (props) =>
|
|
108
|
+
add(
|
|
109
|
+
typeof props === 'string'
|
|
110
|
+
? { content: props, status: 'info' }
|
|
111
|
+
: { status: 'info', ...props },
|
|
112
|
+
),
|
|
113
|
+
info: (props) =>
|
|
114
|
+
add(
|
|
115
|
+
typeof props === 'string'
|
|
116
|
+
? { content: props, status: 'info' }
|
|
117
|
+
: { status: 'info', ...props },
|
|
118
|
+
),
|
|
119
|
+
success: (props) =>
|
|
120
|
+
add(
|
|
121
|
+
typeof props === 'string'
|
|
122
|
+
? { content: props, status: 'success' }
|
|
123
|
+
: { ...props, status: 'success' },
|
|
124
|
+
),
|
|
125
|
+
error: (props) =>
|
|
126
|
+
add(
|
|
127
|
+
typeof props === 'string'
|
|
128
|
+
? { content: props, status: 'error' }
|
|
129
|
+
: { ...props, status: 'error' },
|
|
130
|
+
),
|
|
131
|
+
warning: (props) =>
|
|
132
|
+
add(
|
|
133
|
+
typeof props === 'string'
|
|
134
|
+
? { content: props, status: 'warning' }
|
|
135
|
+
: { ...props, status: 'warning' },
|
|
136
|
+
),
|
|
137
|
+
loading: (props) =>
|
|
138
|
+
add(
|
|
139
|
+
typeof props === 'string'
|
|
140
|
+
? { content: props, status: 'loading' }
|
|
141
|
+
: { ...props, status: 'loading' },
|
|
142
|
+
),
|
|
143
|
+
destroy: onDestroy,
|
|
144
|
+
clear,
|
|
145
|
+
}),
|
|
146
|
+
[add, clear, onDestroy],
|
|
86
147
|
);
|
|
87
148
|
|
|
149
|
+
const messageHolder = portalContainer
|
|
150
|
+
? createPortal(
|
|
151
|
+
<div className="yee-message-list">
|
|
152
|
+
{messages.map((msg) => (
|
|
153
|
+
<Message
|
|
154
|
+
{...msg}
|
|
155
|
+
onDestroy={onDestroy}
|
|
156
|
+
id={msg.key}
|
|
157
|
+
key={msg.key}
|
|
158
|
+
/>
|
|
159
|
+
))}
|
|
160
|
+
</div>,
|
|
161
|
+
portalContainer,
|
|
162
|
+
)
|
|
163
|
+
: null;
|
|
164
|
+
|
|
88
165
|
return { messageApi, messageHolder };
|
|
89
166
|
};
|
|
90
167
|
|
package/src/message/wrapper.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { createRoot, Root } from 'react-dom/client';
|
|
3
3
|
import {
|
|
4
|
+
MessageClose,
|
|
4
5
|
MessageConfig,
|
|
5
6
|
MessageType,
|
|
6
7
|
WrapperedMessageConfig,
|
|
@@ -8,15 +9,24 @@ import {
|
|
|
8
9
|
import MessageList from './message-list';
|
|
9
10
|
import useMessage from './use-message';
|
|
10
11
|
|
|
12
|
+
const noop: MessageClose = () => {};
|
|
13
|
+
|
|
11
14
|
class MessageWrapper {
|
|
12
15
|
root: Root | null;
|
|
13
16
|
messages: MessageType[];
|
|
14
17
|
container: HTMLElement | null;
|
|
18
|
+
generationByKey: Map<string | number, number>;
|
|
19
|
+
generation: number;
|
|
20
|
+
timerGeneration: number;
|
|
15
21
|
|
|
16
22
|
constructor() {
|
|
17
23
|
this.root = null;
|
|
18
24
|
this.messages = [];
|
|
19
25
|
this.container = null;
|
|
26
|
+
this.generationByKey = new Map();
|
|
27
|
+
this.generation = 0;
|
|
28
|
+
this.timerGeneration = 0;
|
|
29
|
+
this.destroy = this.destroy.bind(this);
|
|
20
30
|
}
|
|
21
31
|
|
|
22
32
|
private createContainer() {
|
|
@@ -50,9 +60,14 @@ class MessageWrapper {
|
|
|
50
60
|
this.root = null;
|
|
51
61
|
this.cleanupContainer();
|
|
52
62
|
this.messages = [];
|
|
63
|
+
this.generationByKey.clear();
|
|
53
64
|
}
|
|
54
65
|
|
|
55
66
|
render() {
|
|
67
|
+
if (typeof document === 'undefined') {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
56
71
|
if (this.messages.length === 0) {
|
|
57
72
|
if (this.root) {
|
|
58
73
|
this.root.unmount();
|
|
@@ -68,40 +83,67 @@ class MessageWrapper {
|
|
|
68
83
|
}
|
|
69
84
|
|
|
70
85
|
this.root.render(
|
|
71
|
-
<MessageList items={this.messages} onDestroy={this.destroy
|
|
86
|
+
<MessageList items={this.messages} onDestroy={this.destroy} />,
|
|
72
87
|
);
|
|
73
88
|
}
|
|
74
89
|
|
|
75
|
-
show(params: WrapperedMessageConfig) {
|
|
76
|
-
if (
|
|
77
|
-
|
|
90
|
+
show(params: WrapperedMessageConfig): MessageClose {
|
|
91
|
+
if (typeof document === 'undefined') {
|
|
92
|
+
return noop;
|
|
78
93
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
94
|
+
|
|
95
|
+
const key = params.key ?? this.uuid();
|
|
96
|
+
const keyGeneration =
|
|
97
|
+
this.generationByKey.get(key) ?? this.generation++;
|
|
98
|
+
this.generationByKey.set(key, keyGeneration);
|
|
99
|
+
const nextMessage = {
|
|
100
|
+
...params,
|
|
101
|
+
key,
|
|
102
|
+
timerGeneration: this.timerGeneration++,
|
|
103
|
+
} as MessageType;
|
|
104
|
+
const exists = this.messages.some((item) => item.key === key);
|
|
105
|
+
|
|
106
|
+
if (exists) {
|
|
107
|
+
this.messages = this.messages.map((item) =>
|
|
108
|
+
item.key === key ? nextMessage : item,
|
|
109
|
+
);
|
|
87
110
|
} else {
|
|
88
|
-
this.messages.
|
|
111
|
+
this.messages = [...this.messages, nextMessage];
|
|
89
112
|
}
|
|
90
113
|
|
|
91
114
|
this.render();
|
|
115
|
+
return () => {
|
|
116
|
+
if (this.generationByKey.get(key) === keyGeneration) {
|
|
117
|
+
this.destroy(key);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
92
120
|
}
|
|
93
121
|
|
|
94
|
-
destroy(key: string | number) {
|
|
122
|
+
destroy(key: string | number, expectedTimerGeneration?: number) {
|
|
123
|
+
const target = this.messages.find((item) => item.key === key);
|
|
124
|
+
if (
|
|
125
|
+
expectedTimerGeneration !== undefined &&
|
|
126
|
+
target?.timerGeneration !== expectedTimerGeneration
|
|
127
|
+
) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (!target) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
this.generationByKey.delete(key);
|
|
95
136
|
this.messages = this.messages.filter((item) => item.key !== key);
|
|
96
137
|
this.render();
|
|
138
|
+
target.onClose?.();
|
|
97
139
|
}
|
|
98
140
|
|
|
99
141
|
open(params: string | MessageConfig) {
|
|
100
|
-
this.show(typeof params === 'string' ? { content: params } : params);
|
|
142
|
+
return this.show(typeof params === 'string' ? { content: params } : params);
|
|
101
143
|
}
|
|
102
144
|
|
|
103
145
|
info(params: string | MessageConfig) {
|
|
104
|
-
this.show(
|
|
146
|
+
return this.show(
|
|
105
147
|
typeof params === 'string'
|
|
106
148
|
? { status: 'info', content: params }
|
|
107
149
|
: { ...params, status: 'info' },
|
|
@@ -109,7 +151,7 @@ class MessageWrapper {
|
|
|
109
151
|
}
|
|
110
152
|
|
|
111
153
|
success(params: string | MessageConfig) {
|
|
112
|
-
this.show(
|
|
154
|
+
return this.show(
|
|
113
155
|
typeof params === 'string'
|
|
114
156
|
? { status: 'success', content: params }
|
|
115
157
|
: { ...params, status: 'success' },
|
|
@@ -117,7 +159,7 @@ class MessageWrapper {
|
|
|
117
159
|
}
|
|
118
160
|
|
|
119
161
|
warning(params: string | MessageConfig) {
|
|
120
|
-
this.show(
|
|
162
|
+
return this.show(
|
|
121
163
|
typeof params === 'string'
|
|
122
164
|
? { status: 'warning', content: params }
|
|
123
165
|
: { ...params, status: 'warning' },
|
|
@@ -125,7 +167,7 @@ class MessageWrapper {
|
|
|
125
167
|
}
|
|
126
168
|
|
|
127
169
|
error(params: string | MessageConfig) {
|
|
128
|
-
this.show(
|
|
170
|
+
return this.show(
|
|
129
171
|
typeof params === 'string'
|
|
130
172
|
? { status: 'error', content: params }
|
|
131
173
|
: { ...params, status: 'error' },
|
|
@@ -133,7 +175,7 @@ class MessageWrapper {
|
|
|
133
175
|
}
|
|
134
176
|
|
|
135
177
|
loading(params: string | MessageConfig) {
|
|
136
|
-
this.show(
|
|
178
|
+
return this.show(
|
|
137
179
|
typeof params === 'string'
|
|
138
180
|
? { status: 'loading', content: params }
|
|
139
181
|
: { ...params, status: 'loading' },
|
|
@@ -1,75 +1,76 @@
|
|
|
1
|
-
---
|
|
2
|
-
category: Components
|
|
3
|
-
title: notice
|
|
4
|
-
subtitle: notice
|
|
5
|
-
group:
|
|
6
|
-
title: Notification
|
|
7
|
-
order: 1
|
|
8
|
-
toc: 'content'
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# notice
|
|
12
|
-
|
|
13
|
-
Display notification messages globally, supporting multiple positions simultaneously.
|
|
14
|
-
|
|
15
|
-
## When To Use
|
|
16
|
-
|
|
17
|
-
- Display notification messages in the four corners or at the top/bottom of the system
|
|
18
|
-
- Commonly used for:
|
|
19
|
-
- More complex notification content
|
|
20
|
-
- Interactive notifications that provide users with next steps
|
|
21
|
-
- System-initiated push notifications
|
|
22
|
-
|
|
23
|
-
## Examples
|
|
24
|
-
|
|
25
|
-
<code src="./demo/basic.tsx" title="Basic" desc="The most basic usage, supports multiple positions"></code>
|
|
26
|
-
|
|
27
|
-
## API
|
|
28
|
-
|
|
29
|
-
### notice
|
|
30
|
-
|
|
31
|
-
| Property | Description | Type | Default |
|
|
32
|
-
| --- | --- | --- | --- |
|
|
33
|
-
| title | Notice title | ReactNode | - |
|
|
34
|
-
| content | Notice content | ReactNode | - |
|
|
35
|
-
| duration | Time in
|
|
36
|
-
| icon | Custom icon | ReactNode | - |
|
|
37
|
-
| key | The unique identifier of the current notice | string \| number | - |
|
|
38
|
-
| placement | Display position | `'topLeft' \| 'topRight' \| 'bottomLeft' \| 'bottomRight' \| 'top' \| 'bottom'` | `'topRight'` |
|
|
39
|
-
| showProgress | Whether to show progress bar | boolean | - |
|
|
40
|
-
| pauseOnHover | Whether to pause auto-close on mouse hover | boolean | - |
|
|
41
|
-
| closable | Whether to show close button | boolean | `true` |
|
|
42
|
-
| onClose | Callback function when notice is closed | function | - |
|
|
43
|
-
| onClick | Callback function when notice is clicked | function | - |
|
|
44
|
-
| data-* | `string` | - | Supports all data-* attributes, forwarded to root DOM element |
|
|
45
|
-
|
|
46
|
-
### notice Methods
|
|
47
|
-
|
|
48
|
-
| Method | Description | Type | Default |
|
|
49
|
-
| --- | --- | --- | --- |
|
|
50
|
-
| notice.open(config) | Open a normal notice | string \| [NoticeConfigs](#noticeconfigs) | - |
|
|
51
|
-
| notice.info(config) | Open an info notice | string \| [NoticeConfigs](#noticeconfigs) | - |
|
|
52
|
-
| notice.success(config) | Open a success notice | string \| [NoticeConfigs](#noticeconfigs) | - |
|
|
53
|
-
| notice.warning(config) | Open a warning notice | string \| [NoticeConfigs](#noticeconfigs) | - |
|
|
54
|
-
| notice.error(config) | Open an error notice | string \| [NoticeConfigs](#noticeconfigs) | - |
|
|
55
|
-
| notice.destroy(key) | Manually destroy the notice with the specified key | string \| number | - |
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
|
61
|
-
|
|
|
62
|
-
|
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
|
|
|
66
|
-
|
|
|
67
|
-
|
|
|
68
|
-
|
|
|
69
|
-
|
|
|
70
|
-
|
|
|
71
|
-
|
|
|
72
|
-
|
|
|
73
|
-
|
|
|
74
|
-
|
|
|
75
|
-
|
|
|
1
|
+
---
|
|
2
|
+
category: Components
|
|
3
|
+
title: notice
|
|
4
|
+
subtitle: notice
|
|
5
|
+
group:
|
|
6
|
+
title: Notification
|
|
7
|
+
order: 1
|
|
8
|
+
toc: 'content'
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# notice
|
|
12
|
+
|
|
13
|
+
Display notification messages globally, supporting multiple positions simultaneously.
|
|
14
|
+
|
|
15
|
+
## When To Use
|
|
16
|
+
|
|
17
|
+
- Display notification messages in the four corners or at the top/bottom of the system
|
|
18
|
+
- Commonly used for:
|
|
19
|
+
- More complex notification content
|
|
20
|
+
- Interactive notifications that provide users with next steps
|
|
21
|
+
- System-initiated push notifications
|
|
22
|
+
|
|
23
|
+
## Examples
|
|
24
|
+
|
|
25
|
+
<code src="./demo/basic.tsx" title="Basic" desc="The most basic usage, supports multiple positions"></code>
|
|
26
|
+
|
|
27
|
+
## API
|
|
28
|
+
|
|
29
|
+
### notice
|
|
30
|
+
|
|
31
|
+
| Property | Description | Type | Default |
|
|
32
|
+
| --- | --- | --- | --- |
|
|
33
|
+
| title | Notice title | ReactNode | - |
|
|
34
|
+
| content | Notice content | ReactNode | - |
|
|
35
|
+
| duration | Time in milliseconds before the notice disappears. If set to 0, it will not automatically close | number | `4500` |
|
|
36
|
+
| icon | Custom icon | ReactNode | - |
|
|
37
|
+
| key | The unique identifier of the current notice | string \| number | - |
|
|
38
|
+
| placement | Display position | `'topLeft' \| 'topRight' \| 'bottomLeft' \| 'bottomRight' \| 'top' \| 'bottom'` | `'topRight'` |
|
|
39
|
+
| showProgress | Whether to show progress bar | boolean | - |
|
|
40
|
+
| pauseOnHover | Whether to pause auto-close on mouse hover | boolean | - |
|
|
41
|
+
| closable | Whether to show close button | boolean | `true` |
|
|
42
|
+
| onClose | Callback function when notice is closed | function | - |
|
|
43
|
+
| onClick | Callback function when notice is clicked | function | - |
|
|
44
|
+
| data-* | `string` | - | Supports all data-* attributes, forwarded to root DOM element |
|
|
45
|
+
|
|
46
|
+
### notice Methods
|
|
47
|
+
|
|
48
|
+
| Method | Description | Type | Default |
|
|
49
|
+
| --- | --- | --- | --- |
|
|
50
|
+
| notice.open(config) | Open a normal notice | string \| [NoticeConfigs](#noticeconfigs) | - |
|
|
51
|
+
| notice.info(config) | Open an info notice | string \| [NoticeConfigs](#noticeconfigs) | - |
|
|
52
|
+
| notice.success(config) | Open a success notice | string \| [NoticeConfigs](#noticeconfigs) | - |
|
|
53
|
+
| notice.warning(config) | Open a warning notice | string \| [NoticeConfigs](#noticeconfigs) | - |
|
|
54
|
+
| notice.error(config) | Open an error notice | string \| [NoticeConfigs](#noticeconfigs) | - |
|
|
55
|
+
| notice.destroy(key) | Manually destroy the notice with the specified key | string \| number | - |
|
|
56
|
+
| notice.clear(placement?) | Clear notices at one position or all positions | placement | - |
|
|
57
|
+
|
|
58
|
+
### NoticeConfigs
|
|
59
|
+
|
|
60
|
+
| Property | Description | Type | Default |
|
|
61
|
+
| --- | --- | --- | --- |
|
|
62
|
+
| prefixCls | Custom class name prefix | string | - |
|
|
63
|
+
| className | Custom class name | string | - |
|
|
64
|
+
| style | Custom inline style | CSSProperties | - |
|
|
65
|
+
| title | Notice title | ReactNode | - |
|
|
66
|
+
| content | Notice content | ReactNode | - |
|
|
67
|
+
| duration | Time in milliseconds before the notice disappears. If set to 0, it will not automatically close | number | `4500` |
|
|
68
|
+
| icon | Custom icon | ReactNode | - |
|
|
69
|
+
| key | The unique identifier of the current notice | string \| number | - |
|
|
70
|
+
| placement | Display position | `'topLeft' \| 'topRight' \| 'bottomLeft' \| 'bottomRight' \| 'top' \| 'bottom'` | `'topRight'` |
|
|
71
|
+
| showProgress | Whether to show progress bar | boolean | - |
|
|
72
|
+
| pauseOnHover | Whether to pause auto-close on mouse hover | boolean | - |
|
|
73
|
+
| closable | Whether to show close button | boolean | `true` |
|
|
74
|
+
| onClose | Callback function when notice is closed | function | - |
|
|
75
|
+
| onClick | Callback function when notice is clicked | function | - |
|
|
76
|
+
| data-* | `string` | - | Supports all data-* attributes, forwarded to root DOM element |
|
package/src/notice/index.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { notice } from './wrapper';
|
|
2
|
-
export type {
|
|
2
|
+
export type {
|
|
3
|
+
NoticeApi,
|
|
4
|
+
NoticeClose,
|
|
5
|
+
NoticeConfig,
|
|
6
|
+
PlacementType,
|
|
7
|
+
} from './interface';
|
|
3
8
|
export * from './notice-provider';
|
|
4
9
|
export { default as useNotice } from './use-notice';
|
|
5
10
|
export default notice;
|