UNPKG

5.87 kBJavaScriptView Raw
1"use client";
2
3import React, { useContext } from 'react';
4import { render } from "rc-util/es/React/render";
5import { AppConfigContext } from '../app/context';
6import ConfigProvider, { ConfigContext, globalConfig, warnContext } from '../config-provider';
7import PurePanel from './PurePanel';
8import useNotification, { useInternalNotification } from './useNotification';
9let notification = null;
10let act = callback => callback();
11let taskQueue = [];
12let defaultGlobalConfig = {};
13function 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}
30const GlobalHolder = /*#__PURE__*/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});
59const GlobalHolderWrapper = /*#__PURE__*/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 = /*#__PURE__*/React.createElement(GlobalHolder, {
70 ref: ref,
71 sync: sync,
72 notificationConfig: notificationConfig
73 });
74 return /*#__PURE__*/React.createElement(ConfigProvider, {
75 prefixCls: rootPrefixCls,
76 iconPrefixCls: rootIconPrefixCls,
77 theme: theme
78 }, global.holderRender ? global.holderRender(dom) : dom);
79});
80function flushNotice() {
81 if (!notification) {
82 const holderFragment = document.createDocumentFragment();
83 const newNotification = {
84 fragment: holderFragment
85 };
86 notification = newNotification;
87 // Delay render to avoid sync issue
88 act(() => {
89 render( /*#__PURE__*/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 // Notification not ready
108 if (!notification.instance) {
109 return;
110 }
111 // >>> Execute task
112 taskQueue.forEach(task => {
113 // eslint-disable-next-line default-case
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 // Clean up
130 taskQueue = [];
131}
132// ==============================================================================
133// == Export ==
134// ==============================================================================
135function setNotificationGlobalConfig(config) {
136 defaultGlobalConfig = Object.assign(Object.assign({}, defaultGlobalConfig), config);
137 // Trigger sync for it
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}
143function 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}
154function destroy(key) {
155 taskQueue.push({
156 type: 'destroy',
157 key
158 });
159 flushNotice();
160}
161const methods = ['success', 'info', 'warning', 'error'];
162const baseStaticMethods = {
163 open,
164 destroy,
165 config: setNotificationGlobalConfig,
166 useNotification,
167 _InternalPanelDoNotUseOrYouWillBeFired: PurePanel
168};
169const staticMethods = baseStaticMethods;
170methods.forEach(type => {
171 staticMethods[type] = config => open(Object.assign(Object.assign({}, config), {
172 type
173 }));
174});
175// ==============================================================================
176// == Test ==
177// ==============================================================================
178const noop = () => {};
179/** @internal Only Work in test env */
180// eslint-disable-next-line import/no-mutable-exports
181export let actWrapper = noop;
182if (process.env.NODE_ENV === 'test') {
183 actWrapper = wrapper => {
184 act = wrapper;
185 };
186}
187/** @internal Only Work in test env */
188// eslint-disable-next-line import/no-mutable-exports
189export let actDestroy = noop;
190if (process.env.NODE_ENV === 'test') {
191 actDestroy = () => {
192 notification = null;
193 };
194}
195export default staticMethods;
\No newline at end of file