@kne/react-modal 0.1.10 → 0.1.11
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/README.md +1 -1
- package/dist/index.css +20 -1
- package/dist/index.css.map +1 -1
- package/dist/index.js +84 -121
- package/dist/index.js.map +1 -1
- package/dist/index.modern.js +83 -120
- package/dist/index.modern.js.map +1 -1
- package/package.json +2 -2
package/dist/index.modern.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useEffect, useRef, useState, useCallback, memo, forwardRef, useImperativeHandle, createRef, Children } from 'react';
|
|
2
2
|
import { Modal as Modal$1, App, Button, Drawer as Drawer$1, Tabs } from 'antd';
|
|
3
3
|
import { CloseOutlined, InfoCircleFilled, ExclamationCircleFilled, CloseCircleFilled, CheckCircleFilled } from '@ant-design/icons';
|
|
4
4
|
import classnames from 'classnames';
|
|
5
|
-
import {
|
|
5
|
+
import { usePopupMount, useScrollElement, hoistOutOfModalRoot } from '@kne/responsive-utils';
|
|
6
6
|
import { createWithIntlProvider, useIntl } from '@kne/react-intl';
|
|
7
7
|
import ButtonGroup from '@kne/button-group';
|
|
8
8
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
@@ -125,6 +125,54 @@ const Footer = ({
|
|
|
125
125
|
});
|
|
126
126
|
};
|
|
127
127
|
|
|
128
|
+
let parentScrollLockCount = 0;
|
|
129
|
+
let parentScrollLocked = [];
|
|
130
|
+
|
|
131
|
+
/** Modal / Drawer 共用:锁 body + layout scroll,避免背后页面滚动 */
|
|
132
|
+
const lockParentScroll = getScrollElement => {
|
|
133
|
+
parentScrollLockCount += 1;
|
|
134
|
+
if (parentScrollLockCount === 1) {
|
|
135
|
+
const targets = [document.body];
|
|
136
|
+
const scrollEl = typeof getScrollElement === 'function' ? getScrollElement() : null;
|
|
137
|
+
if (scrollEl && scrollEl !== document.body && !targets.includes(scrollEl)) {
|
|
138
|
+
targets.push(scrollEl);
|
|
139
|
+
}
|
|
140
|
+
parentScrollLocked = targets.map(el => {
|
|
141
|
+
const prev = {
|
|
142
|
+
overflow: el.style.overflow,
|
|
143
|
+
overscrollBehavior: el.style.overscrollBehavior
|
|
144
|
+
};
|
|
145
|
+
el.style.overflow = 'hidden';
|
|
146
|
+
el.style.overscrollBehavior = 'none';
|
|
147
|
+
return {
|
|
148
|
+
el,
|
|
149
|
+
prev
|
|
150
|
+
};
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
return () => {
|
|
154
|
+
parentScrollLockCount = Math.max(0, parentScrollLockCount - 1);
|
|
155
|
+
if (parentScrollLockCount === 0) {
|
|
156
|
+
parentScrollLocked.forEach(({
|
|
157
|
+
el,
|
|
158
|
+
prev
|
|
159
|
+
}) => {
|
|
160
|
+
el.style.overflow = prev.overflow;
|
|
161
|
+
el.style.overscrollBehavior = prev.overscrollBehavior;
|
|
162
|
+
});
|
|
163
|
+
parentScrollLocked = [];
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
};
|
|
167
|
+
const useLockParentScroll = (enabled, getScrollElement) => {
|
|
168
|
+
useEffect(() => {
|
|
169
|
+
if (!enabled) {
|
|
170
|
+
return undefined;
|
|
171
|
+
}
|
|
172
|
+
return lockParentScroll(getScrollElement);
|
|
173
|
+
}, [enabled, getScrollElement]);
|
|
174
|
+
};
|
|
175
|
+
|
|
128
176
|
const _excluded$6 = ["children", "footer", "footerButtons", "className", "size", "title", "onClose", "onConfirm", "confirmText", "onCancel", "cancelText", "closable", "noPadding", "bodyScroll", "isMobile", "mobileFullscreen", "fixedModeClass", "wrapClassName", "classNames", "styles", "style", "modalRender"],
|
|
129
177
|
_excluded2$3 = ["width"],
|
|
130
178
|
_excluded3$1 = ["size", "getContainer", "open", "mobileFullscreen", "bodyScroll"],
|
|
@@ -149,20 +197,10 @@ const wrapCustomGetContainer$2 = customGetContainer => {
|
|
|
149
197
|
return () => customGetContainer;
|
|
150
198
|
};
|
|
151
199
|
const VIEWPORT_EXAMPLE_SELECTORS$3 = ['.example-driver-device-scroll'];
|
|
152
|
-
const viewportPopupMountOptions$
|
|
200
|
+
const viewportPopupMountOptions$3 = {
|
|
153
201
|
cover: 'viewport',
|
|
154
202
|
exampleSelectors: VIEWPORT_EXAMPLE_SELECTORS$3
|
|
155
203
|
};
|
|
156
|
-
const findParentModalMountHost = node => {
|
|
157
|
-
if (!node || typeof node.closest !== 'function') {
|
|
158
|
-
return null;
|
|
159
|
-
}
|
|
160
|
-
const parentRoot = node.closest('.ant-modal-root');
|
|
161
|
-
if (!parentRoot) {
|
|
162
|
-
return null;
|
|
163
|
-
}
|
|
164
|
-
return parentRoot.parentElement || (typeof document !== 'undefined' ? document.body : null);
|
|
165
|
-
};
|
|
166
204
|
const resolveModalGetContainer = ({
|
|
167
205
|
customGetContainer,
|
|
168
206
|
getPopupContainer,
|
|
@@ -177,58 +215,13 @@ const resolveModalGetContainer = ({
|
|
|
177
215
|
}
|
|
178
216
|
}
|
|
179
217
|
const from = triggerNode || (typeof getHostNode === 'function' ? getHostNode() : null);
|
|
180
|
-
const nestedHost =
|
|
218
|
+
const nestedHost = hoistOutOfModalRoot(from);
|
|
181
219
|
if (nestedHost) {
|
|
182
220
|
return nestedHost;
|
|
183
221
|
}
|
|
184
222
|
return getPopupContainer(triggerNode);
|
|
185
223
|
};
|
|
186
224
|
};
|
|
187
|
-
let parentScrollLockCount$1 = 0;
|
|
188
|
-
let parentScrollLocked$1 = [];
|
|
189
|
-
const lockParentScroll$1 = getScrollElement => {
|
|
190
|
-
parentScrollLockCount$1 += 1;
|
|
191
|
-
if (parentScrollLockCount$1 === 1) {
|
|
192
|
-
const targets = [document.body];
|
|
193
|
-
const scrollEl = typeof getScrollElement === 'function' ? getScrollElement() : null;
|
|
194
|
-
if (scrollEl && scrollEl !== document.body && !targets.includes(scrollEl)) {
|
|
195
|
-
targets.push(scrollEl);
|
|
196
|
-
}
|
|
197
|
-
parentScrollLocked$1 = targets.map(el => {
|
|
198
|
-
const prev = {
|
|
199
|
-
overflow: el.style.overflow,
|
|
200
|
-
overscrollBehavior: el.style.overscrollBehavior
|
|
201
|
-
};
|
|
202
|
-
el.style.overflow = 'hidden';
|
|
203
|
-
el.style.overscrollBehavior = 'none';
|
|
204
|
-
return {
|
|
205
|
-
el,
|
|
206
|
-
prev
|
|
207
|
-
};
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
return () => {
|
|
211
|
-
parentScrollLockCount$1 = Math.max(0, parentScrollLockCount$1 - 1);
|
|
212
|
-
if (parentScrollLockCount$1 === 0) {
|
|
213
|
-
parentScrollLocked$1.forEach(({
|
|
214
|
-
el,
|
|
215
|
-
prev
|
|
216
|
-
}) => {
|
|
217
|
-
el.style.overflow = prev.overflow;
|
|
218
|
-
el.style.overscrollBehavior = prev.overscrollBehavior;
|
|
219
|
-
});
|
|
220
|
-
parentScrollLocked$1 = [];
|
|
221
|
-
}
|
|
222
|
-
};
|
|
223
|
-
};
|
|
224
|
-
const useLockParentScroll$1 = (enabled, getScrollElement) => {
|
|
225
|
-
useEffect(() => {
|
|
226
|
-
if (!enabled) {
|
|
227
|
-
return undefined;
|
|
228
|
-
}
|
|
229
|
-
return lockParentScroll$1(getScrollElement);
|
|
230
|
-
}, [enabled, getScrollElement]);
|
|
231
|
-
};
|
|
232
225
|
const sizeStyleVars$1 = (size, hasFooter) => {
|
|
233
226
|
const minBase = size === 'small' ? 300 : 500;
|
|
234
227
|
const chrome = 48 + (hasFooter ? 58 : 0);
|
|
@@ -274,6 +267,15 @@ const ModalOuter = ({
|
|
|
274
267
|
children: children
|
|
275
268
|
});
|
|
276
269
|
const bodyClassName = classnames(modalStyle['modal-body'], 'modal-body');
|
|
270
|
+
// 移动端全屏:body 用 flex 吃满 title/footer 之间剩余高度,footer 才能贴底;
|
|
271
|
+
// 勿写死 --kne-modal-body-height(高度受限类会把该值压矮,footer 悬在中间)
|
|
272
|
+
const bodyStyle = isMobile ? {
|
|
273
|
+
flex: '1 1 auto',
|
|
274
|
+
minHeight: 0,
|
|
275
|
+
height: 'auto'
|
|
276
|
+
} : {
|
|
277
|
+
height: 'var(--kne-modal-body-height)'
|
|
278
|
+
};
|
|
277
279
|
return /*#__PURE__*/jsxs("div", {
|
|
278
280
|
className: classnames(modalStyle['modal-outer'], 'modal-container', {
|
|
279
281
|
[modalStyle['is-mobile']]: isMobile,
|
|
@@ -296,12 +298,14 @@ const ModalOuter = ({
|
|
|
296
298
|
children: title
|
|
297
299
|
}) : null, bodyScroll !== false ? /*#__PURE__*/jsx(SimpleBar, {
|
|
298
300
|
className: bodyClassName,
|
|
299
|
-
style:
|
|
300
|
-
height: 'var(--kne-modal-body-height)'
|
|
301
|
-
},
|
|
301
|
+
style: bodyStyle,
|
|
302
302
|
children: bodyInner
|
|
303
303
|
}) : /*#__PURE__*/jsx("div", {
|
|
304
304
|
className: classnames(bodyClassName, modalStyle['body-scroll-off']),
|
|
305
|
+
style: isMobile ? {
|
|
306
|
+
flex: '1 1 auto',
|
|
307
|
+
minHeight: 0
|
|
308
|
+
} : undefined,
|
|
305
309
|
children: bodyInner
|
|
306
310
|
}), footer === null && footerButtons === undefined ? null : /*#__PURE__*/jsx(Footer, {
|
|
307
311
|
footer: footer,
|
|
@@ -444,11 +448,11 @@ const Modal = withLocale(_ref2 => {
|
|
|
444
448
|
fixedModeClass,
|
|
445
449
|
getPopupContainer,
|
|
446
450
|
anchorRef
|
|
447
|
-
} =
|
|
451
|
+
} = usePopupMount(_extends({}, viewportPopupMountOptions$3, {
|
|
448
452
|
getPopupContainer: wrapCustomGetContainer$2(getContainer)
|
|
449
453
|
}));
|
|
450
454
|
const getScrollElement = useScrollElement();
|
|
451
|
-
useLockParentScroll
|
|
455
|
+
useLockParentScroll(!!open, getScrollElement);
|
|
452
456
|
const setAnchorRef = node => {
|
|
453
457
|
hostRef.current = node;
|
|
454
458
|
anchorRef(node);
|
|
@@ -483,7 +487,7 @@ const useModal = () => {
|
|
|
483
487
|
const {
|
|
484
488
|
resolveMount,
|
|
485
489
|
getPopupContainer
|
|
486
|
-
} =
|
|
490
|
+
} = usePopupMount(viewportPopupMountOptions$3);
|
|
487
491
|
const getScrollElement = useScrollElement();
|
|
488
492
|
return props => {
|
|
489
493
|
const anchor = typeof document !== 'undefined' ? document.activeElement : null;
|
|
@@ -491,7 +495,7 @@ const useModal = () => {
|
|
|
491
495
|
isMobile,
|
|
492
496
|
fixedModeClass
|
|
493
497
|
} = resolveMount(anchor);
|
|
494
|
-
const unlock = lockParentScroll
|
|
498
|
+
const unlock = lockParentScroll(getScrollElement);
|
|
495
499
|
const api = {};
|
|
496
500
|
const {
|
|
497
501
|
afterClose: userAfterClose,
|
|
@@ -558,8 +562,10 @@ const DrawerLocaleRoot = withLocale(({
|
|
|
558
562
|
children
|
|
559
563
|
}) => children);
|
|
560
564
|
const VIEWPORT_EXAMPLE_SELECTORS$2 = ['.example-driver-device-scroll'];
|
|
561
|
-
|
|
562
|
-
|
|
565
|
+
|
|
566
|
+
// 与 Modal 一致:真机挂 body+fixed;示例框 / container 模式仍走 boundary(usePopupMount 内判定)
|
|
567
|
+
const viewportPopupMountOptions$2 = {
|
|
568
|
+
cover: 'viewport',
|
|
563
569
|
exampleSelectors: VIEWPORT_EXAMPLE_SELECTORS$2
|
|
564
570
|
};
|
|
565
571
|
const renderWithOptions = (value, options) => {
|
|
@@ -609,51 +615,6 @@ const resolveDrawerGetContainer = ({
|
|
|
609
615
|
return getPopupContainer(triggerNode);
|
|
610
616
|
};
|
|
611
617
|
};
|
|
612
|
-
let parentScrollLockCount = 0;
|
|
613
|
-
let parentScrollLocked = [];
|
|
614
|
-
const lockParentScroll = getScrollElement => {
|
|
615
|
-
parentScrollLockCount += 1;
|
|
616
|
-
if (parentScrollLockCount === 1) {
|
|
617
|
-
const targets = [document.body];
|
|
618
|
-
const scrollEl = typeof getScrollElement === 'function' ? getScrollElement() : null;
|
|
619
|
-
if (scrollEl && scrollEl !== document.body && !targets.includes(scrollEl)) {
|
|
620
|
-
targets.push(scrollEl);
|
|
621
|
-
}
|
|
622
|
-
parentScrollLocked = targets.map(el => {
|
|
623
|
-
const prev = {
|
|
624
|
-
overflow: el.style.overflow,
|
|
625
|
-
overscrollBehavior: el.style.overscrollBehavior
|
|
626
|
-
};
|
|
627
|
-
el.style.overflow = 'hidden';
|
|
628
|
-
el.style.overscrollBehavior = 'none';
|
|
629
|
-
return {
|
|
630
|
-
el,
|
|
631
|
-
prev
|
|
632
|
-
};
|
|
633
|
-
});
|
|
634
|
-
}
|
|
635
|
-
return () => {
|
|
636
|
-
parentScrollLockCount = Math.max(0, parentScrollLockCount - 1);
|
|
637
|
-
if (parentScrollLockCount === 0) {
|
|
638
|
-
parentScrollLocked.forEach(({
|
|
639
|
-
el,
|
|
640
|
-
prev
|
|
641
|
-
}) => {
|
|
642
|
-
el.style.overflow = prev.overflow;
|
|
643
|
-
el.style.overscrollBehavior = prev.overscrollBehavior;
|
|
644
|
-
});
|
|
645
|
-
parentScrollLocked = [];
|
|
646
|
-
}
|
|
647
|
-
};
|
|
648
|
-
};
|
|
649
|
-
const useLockParentScroll = (enabled, getScrollElement) => {
|
|
650
|
-
useEffect(() => {
|
|
651
|
-
if (!enabled) {
|
|
652
|
-
return undefined;
|
|
653
|
-
}
|
|
654
|
-
return lockParentScroll(getScrollElement);
|
|
655
|
-
}, [enabled, getScrollElement]);
|
|
656
|
-
};
|
|
657
618
|
const sizeStyleVars = (size, hasFooter) => {
|
|
658
619
|
const minBase = size === 'small' ? 300 : 500;
|
|
659
620
|
const chrome = 48 + (hasFooter ? 69 : 0);
|
|
@@ -890,7 +851,7 @@ const Drawer = withLocale(_ref2 => {
|
|
|
890
851
|
fixedModeClass,
|
|
891
852
|
getPopupContainer,
|
|
892
853
|
anchorRef
|
|
893
|
-
} =
|
|
854
|
+
} = usePopupMount(_extends({}, viewportPopupMountOptions$2, {
|
|
894
855
|
getPopupContainer: wrapCustomGetContainer$1(getContainer)
|
|
895
856
|
}));
|
|
896
857
|
const getScrollElement = useScrollElement();
|
|
@@ -937,8 +898,10 @@ const usePatchElement = () => {
|
|
|
937
898
|
const _excluded$4 = ["getContainer", "afterClose"],
|
|
938
899
|
_excluded2$1 = ["afterClose", "getContainer"];
|
|
939
900
|
const VIEWPORT_EXAMPLE_SELECTORS$1 = ['.example-driver-device-scroll'];
|
|
940
|
-
|
|
941
|
-
|
|
901
|
+
|
|
902
|
+
// 与 Modal / Drawer 一致:真机 viewport;示例框 / container 仍 boundary
|
|
903
|
+
const viewportPopupMountOptions$1 = {
|
|
904
|
+
cover: 'viewport',
|
|
942
905
|
exampleSelectors: VIEWPORT_EXAMPLE_SELECTORS$1
|
|
943
906
|
};
|
|
944
907
|
const wrapCustomGetContainer = customGetContainer => {
|
|
@@ -964,7 +927,7 @@ const HookDrawer = /*#__PURE__*/forwardRef(({
|
|
|
964
927
|
const {
|
|
965
928
|
getPopupContainer,
|
|
966
929
|
anchorRef
|
|
967
|
-
} =
|
|
930
|
+
} = usePopupMount(_extends({}, viewportPopupMountOptions$1, {
|
|
968
931
|
getPopupContainer: wrapCustomGetContainer(innerConfig.getContainer)
|
|
969
932
|
}));
|
|
970
933
|
const close = () => {
|
|
@@ -1028,7 +991,7 @@ const useDrawerHolder = () => {
|
|
|
1028
991
|
const {
|
|
1029
992
|
resolveMount,
|
|
1030
993
|
getPopupContainer
|
|
1031
|
-
} =
|
|
994
|
+
} = usePopupMount(viewportPopupMountOptions$1);
|
|
1032
995
|
const getScrollElement = useScrollElement();
|
|
1033
996
|
useEffect(() => {
|
|
1034
997
|
if (actionQueue.length) {
|
|
@@ -1293,7 +1256,7 @@ const useConfirmModal = () => {
|
|
|
1293
1256
|
const {
|
|
1294
1257
|
resolveMount,
|
|
1295
1258
|
getPopupContainer
|
|
1296
|
-
} =
|
|
1259
|
+
} = usePopupMount(viewportPopupMountOptions);
|
|
1297
1260
|
const getScrollElement = useScrollElement();
|
|
1298
1261
|
return props => {
|
|
1299
1262
|
const anchor = typeof document !== 'undefined' ? document.activeElement : null;
|
|
@@ -1301,7 +1264,7 @@ const useConfirmModal = () => {
|
|
|
1301
1264
|
isMobile,
|
|
1302
1265
|
fixedModeClass
|
|
1303
1266
|
} = resolveMount(anchor);
|
|
1304
|
-
const unlock = lockParentScroll
|
|
1267
|
+
const unlock = lockParentScroll(getScrollElement);
|
|
1305
1268
|
const api = {};
|
|
1306
1269
|
const {
|
|
1307
1270
|
afterClose: userAfterClose
|