@rainbow-oh/yee-c 0.8.1 → 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/Cascader/cascader.js +38 -30
- package/dist/cjs/Cascader/column.js +17 -9
- package/dist/cjs/Cascader/search-list.js +30 -22
- package/dist/cjs/Cascader/utils/index.js +1 -5
- package/dist/cjs/Checkbox/checkbox-group.js +23 -14
- package/dist/cjs/Dialog/dialog.js +1 -1
- package/dist/cjs/Dialog/interface.d.ts +1 -1
- package/dist/cjs/Dialog/style/index.less +2 -1
- package/dist/cjs/Drawer/drawer.js +9 -1
- package/dist/cjs/Form/Group.js +1 -1
- package/dist/cjs/Form/demo/tooltip.js +1 -3
- package/dist/cjs/Input/style/index.less +1 -0
- package/dist/cjs/List/hooks/useListKeyboard.js +3 -1
- package/dist/cjs/Menu/menu.js +18 -2
- package/dist/cjs/Pagination/items.js +54 -26
- package/dist/cjs/Pagination/pagination.js +25 -9
- package/dist/cjs/PickerPanel/panels/DateTimePanel/index.d.ts +1 -1
- package/dist/cjs/PickerPanel/panels/MonthPanel/MonthHeader.js +7 -1
- package/dist/cjs/Rate/star.js +27 -3
- package/dist/cjs/Segmented/demo/variant.js +15 -1
- package/dist/cjs/Segmented/index.d.ts +1 -1
- package/dist/cjs/Segmented/segmented.js +12 -15
- package/dist/cjs/Select/option.js +8 -1
- package/dist/cjs/Select/options.js +9 -1
- package/dist/cjs/Select/select.js +3 -1
- package/dist/cjs/Selector/style/index.less +1 -0
- package/dist/cjs/Steps/step.js +14 -2
- package/dist/cjs/Steps/steps.js +11 -1
- package/dist/cjs/Table/demo/components-override.js +31 -2
- package/dist/cjs/Table/demo/grouping.js +7 -1
- package/dist/cjs/Table/hooks/useColumns.d.ts +3 -3
- package/dist/cjs/Table/hooks/useColumns.js +11 -14
- package/dist/cjs/Table/icon/arrow-icon.js +1 -1
- package/dist/cjs/Table/index.d.ts +1 -1
- package/dist/cjs/Table/style/index.less +2 -4
- package/dist/cjs/Table/tbody/row.js +1 -4
- package/dist/cjs/Table/theader/cell.js +6 -3
- package/dist/cjs/Table/theader/index.js +12 -4
- package/dist/cjs/TextArea/style/index.less +1 -0
- package/dist/cjs/Tour/index.d.ts +1 -1
- package/dist/cjs/Tree/style/index.less +1 -5
- package/dist/cjs/Tree/tree.js +38 -35
- 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/hooks/useEvent.js +1 -4
- 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 +5 -3
- package/dist/cjs/style/themes.css +1 -1
- package/dist/cjs/style/variables.css +6 -4
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/Dialog/dialog.js +2 -2
- package/dist/esm/Dialog/interface.d.ts +1 -1
- package/dist/esm/Dialog/style/index.less +2 -1
- package/dist/esm/Form/Group.js +1 -1
- package/dist/esm/Input/style/index.less +1 -0
- package/dist/esm/PickerPanel/panels/DateTimePanel/index.d.ts +1 -1
- package/dist/esm/Segmented/index.d.ts +1 -1
- package/dist/esm/Segmented/segmented.js +1 -1
- package/dist/esm/Selector/style/index.less +1 -0
- package/dist/esm/Table/demo/components-override.js +1 -0
- package/dist/esm/Table/hooks/useColumns.d.ts +3 -3
- package/dist/esm/Table/hooks/useColumns.js +13 -16
- package/dist/esm/Table/icon/arrow-icon.js +1 -1
- package/dist/esm/Table/index.d.ts +1 -1
- package/dist/esm/Table/style/index.less +2 -4
- package/dist/esm/Table/theader/cell.js +7 -3
- package/dist/esm/TextArea/style/index.less +1 -0
- package/dist/esm/Tour/index.d.ts +1 -1
- package/dist/esm/Tree/style/index.less +1 -5
- package/dist/esm/Tree/tree.js +1 -1
- 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 +5 -3
- package/dist/esm/style/themes.css +1 -1
- package/dist/esm/style/variables.css +6 -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/Anchor/anchor.tsx +2 -2
- package/src/Carousel/carousel.tsx +1 -2
- package/src/Cascader/cascader.tsx +5 -1
- package/src/Cascader/column.tsx +5 -1
- package/src/Cascader/search-list.tsx +10 -3
- package/src/Cascader/utils/index.ts +3 -6
- package/src/Checkbox/checkbox-group.tsx +6 -1
- package/src/Dialog/dialog.tsx +7 -3
- package/src/Dialog/interface.ts +1 -1
- package/src/Dialog/style/index.less +2 -1
- package/src/Drawer/drawer.tsx +7 -1
- package/src/Form/Group.tsx +2 -4
- package/src/Form/demo/tooltip.tsx +2 -11
- package/src/Form/utils/validate.ts +1 -4
- package/src/Input/style/index.less +1 -0
- package/src/List/hooks/useListKeyboard.ts +3 -3
- package/src/List/list.tsx +2 -1
- package/src/Menu/menu.tsx +14 -3
- package/src/Pagination/items.tsx +16 -4
- package/src/Pagination/pagination.tsx +18 -4
- package/src/PickerPanel/panels/DatePanel/DateBody.tsx +1 -1
- package/src/PickerPanel/panels/DateTimePanel/index.tsx +1 -1
- package/src/PickerPanel/panels/MonthPanel/MonthHeader.tsx +7 -2
- package/src/PickerPanel/panels/PanelBody.tsx +1 -1
- package/src/PickerPanel/panels/QuarterPanel/QuarterHeader.tsx +1 -1
- package/src/PickerPanel/panels/RangePanel/index.tsx +1 -1
- package/src/PickerPanel/panels/TimePanel/TimeBody.tsx +1 -1
- package/src/PickerPanel/panels/YearPanel/YearHeader.tsx +1 -1
- package/src/PickerPanel/utils/pickerUtils.ts +2 -1
- package/src/RangePicker/range-picker-mobile.tsx +1 -3
- package/src/Rate/star.tsx +16 -4
- package/src/Segmented/demo/variant.tsx +10 -2
- package/src/Segmented/index.ts +2 -2
- package/src/Segmented/segmented.tsx +4 -11
- package/src/Select/interface.ts +0 -1
- package/src/Select/option.tsx +8 -2
- package/src/Select/options.tsx +11 -4
- package/src/Select/select.tsx +4 -4
- package/src/Selector/style/index.less +1 -0
- package/src/Steps/step.tsx +11 -3
- package/src/Steps/steps.tsx +8 -1
- package/src/Table/demo/components-override.tsx +34 -7
- package/src/Table/demo/grouping.tsx +8 -4
- package/src/Table/hooks/useColumns.ts +14 -18
- package/src/Table/icon/arrow-icon.tsx +1 -1
- package/src/Table/index.ts +3 -3
- package/src/Table/style/index.less +2 -4
- package/src/Table/table.tsx +2 -4
- package/src/Table/tbody/row.tsx +1 -3
- package/src/Table/theader/cell.tsx +6 -3
- package/src/Table/theader/index.tsx +9 -10
- package/src/TextArea/style/index.less +1 -0
- package/src/Tour/demo/placement.tsx +2 -1
- package/src/Tour/index.ts +1 -1
- package/src/Tree/style/index.less +1 -5
- package/src/Tree/tree.tsx +16 -11
- package/src/Tree/utils/tree-tools.ts +4 -1
- package/src/VerificationCode/style/index.less +1 -0
- package/src/hooks/useCountdown.ts +52 -21
- package/src/hooks/useEvent.ts +1 -3
- package/src/locale/context.tsx +5 -1
- package/src/locale/interface.ts +6 -1
- 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 +5 -3
- package/src/utils/debounce.ts +1 -3
- package/src/version.ts +1 -1
|
@@ -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;
|
|
@@ -32,7 +32,7 @@ toc: 'content'
|
|
|
32
32
|
| --- | --- | --- | --- |
|
|
33
33
|
| title | 通知标题 | ReactNode | - |
|
|
34
34
|
| content | 通知内容 | ReactNode | - |
|
|
35
|
-
| duration | 自动关闭时间(
|
|
35
|
+
| duration | 自动关闭时间(毫秒),设为 0 时不自动关闭 | number | `4500` |
|
|
36
36
|
| icon | 自定义图标 | ReactNode | - |
|
|
37
37
|
| key | 当前通知的唯一标识 | string \| number | - |
|
|
38
38
|
| placement | 显示位置 | `'topLeft' \| 'topRight' \| 'bottomLeft' \| 'bottomRight' \| 'top' \| 'bottom'` | `'topRight'` |
|
|
@@ -53,6 +53,7 @@ toc: 'content'
|
|
|
53
53
|
| notice.warning(config) | 打开警告通知 | string \| [NoticeConfigs](#noticeconfigs) | - |
|
|
54
54
|
| notice.error(config) | 打开错误通知 | string \| [NoticeConfigs](#noticeconfigs) | - |
|
|
55
55
|
| notice.destroy(key) | 手动销毁指定 key 的通知 | string \| number | - |
|
|
56
|
+
| notice.clear(placement?) | 清除指定位置或全部通知 | placement | - |
|
|
56
57
|
|
|
57
58
|
### NoticeConfigs
|
|
58
59
|
|
|
@@ -63,7 +64,7 @@ toc: 'content'
|
|
|
63
64
|
| style | 自定义根样式 | CSSProperties | - |
|
|
64
65
|
| title | 通知标题 | ReactNode | - |
|
|
65
66
|
| content | 通知内容 | ReactNode | - |
|
|
66
|
-
| duration | 自动关闭时间(
|
|
67
|
+
| duration | 自动关闭时间(毫秒),设为 0 时不自动关闭 | number | `4500` |
|
|
67
68
|
| icon | 自定义图标 | ReactNode | - |
|
|
68
69
|
| key | 当前通知的唯一标识 | string \| number | - |
|
|
69
70
|
| placement | 显示位置 | `'topLeft' \| 'topRight' \| 'bottomLeft' \| 'bottomRight' \| 'top' \| 'bottom'` | `'topRight'` |
|
package/src/notice/interface.ts
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
|
+
export type PlacementType =
|
|
2
|
+
| 'topLeft'
|
|
3
|
+
| 'topRight'
|
|
4
|
+
| 'bottomLeft'
|
|
5
|
+
| 'bottomRight'
|
|
6
|
+
| 'top'
|
|
7
|
+
| 'bottom';
|
|
8
|
+
|
|
1
9
|
export type NoticeConfig = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
10
|
+
[dataAttribute: `data-${string}`]:
|
|
11
|
+
| string
|
|
12
|
+
| number
|
|
13
|
+
| boolean
|
|
14
|
+
| undefined;
|
|
6
15
|
/**
|
|
7
16
|
* Custom prefix class name
|
|
8
17
|
*/
|
|
@@ -24,7 +33,7 @@ export type NoticeConfig = {
|
|
|
24
33
|
*/
|
|
25
34
|
content: React.ReactNode;
|
|
26
35
|
/**
|
|
27
|
-
* Auto close time (
|
|
36
|
+
* Auto close time (milliseconds), 0 means no auto close
|
|
28
37
|
* @default 4500
|
|
29
38
|
*/
|
|
30
39
|
duration?: number;
|
|
@@ -40,13 +49,7 @@ export type NoticeConfig = {
|
|
|
40
49
|
* Display position
|
|
41
50
|
* @default 'topRight'
|
|
42
51
|
*/
|
|
43
|
-
placement?:
|
|
44
|
-
| 'topLeft'
|
|
45
|
-
| 'topRight'
|
|
46
|
-
| 'bottomLeft'
|
|
47
|
-
| 'bottomRight'
|
|
48
|
-
| 'top'
|
|
49
|
-
| 'bottom';
|
|
52
|
+
placement?: PlacementType;
|
|
50
53
|
/**
|
|
51
54
|
* Whether to show progress bar
|
|
52
55
|
*/
|
|
@@ -70,19 +73,33 @@ export type NoticeConfig = {
|
|
|
70
73
|
closable?: boolean;
|
|
71
74
|
};
|
|
72
75
|
|
|
76
|
+
export type NoticeClose = () => void;
|
|
77
|
+
|
|
78
|
+
export interface NoticeApi {
|
|
79
|
+
open: (config: string | NoticeConfig) => NoticeClose;
|
|
80
|
+
info: (config: string | NoticeConfig) => NoticeClose;
|
|
81
|
+
success: (config: string | NoticeConfig) => NoticeClose;
|
|
82
|
+
warning: (config: string | NoticeConfig) => NoticeClose;
|
|
83
|
+
error: (config: string | NoticeConfig) => NoticeClose;
|
|
84
|
+
destroy: (key: string | number) => void;
|
|
85
|
+
clear: (placement?: PlacementType) => void;
|
|
86
|
+
}
|
|
87
|
+
|
|
73
88
|
// With status
|
|
74
89
|
export type WrapperedNoticeConfig = NoticeConfig & {
|
|
75
90
|
status?: 'info' | 'success' | 'warning' | 'error';
|
|
76
91
|
};
|
|
77
92
|
|
|
78
|
-
//
|
|
93
|
+
// Internal notice state
|
|
79
94
|
export type NoticeType = WrapperedNoticeConfig & {
|
|
80
95
|
key: string | number;
|
|
96
|
+
placement: PlacementType;
|
|
97
|
+
timerGeneration: number;
|
|
81
98
|
};
|
|
82
99
|
|
|
83
100
|
export interface NoticeProps extends NoticeType {
|
|
84
101
|
/**
|
|
85
102
|
* Destroy component callback
|
|
86
103
|
*/
|
|
87
|
-
onDestroy?: (key: string | number) => void;
|
|
104
|
+
onDestroy?: (key: string | number, timerGeneration?: number) => void;
|
|
88
105
|
}
|