1 | "use client";
|
2 |
|
3 | import React, { useContext } from 'react';
|
4 | import { render } from "rc-util/es/React/render";
|
5 | import { AppConfigContext } from '../app/context';
|
6 | import ConfigProvider, { ConfigContext, globalConfig, warnContext } from '../config-provider';
|
7 | import PurePanel from './PurePanel';
|
8 | import useNotification, { useInternalNotification } from './useNotification';
|
9 | let notification = null;
|
10 | let act = callback => callback();
|
11 | let taskQueue = [];
|
12 | let defaultGlobalConfig = {};
|
13 | function getGlobalContext() {
|
14 | const {
|
15 | getContainer,
|
16 | rtl,
|
17 | maxCount,
|
18 | top,
|
19 | bottom
|
20 | } = defaultGlobalConfig;
|
21 | const mergedContainer = (getContainer === null || getContainer === void 0 ? void 0 : getContainer()) || document.body;
|
22 | return {
|
23 | getContainer: () => mergedContainer,
|
24 | rtl,
|
25 | maxCount,
|
26 | top,
|
27 | bottom
|
28 | };
|
29 | }
|
30 | const GlobalHolder = React.forwardRef((props, ref) => {
|
31 | const {
|
32 | notificationConfig,
|
33 | sync
|
34 | } = props;
|
35 | const {
|
36 | getPrefixCls
|
37 | } = useContext(ConfigContext);
|
38 | const prefixCls = defaultGlobalConfig.prefixCls || getPrefixCls('notification');
|
39 | const appConfig = useContext(AppConfigContext);
|
40 | const [api, holder] = useInternalNotification(Object.assign(Object.assign(Object.assign({}, notificationConfig), {
|
41 | prefixCls
|
42 | }), appConfig.notification));
|
43 | React.useEffect(sync, []);
|
44 | React.useImperativeHandle(ref, () => {
|
45 | const instance = Object.assign({}, api);
|
46 | Object.keys(instance).forEach(method => {
|
47 | instance[method] = function () {
|
48 | sync();
|
49 | return api[method].apply(api, arguments);
|
50 | };
|
51 | });
|
52 | return {
|
53 | instance,
|
54 | sync
|
55 | };
|
56 | });
|
57 | return holder;
|
58 | });
|
59 | const GlobalHolderWrapper = React.forwardRef((_, ref) => {
|
60 | const [notificationConfig, setNotificationConfig] = React.useState(getGlobalContext);
|
61 | const sync = () => {
|
62 | setNotificationConfig(getGlobalContext);
|
63 | };
|
64 | React.useEffect(sync, []);
|
65 | const global = globalConfig();
|
66 | const rootPrefixCls = global.getRootPrefixCls();
|
67 | const rootIconPrefixCls = global.getIconPrefixCls();
|
68 | const theme = global.getTheme();
|
69 | const dom = React.createElement(GlobalHolder, {
|
70 | ref: ref,
|
71 | sync: sync,
|
72 | notificationConfig: notificationConfig
|
73 | });
|
74 | return React.createElement(ConfigProvider, {
|
75 | prefixCls: rootPrefixCls,
|
76 | iconPrefixCls: rootIconPrefixCls,
|
77 | theme: theme
|
78 | }, global.holderRender ? global.holderRender(dom) : dom);
|
79 | });
|
80 | function flushNotice() {
|
81 | if (!notification) {
|
82 | const holderFragment = document.createDocumentFragment();
|
83 | const newNotification = {
|
84 | fragment: holderFragment
|
85 | };
|
86 | notification = newNotification;
|
87 |
|
88 | act(() => {
|
89 | render( React.createElement(GlobalHolderWrapper, {
|
90 | ref: node => {
|
91 | const {
|
92 | instance,
|
93 | sync
|
94 | } = node || {};
|
95 | Promise.resolve().then(() => {
|
96 | if (!newNotification.instance && instance) {
|
97 | newNotification.instance = instance;
|
98 | newNotification.sync = sync;
|
99 | flushNotice();
|
100 | }
|
101 | });
|
102 | }
|
103 | }), holderFragment);
|
104 | });
|
105 | return;
|
106 | }
|
107 |
|
108 | if (!notification.instance) {
|
109 | return;
|
110 | }
|
111 |
|
112 | taskQueue.forEach(task => {
|
113 |
|
114 | switch (task.type) {
|
115 | case 'open':
|
116 | {
|
117 | act(() => {
|
118 | notification.instance.open(Object.assign(Object.assign({}, defaultGlobalConfig), task.config));
|
119 | });
|
120 | break;
|
121 | }
|
122 | case 'destroy':
|
123 | act(() => {
|
124 | notification === null || notification === void 0 ? void 0 : notification.instance.destroy(task.key);
|
125 | });
|
126 | break;
|
127 | }
|
128 | });
|
129 |
|
130 | taskQueue = [];
|
131 | }
|
132 |
|
133 |
|
134 |
|
135 | function setNotificationGlobalConfig(config) {
|
136 | defaultGlobalConfig = Object.assign(Object.assign({}, defaultGlobalConfig), config);
|
137 |
|
138 | act(() => {
|
139 | var _a;
|
140 | (_a = notification === null || notification === void 0 ? void 0 : notification.sync) === null || _a === void 0 ? void 0 : _a.call(notification);
|
141 | });
|
142 | }
|
143 | function open(config) {
|
144 | const global = globalConfig();
|
145 | if (process.env.NODE_ENV !== 'production' && !global.holderRender) {
|
146 | warnContext('notification');
|
147 | }
|
148 | taskQueue.push({
|
149 | type: 'open',
|
150 | config
|
151 | });
|
152 | flushNotice();
|
153 | }
|
154 | function destroy(key) {
|
155 | taskQueue.push({
|
156 | type: 'destroy',
|
157 | key
|
158 | });
|
159 | flushNotice();
|
160 | }
|
161 | const methods = ['success', 'info', 'warning', 'error'];
|
162 | const baseStaticMethods = {
|
163 | open,
|
164 | destroy,
|
165 | config: setNotificationGlobalConfig,
|
166 | useNotification,
|
167 | _InternalPanelDoNotUseOrYouWillBeFired: PurePanel
|
168 | };
|
169 | const staticMethods = baseStaticMethods;
|
170 | methods.forEach(type => {
|
171 | staticMethods[type] = config => open(Object.assign(Object.assign({}, config), {
|
172 | type
|
173 | }));
|
174 | });
|
175 |
|
176 |
|
177 |
|
178 | const noop = () => {};
|
179 |
|
180 |
|
181 | export let actWrapper = noop;
|
182 | if (process.env.NODE_ENV === 'test') {
|
183 | actWrapper = wrapper => {
|
184 | act = wrapper;
|
185 | };
|
186 | }
|
187 |
|
188 |
|
189 | export let actDestroy = noop;
|
190 | if (process.env.NODE_ENV === 'test') {
|
191 | actDestroy = () => {
|
192 | notification = null;
|
193 | };
|
194 | }
|
195 | export default staticMethods; |
\ | No newline at end of file |