@kne/react-modal 0.1.10 → 0.1.12

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.
@@ -1,8 +1,8 @@
1
- import { useRef, useEffect, useState, useCallback, memo, forwardRef, useImperativeHandle, createRef, Children } from 'react';
2
- import { Modal as Modal$1, App, Button, Drawer as Drawer$1, Tabs } from 'antd';
1
+ import { useEffect, useState, useCallback, createContext, useContext, useMemo, useRef, createRef, forwardRef, useImperativeHandle, memo, Children } from 'react';
2
+ import { Modal as Modal$1, Button, Drawer as Drawer$1, App, Tabs } from 'antd';
3
3
  import { CloseOutlined, InfoCircleFilled, ExclamationCircleFilled, CloseCircleFilled, CheckCircleFilled } from '@ant-design/icons';
4
4
  import classnames from 'classnames';
5
- import { useMobilePopupMount, useScrollElement } from '@kne/responsive-utils';
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';
@@ -51,7 +51,7 @@ const withLocale = createWithIntlProvider({
51
51
 
52
52
  var modalStyle = {"kne-responsive-boundary":"kne-react-modal_gh14z","kne-responsive-scroll":"kne-react-modal_Kfn6L","modal":"kne-react-modal_Bk7-B","small":"kne-react-modal_DZGD6","large":"kne-react-modal_9sz-n","modal-body-inner":"kne-react-modal_fFnva","is-mobile":"kne-react-modal_LtgJz","modal-container":"kne-react-modal_aEoZq","modal-antd-header":"kne-react-modal_54n8W","modal-antd-footer":"kne-react-modal_AJ9pV","modal-antd-body":"kne-react-modal_u2IjN","modal-outer":"kne-react-modal_kkILR","no-title":"kne-react-modal_8Iysr","no-footer":"kne-react-modal_VMxik","no-padding":"kne-react-modal_Fof-N","modal-title":"kne-react-modal_tG9MF","modal-body":"kne-react-modal_W-QFz","modal-footer":"kne-react-modal_meVfy","body-scroll-off":"kne-react-modal_l627I","is-embedded-footer":"kne-react-modal_17Eih","modal-footer-extra":"kne-react-modal_Fx8Z-","modal-footer-actions":"kne-react-modal_V3ZrX","modal-close":"kne-react-modal_-EK8N","modal-host":"kne-react-modal_eNb-h","modal-form-host":"kne-react-modal_Js8cf","modal-wrap":"kne-react-modal_3Sju5","modal-wrap-centered":"kne-react-modal_-qCIk","modal-wrap-fullscreen":"kne-react-modal_8lS2G","modal-mask-fullscreen":"kne-react-modal_XfLOC"};
53
53
 
54
- const _excluded$7 = ["ButtonComponent", "onClick", "autoClose", "display"];
54
+ const _excluded$8 = ["ButtonComponent", "onClick", "autoClose", "display"];
55
55
  const Footer = ({
56
56
  footer,
57
57
  footerButtons,
@@ -90,7 +90,7 @@ const Footer = ({
90
90
  onClick,
91
91
  autoClose = true
92
92
  } = _ref,
93
- props = _objectWithoutPropertiesLoose(_ref, _excluded$7);
93
+ props = _objectWithoutPropertiesLoose(_ref, _excluded$8);
94
94
  return _extends({}, props, {
95
95
  buttonComponent: ButtonComponent,
96
96
  onClick: async (...args) => {
@@ -125,11 +125,100 @@ const Footer = ({
125
125
  });
126
126
  };
127
127
 
128
- 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
- _excluded2$3 = ["width"],
130
- _excluded3$1 = ["size", "getContainer", "open", "mobileFullscreen", "bodyScroll"],
131
- _excluded4 = ["afterClose", "getContainer", "onClose", "onConfirm", "onCancel"],
132
- _excluded5 = ["children", "getContainer", "afterClose"];
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
+
176
+ const usePatchElement = () => {
177
+ const [elements, setElements] = useState([]);
178
+ const patchElement = useCallback(element => {
179
+ setElements(originElements => [...originElements, element]);
180
+ return () => {
181
+ setElements(originElements => originElements.filter(ele => ele !== element));
182
+ };
183
+ }, []);
184
+ return [elements, patchElement];
185
+ };
186
+
187
+ const ModalLayerContext = /*#__PURE__*/createContext(null);
188
+ const useModalLayer = () => useContext(ModalLayerContext);
189
+
190
+ /**
191
+ * 挂在 Modal 内容树内(antd ZIndexContext 之下),
192
+ * 使就近 useModal 打开的内层成为本层 React 子树,从而自动叠层。
193
+ */
194
+ const ModalLayerProvider = ({
195
+ children
196
+ }) => {
197
+ const [elements, patchElement] = usePatchElement();
198
+ const value = useMemo(() => ({
199
+ patchElement
200
+ }), [patchElement]);
201
+ return /*#__PURE__*/jsxs(ModalLayerContext.Provider, {
202
+ value: value,
203
+ children: [children, elements]
204
+ });
205
+ };
206
+
207
+ /** 根级命令式打开(页面首次弹层);不包 ModalLayerContext。 */
208
+ const rootModalPatchRef = {
209
+ current: null
210
+ };
211
+ const ModalContextHolder = () => {
212
+ const [elements, patchElement] = usePatchElement();
213
+ rootModalPatchRef.current = patchElement;
214
+ return /*#__PURE__*/jsx(Fragment, {
215
+ children: elements
216
+ });
217
+ };
218
+
219
+ const _excluded$7 = ["children", "footer", "footerButtons", "className", "size", "title", "onClose", "onConfirm", "confirmText", "onCancel", "cancelText", "closable", "noPadding", "bodyScroll", "isMobile", "mobileFullscreen", "fixedModeClass", "wrapClassName", "classNames", "styles", "style", "modalRender"],
220
+ _excluded2$4 = ["width"],
221
+ _excluded3$1 = ["size", "getContainer", "open", "mobileFullscreen", "bodyScroll"];
133
222
  const ModalLocaleRoot = withLocale(({
134
223
  children
135
224
  }) => children);
@@ -149,20 +238,10 @@ const wrapCustomGetContainer$2 = customGetContainer => {
149
238
  return () => customGetContainer;
150
239
  };
151
240
  const VIEWPORT_EXAMPLE_SELECTORS$3 = ['.example-driver-device-scroll'];
152
- const viewportPopupMountOptions$1 = {
241
+ const viewportPopupMountOptions$3 = {
153
242
  cover: 'viewport',
154
243
  exampleSelectors: VIEWPORT_EXAMPLE_SELECTORS$3
155
244
  };
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
245
  const resolveModalGetContainer = ({
167
246
  customGetContainer,
168
247
  getPopupContainer,
@@ -177,59 +256,15 @@ const resolveModalGetContainer = ({
177
256
  }
178
257
  }
179
258
  const from = triggerNode || (typeof getHostNode === 'function' ? getHostNode() : null);
180
- const nestedHost = findParentModalMountHost(from);
259
+ const nestedHost = hoistOutOfModalRoot(from);
181
260
  if (nestedHost) {
182
261
  return nestedHost;
183
262
  }
184
263
  return getPopupContainer(triggerNode);
185
264
  };
186
265
  };
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
266
  const sizeStyleVars$1 = (size, hasFooter) => {
267
+ // body 最低高度随 size:small 基准 300,default/large 基准 500(再扣 title/footer chrome)
233
268
  const minBase = size === 'small' ? 300 : 500;
234
269
  const chrome = 48 + (hasFooter ? 58 : 0);
235
270
  const minHeight = `${Math.max(0, minBase - chrome)}px`;
@@ -274,6 +309,19 @@ const ModalOuter = ({
274
309
  children: children
275
310
  });
276
311
  const bodyClassName = classnames(modalStyle['modal-body'], 'modal-body');
312
+ // 移动端全屏:body 用 flex 吃满 title/footer 之间剩余高度,footer 才能贴底;
313
+ // 桌面默认:height:auto + max-height,短内容不撑满;bodyScroll=false 仍写死满高供 Tabs/分栏
314
+ const bodyStyle = isMobile ? {
315
+ flex: '1 1 auto',
316
+ minHeight: 0,
317
+ height: 'auto'
318
+ } : bodyScroll !== false ? {
319
+ height: 'auto',
320
+ maxHeight: 'var(--kne-modal-body-max-height)',
321
+ minHeight: 'var(--kne-modal-body-min-height)'
322
+ } : {
323
+ height: 'var(--kne-modal-body-height)'
324
+ };
277
325
  return /*#__PURE__*/jsxs("div", {
278
326
  className: classnames(modalStyle['modal-outer'], 'modal-container', {
279
327
  [modalStyle['is-mobile']]: isMobile,
@@ -296,12 +344,11 @@ const ModalOuter = ({
296
344
  children: title
297
345
  }) : null, bodyScroll !== false ? /*#__PURE__*/jsx(SimpleBar, {
298
346
  className: bodyClassName,
299
- style: {
300
- height: 'var(--kne-modal-body-height)'
301
- },
347
+ style: bodyStyle,
302
348
  children: bodyInner
303
349
  }) : /*#__PURE__*/jsx("div", {
304
350
  className: classnames(bodyClassName, modalStyle['body-scroll-off']),
351
+ style: bodyStyle,
305
352
  children: bodyInner
306
353
  }), footer === null && footerButtons === undefined ? null : /*#__PURE__*/jsx(Footer, {
307
354
  footer: footer,
@@ -342,14 +389,14 @@ const computedCommonProps = _ref => {
342
389
  style: propsStyle,
343
390
  modalRender
344
391
  } = _ref,
345
- props = _objectWithoutPropertiesLoose(_ref, _excluded$6);
392
+ props = _objectWithoutPropertiesLoose(_ref, _excluded$7);
346
393
  const useMobileLayout = isMobile && mobileFullscreen !== false;
347
394
  const hasFooter = !(footer === null && footerButtons === undefined);
348
395
  const sizeVars = sizeStyleVars$1(size, hasFooter);
349
396
  const {
350
397
  width
351
398
  } = sizeVars,
352
- cssVars = _objectWithoutPropertiesLoose(sizeVars, _excluded2$3);
399
+ cssVars = _objectWithoutPropertiesLoose(sizeVars, _excluded2$4);
353
400
  const runChildren = options => {
354
401
  const opts = Object.assign({}, options, {
355
402
  close: onClose
@@ -424,8 +471,11 @@ const computedCommonProps = _ref => {
424
471
  overflow: 'hidden'
425
472
  } : null)
426
473
  }),
474
+ // LayerProvider 须在 antd Modal 内容树内(ZIndexContext 下),内层命令式才能自动 +100
427
475
  children: /*#__PURE__*/jsx(ModalLocaleRoot, {
428
- children: runChildren({})
476
+ children: /*#__PURE__*/jsx(ModalLayerProvider, {
477
+ children: runChildren({})
478
+ })
429
479
  })
430
480
  });
431
481
  };
@@ -444,11 +494,11 @@ const Modal = withLocale(_ref2 => {
444
494
  fixedModeClass,
445
495
  getPopupContainer,
446
496
  anchorRef
447
- } = useMobilePopupMount(_extends({}, viewportPopupMountOptions$1, {
497
+ } = usePopupMount(_extends({}, viewportPopupMountOptions$3, {
448
498
  getPopupContainer: wrapCustomGetContainer$2(getContainer)
449
499
  }));
450
500
  const getScrollElement = useScrollElement();
451
- useLockParentScroll$1(!!open, getScrollElement);
501
+ useLockParentScroll(!!open, getScrollElement);
452
502
  const setAnchorRef = node => {
453
503
  hostRef.current = node;
454
504
  anchorRef(node);
@@ -476,77 +526,119 @@ const Modal = withLocale(_ref2 => {
476
526
  }))]
477
527
  });
478
528
  });
479
- const useModal = () => {
480
- const {
481
- modal
482
- } = App.useApp();
529
+
530
+ const _excluded$6 = ["afterClose", "onClose", "onConfirm", "onCancel"],
531
+ _excluded2$3 = ["afterClose"];
532
+ let hookModalUuid = 0;
533
+ const HookModal = /*#__PURE__*/forwardRef(({
534
+ config,
535
+ afterClose: hookAfterClose
536
+ }, ref) => {
537
+ const [open, setOpen] = useState(true);
538
+ const [innerConfig, setInnerConfig] = useState(config);
539
+ const close = () => {
540
+ setOpen(false);
541
+ };
542
+ useImperativeHandle(ref, () => ({
543
+ destroy: close,
544
+ update: newConfig => {
545
+ setInnerConfig(origin => Object.assign({}, origin, typeof newConfig === 'function' ? newConfig(origin) : newConfig));
546
+ }
547
+ }));
483
548
  const {
484
- resolveMount,
485
- getPopupContainer
486
- } = useMobilePopupMount(viewportPopupMountOptions$1);
549
+ afterClose: userAfterClose,
550
+ onClose: userOnClose,
551
+ onConfirm: userOnConfirm,
552
+ onCancel: userOnCancel
553
+ } = innerConfig,
554
+ restConfig = _objectWithoutPropertiesLoose(innerConfig, _excluded$6);
555
+ return /*#__PURE__*/jsx(Modal, _extends({}, restConfig, {
556
+ open: open,
557
+ onClose: () => {
558
+ userOnClose == null || userOnClose();
559
+ close();
560
+ },
561
+ onCancel: (...args) => {
562
+ userOnCancel == null || userOnCancel(...args);
563
+ close();
564
+ },
565
+ onConfirm: async (...args) => {
566
+ const res = await Promise.resolve(userOnConfirm == null ? void 0 : userOnConfirm(...args));
567
+ if (res !== false) {
568
+ close();
569
+ }
570
+ return res;
571
+ },
572
+ afterClose: (...args) => {
573
+ hookAfterClose == null || hookAfterClose(...args);
574
+ userAfterClose == null || userAfterClose(...args);
575
+ }
576
+ }));
577
+ });
578
+
579
+ /**
580
+ * 命令式内容弹窗:就近 patch 到 ModalLayerProvider(多层)或根 ModalContextHolder。
581
+ * 不走 App.modal.info / ConfirmDialog,层级交给 antd ZIndexContext。
582
+ */
583
+ const useModal = () => {
584
+ const layer = useContext(ModalLayerContext);
487
585
  const getScrollElement = useScrollElement();
488
- return props => {
489
- const anchor = typeof document !== 'undefined' ? document.activeElement : null;
490
- const {
491
- isMobile,
492
- fixedModeClass
493
- } = resolveMount(anchor);
494
- const unlock = lockParentScroll$1(getScrollElement);
586
+ const [actionQueue, setActionQueue] = useState([]);
587
+ useEffect(() => {
588
+ if (actionQueue.length) {
589
+ const cloneQueue = [...actionQueue];
590
+ cloneQueue.forEach(action => action());
591
+ setActionQueue([]);
592
+ }
593
+ }, [actionQueue]);
594
+ return useCallback(props => {
595
+ hookModalUuid += 1;
596
+ const modalRef = /*#__PURE__*/createRef();
495
597
  const api = {};
496
- const {
497
- afterClose: userAfterClose,
498
- getContainer: customGetContainer,
499
- onClose: userOnClose,
500
- onConfirm: userOnConfirm,
501
- onCancel: userOnCancel
502
- } = props,
503
- restProps = _objectWithoutPropertiesLoose(props, _excluded4);
504
- const closeModal = () => {
505
- api.close == null || api.close();
506
- };
507
- const _computedCommonProps = computedCommonProps(_extends({}, restProps, {
508
- isMobile,
509
- fixedModeClass,
510
- onClose: () => {
511
- userOnClose == null || userOnClose();
512
- closeModal();
513
- },
514
- onCancel: (...args) => {
515
- userOnCancel == null || userOnCancel(...args);
516
- closeModal();
517
- },
518
- onConfirm: async (...args) => {
519
- const res = await Promise.resolve(userOnConfirm == null ? void 0 : userOnConfirm(...args));
520
- if (res !== false) {
521
- closeModal();
598
+ let closeFunc;
599
+ let unlock = () => {};
600
+ const resolvePatch = () => (layer == null ? void 0 : layer.patchElement) || rootModalPatchRef.current;
601
+ const runOpen = () => {
602
+ const patch = resolvePatch();
603
+ if (typeof patch !== 'function') {
604
+ throw new Error('useModal requires <ModalContextHolder /> mounted inside <App> before calling useModal()');
605
+ }
606
+ unlock = lockParentScroll(getScrollElement);
607
+ const {
608
+ afterClose: userAfterClose
609
+ } = props,
610
+ restProps = _objectWithoutPropertiesLoose(props, _excluded2$3);
611
+ const modalEl = /*#__PURE__*/jsx(HookModal, {
612
+ ref: modalRef,
613
+ config: _extends({}, restProps, {
614
+ afterClose: (...args) => {
615
+ unlock();
616
+ userAfterClose == null || userAfterClose(...args);
522
617
  }
523
- return res;
524
- },
525
- afterClose: (...args) => {
526
- unlock();
527
- userAfterClose == null || userAfterClose(...args);
618
+ }),
619
+ afterClose: () => {
620
+ closeFunc && closeFunc();
528
621
  }
529
- })),
530
- {
531
- children,
532
- getContainer,
533
- afterClose
534
- } = _computedCommonProps,
535
- otherProps = _objectWithoutPropertiesLoose(_computedCommonProps, _excluded5);
536
- const {
537
- destroy
538
- } = modal.info(_extends({}, otherProps, {
539
- afterClose,
540
- content: children,
541
- getContainer: resolveModalGetContainer({
542
- customGetContainer: customGetContainer != null ? customGetContainer : getContainer,
543
- getPopupContainer,
544
- getHostNode: () => anchor
545
- })
546
- }));
547
- api.close = destroy;
622
+ }, `react-modal-${hookModalUuid}`);
623
+ closeFunc = patch(modalEl);
624
+ };
625
+ if (resolvePatch()) {
626
+ runOpen();
627
+ } else {
628
+ setActionQueue(prev => [...prev, runOpen]);
629
+ }
630
+ api.close = () => {
631
+ if (modalRef.current) {
632
+ modalRef.current.destroy();
633
+ } else {
634
+ setActionQueue(prev => [...prev, () => {
635
+ var _modalRef$current;
636
+ return (_modalRef$current = modalRef.current) == null ? void 0 : _modalRef$current.destroy();
637
+ }]);
638
+ }
639
+ };
548
640
  return api;
549
- };
641
+ }, [getScrollElement, layer]);
550
642
  };
551
643
 
552
644
  var style = {"kne-responsive-boundary":"kne-react-modal_qwqLr","kne-responsive-scroll":"kne-react-modal_vmry7","drawer":"kne-react-modal_cDsbq","small":"kne-react-modal_3QgK-","is-mobile":"kne-react-modal_FFf73","large":"kne-react-modal_8lell","drawer-body-inner":"kne-react-modal_xgX4D","drawer-antd-header":"kne-react-modal_3EUxr","drawer-antd-footer":"kne-react-modal_2G81L","drawer-antd-body":"kne-react-modal_eKVMu","drawer-outer":"kne-react-modal_P3Cw8","no-title":"kne-react-modal_upRot","no-footer":"kne-react-modal_j4sGu","no-padding":"kne-react-modal_pg37M","drawer-title":"kne-react-modal_-hw5V","drawer-body":"kne-react-modal_nJj7Y","body-scroll-off":"kne-react-modal_2Wh1H","modal-footer-extra":"kne-react-modal_M4hy9","drawer-close":"kne-react-modal_dVh38","drawer-host":"kne-react-modal_Nsxi9","drawer-host-render":"kne-react-modal_iGDWP","drawer-panel-host":"kne-react-modal_A0h-2","drawer-panel-body":"kne-react-modal_E4tcc","drawer-form-host":"kne-react-modal_vKkQW","drawer-wrapper-mobile":"kne-react-modal_vsxOs","drawer-wrapper-mobile-vertical":"kne-react-modal_HG8Vz","drawer-root-mobile":"kne-react-modal_G-qXe"};
@@ -558,8 +650,10 @@ const DrawerLocaleRoot = withLocale(({
558
650
  children
559
651
  }) => children);
560
652
  const VIEWPORT_EXAMPLE_SELECTORS$2 = ['.example-driver-device-scroll'];
561
- const boundaryPopupMountOptions$1 = {
562
- cover: 'boundary',
653
+
654
+ // 与 Modal 一致:真机挂 body+fixed;示例框 / container 模式仍走 boundary(usePopupMount 内判定)
655
+ const viewportPopupMountOptions$2 = {
656
+ cover: 'viewport',
563
657
  exampleSelectors: VIEWPORT_EXAMPLE_SELECTORS$2
564
658
  };
565
659
  const renderWithOptions = (value, options) => {
@@ -609,51 +703,6 @@ const resolveDrawerGetContainer = ({
609
703
  return getPopupContainer(triggerNode);
610
704
  };
611
705
  };
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
706
  const sizeStyleVars = (size, hasFooter) => {
658
707
  const minBase = size === 'small' ? 300 : 500;
659
708
  const chrome = 48 + (hasFooter ? 69 : 0);
@@ -890,7 +939,7 @@ const Drawer = withLocale(_ref2 => {
890
939
  fixedModeClass,
891
940
  getPopupContainer,
892
941
  anchorRef
893
- } = useMobilePopupMount(_extends({}, boundaryPopupMountOptions$1, {
942
+ } = usePopupMount(_extends({}, viewportPopupMountOptions$2, {
894
943
  getPopupContainer: wrapCustomGetContainer$1(getContainer)
895
944
  }));
896
945
  const getScrollElement = useScrollElement();
@@ -923,22 +972,13 @@ const Drawer = withLocale(_ref2 => {
923
972
  });
924
973
  });
925
974
 
926
- const usePatchElement = () => {
927
- const [elements, setElements] = useState([]);
928
- const patchElement = useCallback(element => {
929
- setElements(originElements => [...originElements, element]);
930
- return () => {
931
- setElements(originElements => originElements.filter(ele => ele !== element));
932
- };
933
- }, []);
934
- return [elements, patchElement];
935
- };
936
-
937
975
  const _excluded$4 = ["getContainer", "afterClose"],
938
976
  _excluded2$1 = ["afterClose", "getContainer"];
939
977
  const VIEWPORT_EXAMPLE_SELECTORS$1 = ['.example-driver-device-scroll'];
940
- const boundaryPopupMountOptions = {
941
- cover: 'boundary',
978
+
979
+ // 与 Modal / Drawer 一致:真机 viewport;示例框 / container 仍 boundary
980
+ const viewportPopupMountOptions$1 = {
981
+ cover: 'viewport',
942
982
  exampleSelectors: VIEWPORT_EXAMPLE_SELECTORS$1
943
983
  };
944
984
  const wrapCustomGetContainer = customGetContainer => {
@@ -964,7 +1004,7 @@ const HookDrawer = /*#__PURE__*/forwardRef(({
964
1004
  const {
965
1005
  getPopupContainer,
966
1006
  anchorRef
967
- } = useMobilePopupMount(_extends({}, boundaryPopupMountOptions, {
1007
+ } = usePopupMount(_extends({}, viewportPopupMountOptions$1, {
968
1008
  getPopupContainer: wrapCustomGetContainer(innerConfig.getContainer)
969
1009
  }));
970
1010
  const close = () => {
@@ -1028,7 +1068,7 @@ const useDrawerHolder = () => {
1028
1068
  const {
1029
1069
  resolveMount,
1030
1070
  getPopupContainer
1031
- } = useMobilePopupMount(boundaryPopupMountOptions);
1071
+ } = usePopupMount(viewportPopupMountOptions$1);
1032
1072
  const getScrollElement = useScrollElement();
1033
1073
  useEffect(() => {
1034
1074
  if (actionQueue.length) {
@@ -1249,41 +1289,46 @@ const mapConfirmProps = (props, {
1249
1289
  icon,
1250
1290
  isMobile
1251
1291
  });
1292
+
1293
+ // Confirm 走 antd ConfirmDialog:未传 zIndex 时用 static 顶层,适合真确认框盖住内容弹窗
1294
+ const config = _extends({}, otherProps, {
1295
+ okText: confirmText != null ? confirmText : otherProps.okText,
1296
+ cancelText: cancelText != null ? cancelText : otherProps.cancelText,
1297
+ onOk: onConfirm != null ? onConfirm : otherProps.onOk,
1298
+ onCancel: onCancel != null ? onCancel : otherProps.onCancel,
1299
+ getContainer: resolveModalGetContainer({
1300
+ customGetContainer,
1301
+ getPopupContainer,
1302
+ getHostNode: () => anchor
1303
+ }),
1304
+ centered: true,
1305
+ afterClose: (...args) => {
1306
+ unlock();
1307
+ userAfterClose && userAfterClose(...args);
1308
+ afterClose && afterClose(...args);
1309
+ },
1310
+ icon: null,
1311
+ classNames: {
1312
+ mask: classnames(isMobile && modalStyle['modal-mask-fullscreen'], isMobile && fixedModeClass, (_otherProps$className = otherProps.classNames) == null ? void 0 : _otherProps$className.mask)
1313
+ },
1314
+ wrapClassName: classnames(modalStyle['modal-wrap'], modalStyle['modal-wrap-centered'], confirmStyle['confirm-modal-wrap'], wrapClassName, {
1315
+ [confirmStyle['is-danger']]: danger,
1316
+ [confirmStyle['is-mobile']]: isMobile,
1317
+ [fixedModeClass]: isMobile
1318
+ }),
1319
+ title: confirmTitle ? /*#__PURE__*/jsx(ConfirmLocaleRoot, {
1320
+ children: confirmTitle
1321
+ }) : null,
1322
+ content: /*#__PURE__*/jsx(ConfirmLocaleRoot, {
1323
+ children: content
1324
+ })
1325
+ });
1326
+ if (zIndex !== undefined) {
1327
+ config.zIndex = zIndex;
1328
+ }
1252
1329
  return {
1253
1330
  modalMethod: type,
1254
- config: _extends({}, otherProps, {
1255
- zIndex: zIndex != null ? zIndex : 1100,
1256
- okText: confirmText != null ? confirmText : otherProps.okText,
1257
- cancelText: cancelText != null ? cancelText : otherProps.cancelText,
1258
- onOk: onConfirm != null ? onConfirm : otherProps.onOk,
1259
- onCancel: onCancel != null ? onCancel : otherProps.onCancel,
1260
- getContainer: resolveModalGetContainer({
1261
- customGetContainer,
1262
- getPopupContainer,
1263
- getHostNode: () => anchor
1264
- }),
1265
- centered: true,
1266
- afterClose: (...args) => {
1267
- unlock();
1268
- userAfterClose && userAfterClose(...args);
1269
- afterClose && afterClose(...args);
1270
- },
1271
- icon: null,
1272
- classNames: {
1273
- mask: classnames(isMobile && modalStyle['modal-mask-fullscreen'], isMobile && fixedModeClass, (_otherProps$className = otherProps.classNames) == null ? void 0 : _otherProps$className.mask)
1274
- },
1275
- wrapClassName: classnames(modalStyle['modal-wrap'], modalStyle['modal-wrap-centered'], confirmStyle['confirm-modal-wrap'], wrapClassName, {
1276
- [confirmStyle['is-danger']]: danger,
1277
- [confirmStyle['is-mobile']]: isMobile,
1278
- [fixedModeClass]: isMobile
1279
- }),
1280
- title: confirmTitle ? /*#__PURE__*/jsx(ConfirmLocaleRoot, {
1281
- children: confirmTitle
1282
- }) : null,
1283
- content: /*#__PURE__*/jsx(ConfirmLocaleRoot, {
1284
- children: content
1285
- })
1286
- })
1331
+ config
1287
1332
  };
1288
1333
  };
1289
1334
  const useConfirmModal = () => {
@@ -1293,7 +1338,7 @@ const useConfirmModal = () => {
1293
1338
  const {
1294
1339
  resolveMount,
1295
1340
  getPopupContainer
1296
- } = useMobilePopupMount(viewportPopupMountOptions);
1341
+ } = usePopupMount(viewportPopupMountOptions);
1297
1342
  const getScrollElement = useScrollElement();
1298
1343
  return props => {
1299
1344
  const anchor = typeof document !== 'undefined' ? document.activeElement : null;
@@ -1301,7 +1346,7 @@ const useConfirmModal = () => {
1301
1346
  isMobile,
1302
1347
  fixedModeClass
1303
1348
  } = resolveMount(anchor);
1304
- const unlock = lockParentScroll$1(getScrollElement);
1349
+ const unlock = lockParentScroll(getScrollElement);
1305
1350
  const api = {};
1306
1351
  const {
1307
1352
  afterClose: userAfterClose
@@ -1406,5 +1451,5 @@ const modalClassNames = {
1406
1451
  splitter: 'react-modal-splitter'
1407
1452
  };
1408
1453
 
1409
- export { ColumnsLayout, Drawer, DrawerContextHolder, ScrollRegion, TabsLayout, createDrawerRender, createModalRender, Modal as default, modalClassNames, useConfirmModal, useDrawer, useModal };
1454
+ export { ColumnsLayout, Drawer, DrawerContextHolder, ModalContextHolder, ModalLayerContext, ScrollRegion, TabsLayout, createDrawerRender, createModalRender, Modal as default, modalClassNames, useConfirmModal, useDrawer, useModal, useModalLayer };
1410
1455
  //# sourceMappingURL=index.modern.js.map