@alfalab/core-components-base-modal 2.1.1 → 3.1.0

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/CHANGELOG.md CHANGED
@@ -3,6 +3,43 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [3.1.0](https://github.com/alfa-laboratory/core-components/compare/@alfalab/core-components-base-modal@3.0.2...@alfalab/core-components-base-modal@3.1.0) (2022-01-17)
7
+
8
+
9
+ ### Features
10
+
11
+ * **base-modal:** extract modal store to global ([#943](https://github.com/alfa-laboratory/core-components/issues/943)) ([9587f17](https://github.com/alfa-laboratory/core-components/commit/9587f1773bb690ac6696077509d4a519aa109198))
12
+
13
+
14
+
15
+
16
+
17
+ ## [3.0.2](https://github.com/alfa-laboratory/core-components/compare/@alfalab/core-components-base-modal@3.0.1...@alfalab/core-components-base-modal@3.0.2) (2021-09-14)
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * **base-modal:** modal scroll ([#820](https://github.com/alfa-laboratory/core-components/issues/820)) ([1b2d94a](https://github.com/alfa-laboratory/core-components/commit/1b2d94ad45e04145bf1292d749ae2028702dc622))
23
+
24
+
25
+
26
+
27
+
28
+ ## [3.0.1](https://github.com/alfa-laboratory/core-components/compare/@alfalab/core-components-base-modal@3.0.0...@alfalab/core-components-base-modal@3.0.1) (2021-07-09)
29
+
30
+ **Note:** Version bump only for package @alfalab/core-components-base-modal
31
+
32
+
33
+
34
+
35
+
36
+ # [3.0.0](https://github.com/alfa-laboratory/core-components/compare/@alfalab/core-components-base-modal@2.1.1...@alfalab/core-components-base-modal@3.0.0) (2021-07-08)
37
+
38
+
39
+ ### Features
40
+
41
+ * upgrade storybook ([#696](https://github.com/alfa-laboratory/core-components/issues/696))
42
+
6
43
  ## [2.1.1](https://github.com/alfa-laboratory/core-components/compare/@alfalab/core-components-base-modal@2.1.0...@alfalab/core-components-base-modal@2.1.1) (2021-07-02)
7
44
 
8
45
 
package/dist/Component.js CHANGED
@@ -11,6 +11,7 @@ var FocusLock = require('react-focus-lock');
11
11
  var coreComponentsPortal = require('@alfalab/core-components-portal');
12
12
  var coreComponentsBackdrop = require('@alfalab/core-components-backdrop');
13
13
  var coreComponentsStack = require('@alfalab/core-components-stack');
14
+ require('@alfalab/core-components-global-store');
14
15
  var utils = require('./utils.js');
15
16
 
16
17
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -47,7 +48,7 @@ var __assign = function () {
47
48
  return __assign.apply(this, arguments);
48
49
  };
49
50
 
50
- var styles = {"component":"base-modal__component_5xaig","wrapper":"base-modal__wrapper_5xaig","content":"base-modal__content_5xaig","hidden":"base-modal__hidden_5xaig","backdrop":"base-modal__backdrop_5xaig","appear":"base-modal__appear_5xaig","enter":"base-modal__enter_5xaig","appearActive":"base-modal__appearActive_5xaig","enterActive":"base-modal__enterActive_5xaig","exit":"base-modal__exit_5xaig","exitActive":"base-modal__exitActive_5xaig","exitDone":"base-modal__exitDone_5xaig"};
51
+ var styles = {"component":"base-modal__component_rp8e5","wrapper":"base-modal__wrapper_rp8e5","content":"base-modal__content_rp8e5","hidden":"base-modal__hidden_rp8e5","backdrop":"base-modal__backdrop_rp8e5","appear":"base-modal__appear_rp8e5","enter":"base-modal__enter_rp8e5","appearActive":"base-modal__appearActive_rp8e5","enterActive":"base-modal__enterActive_rp8e5","exit":"base-modal__exit_rp8e5","exitActive":"base-modal__exitActive_rp8e5","exitDone":"base-modal__exitDone_rp8e5"};
51
52
  require('./index.css')
52
53
 
53
54
  var BaseModalContext = React__default['default'].createContext({
@@ -73,7 +74,7 @@ var BaseModal = React.forwardRef(function (_a, ref) {
73
74
  var wrapperRef = React.useRef(null);
74
75
  var scrollableNodeRef = React.useRef(null);
75
76
  var contentNodeRef = React.useRef(null);
76
- var restoreContainerStyles = React.useRef(null);
77
+ var restoreContainerStylesRef = React.useRef(null);
77
78
  var checkToHasScrollBar = function () {
78
79
  if (scrollableNodeRef.current) {
79
80
  var scrollExists = utils.hasScrollbar(scrollableNodeRef.current);
@@ -82,6 +83,9 @@ var BaseModal = React.forwardRef(function (_a, ref) {
82
83
  }
83
84
  };
84
85
  var shouldRender = keepMounted || open || !exited;
86
+ var getContainer = React.useCallback(function () {
87
+ return (container ? container() : document.body);
88
+ }, [container]);
85
89
  var resizeObserver$1 = React.useMemo(function () { return new resizeObserver.ResizeObserver(checkToHasScrollBar); }, []);
86
90
  var addResizeHandle = React.useCallback(function () {
87
91
  if (scrollableNodeRef.current)
@@ -124,7 +128,7 @@ var BaseModal = React.forwardRef(function (_a, ref) {
124
128
  return null;
125
129
  }, [onBackdropClick, onClose, onEscapeKeyDown]);
126
130
  var handleBackdropClick = function (event) {
127
- if (!disableBackdropClick) {
131
+ if (!disableBackdropClick && event.target === wrapperRef.current) {
128
132
  handleClose(event, 'backdropClick');
129
133
  }
130
134
  };
@@ -173,27 +177,29 @@ var BaseModal = React.forwardRef(function (_a, ref) {
173
177
  }
174
178
  if (onUnmount)
175
179
  onUnmount();
176
- if (restoreContainerStyles.current) {
177
- restoreContainerStyles.current();
178
- restoreContainerStyles.current = null;
180
+ if (restoreContainerStylesRef.current) {
181
+ restoreContainerStylesRef.current();
179
182
  }
180
183
  }, [handleScroll, onUnmount, removeResizeHandle, transitionProps]);
181
184
  React.useEffect(function () {
182
185
  if (open) {
183
- restoreContainerStyles.current = utils.handleContainer((container ? container() : document.body));
186
+ utils.handleContainer(getContainer());
187
+ restoreContainerStylesRef.current = function () {
188
+ restoreContainerStylesRef.current = null;
189
+ utils.restoreContainerStyles(getContainer());
190
+ };
184
191
  }
185
- // eslint-disable-next-line react-hooks/exhaustive-deps
186
- }, [open]);
192
+ }, [getContainer, open]);
187
193
  React.useEffect(function () {
188
194
  if (open)
189
195
  setExited(false);
190
196
  }, [open]);
191
197
  React.useEffect(function () {
192
198
  return function () {
193
- resizeObserver$1.disconnect();
194
- if (restoreContainerStyles.current) {
195
- restoreContainerStyles.current();
199
+ if (restoreContainerStylesRef.current) {
200
+ restoreContainerStylesRef.current();
196
201
  }
202
+ resizeObserver$1.disconnect();
197
203
  };
198
204
  // eslint-disable-next-line react-hooks/exhaustive-deps
199
205
  }, []);
@@ -223,12 +229,14 @@ var BaseModal = React.forwardRef(function (_a, ref) {
223
229
  return (React__default['default'].createElement(coreComponentsPortal.Portal, { getPortalContainer: container },
224
230
  React__default['default'].createElement(BaseModalContext.Provider, { value: contextValue },
225
231
  React__default['default'].createElement(FocusLock__default['default'], { autoFocus: !disableAutoFocus, disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus },
232
+ Backdrop && (React__default['default'].createElement(Backdrop, __assign({}, backdropProps, { className: cn__default['default'](backdropProps.className, styles.backdrop), open: open, style: {
233
+ zIndex: computedZIndex,
234
+ } }))),
226
235
  React__default['default'].createElement("div", { role: 'dialog', className: cn__default['default'](styles.wrapper, wrapperClassName, (_a = {},
227
236
  _a[styles.hidden] = !open && exited,
228
- _a)), ref: mergeRefs__default['default']([ref, wrapperRef]), onKeyDown: handleKeyDown, tabIndex: -1, "data-test-id": dataTestId, style: {
237
+ _a)), ref: mergeRefs__default['default']([ref, wrapperRef]), onKeyDown: handleKeyDown, onClick: handleBackdropClick, tabIndex: -1, "data-test-id": dataTestId, style: {
229
238
  zIndex: computedZIndex,
230
239
  } },
231
- Backdrop && (React__default['default'].createElement(Backdrop, __assign({}, backdropProps, { className: cn__default['default'](backdropProps.className, styles.backdrop), open: open, onClick: handleBackdropClick }))),
232
240
  React__default['default'].createElement(reactTransitionGroup.CSSTransition, __assign({ appear: true, timeout: 200, classNames: styles }, transitionProps, { in: open, onEntered: handleEntered, onExited: handleExited }),
233
241
  React__default['default'].createElement("div", { className: cn__default['default'](styles.component, className), ref: componentRef },
234
242
  React__default['default'].createElement("div", { className: cn__default['default'](styles.content, contentClassName) }, children))))))));
@@ -11,6 +11,7 @@ var FocusLock = require('react-focus-lock');
11
11
  var coreComponentsPortal = require('@alfalab/core-components-portal/dist/cssm');
12
12
  var coreComponentsBackdrop = require('@alfalab/core-components-backdrop/dist/cssm');
13
13
  var coreComponentsStack = require('@alfalab/core-components-stack/dist/cssm');
14
+ require('@alfalab/core-components-global-store/dist/cssm');
14
15
  var utils = require('./utils.js');
15
16
  var styles = require('./index.module.css');
16
17
 
@@ -72,7 +73,7 @@ var BaseModal = React.forwardRef(function (_a, ref) {
72
73
  var wrapperRef = React.useRef(null);
73
74
  var scrollableNodeRef = React.useRef(null);
74
75
  var contentNodeRef = React.useRef(null);
75
- var restoreContainerStyles = React.useRef(null);
76
+ var restoreContainerStylesRef = React.useRef(null);
76
77
  var checkToHasScrollBar = function () {
77
78
  if (scrollableNodeRef.current) {
78
79
  var scrollExists = utils.hasScrollbar(scrollableNodeRef.current);
@@ -81,6 +82,9 @@ var BaseModal = React.forwardRef(function (_a, ref) {
81
82
  }
82
83
  };
83
84
  var shouldRender = keepMounted || open || !exited;
85
+ var getContainer = React.useCallback(function () {
86
+ return (container ? container() : document.body);
87
+ }, [container]);
84
88
  var resizeObserver$1 = React.useMemo(function () { return new resizeObserver.ResizeObserver(checkToHasScrollBar); }, []);
85
89
  var addResizeHandle = React.useCallback(function () {
86
90
  if (scrollableNodeRef.current)
@@ -123,7 +127,7 @@ var BaseModal = React.forwardRef(function (_a, ref) {
123
127
  return null;
124
128
  }, [onBackdropClick, onClose, onEscapeKeyDown]);
125
129
  var handleBackdropClick = function (event) {
126
- if (!disableBackdropClick) {
130
+ if (!disableBackdropClick && event.target === wrapperRef.current) {
127
131
  handleClose(event, 'backdropClick');
128
132
  }
129
133
  };
@@ -172,27 +176,29 @@ var BaseModal = React.forwardRef(function (_a, ref) {
172
176
  }
173
177
  if (onUnmount)
174
178
  onUnmount();
175
- if (restoreContainerStyles.current) {
176
- restoreContainerStyles.current();
177
- restoreContainerStyles.current = null;
179
+ if (restoreContainerStylesRef.current) {
180
+ restoreContainerStylesRef.current();
178
181
  }
179
182
  }, [handleScroll, onUnmount, removeResizeHandle, transitionProps]);
180
183
  React.useEffect(function () {
181
184
  if (open) {
182
- restoreContainerStyles.current = utils.handleContainer((container ? container() : document.body));
185
+ utils.handleContainer(getContainer());
186
+ restoreContainerStylesRef.current = function () {
187
+ restoreContainerStylesRef.current = null;
188
+ utils.restoreContainerStyles(getContainer());
189
+ };
183
190
  }
184
- // eslint-disable-next-line react-hooks/exhaustive-deps
185
- }, [open]);
191
+ }, [getContainer, open]);
186
192
  React.useEffect(function () {
187
193
  if (open)
188
194
  setExited(false);
189
195
  }, [open]);
190
196
  React.useEffect(function () {
191
197
  return function () {
192
- resizeObserver$1.disconnect();
193
- if (restoreContainerStyles.current) {
194
- restoreContainerStyles.current();
198
+ if (restoreContainerStylesRef.current) {
199
+ restoreContainerStylesRef.current();
195
200
  }
201
+ resizeObserver$1.disconnect();
196
202
  };
197
203
  // eslint-disable-next-line react-hooks/exhaustive-deps
198
204
  }, []);
@@ -222,12 +228,14 @@ var BaseModal = React.forwardRef(function (_a, ref) {
222
228
  return (React__default['default'].createElement(coreComponentsPortal.Portal, { getPortalContainer: container },
223
229
  React__default['default'].createElement(BaseModalContext.Provider, { value: contextValue },
224
230
  React__default['default'].createElement(FocusLock__default['default'], { autoFocus: !disableAutoFocus, disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus },
231
+ Backdrop && (React__default['default'].createElement(Backdrop, __assign({}, backdropProps, { className: cn__default['default'](backdropProps.className, styles__default['default'].backdrop), open: open, style: {
232
+ zIndex: computedZIndex,
233
+ } }))),
225
234
  React__default['default'].createElement("div", { role: 'dialog', className: cn__default['default'](styles__default['default'].wrapper, wrapperClassName, (_a = {},
226
235
  _a[styles__default['default'].hidden] = !open && exited,
227
- _a)), ref: mergeRefs__default['default']([ref, wrapperRef]), onKeyDown: handleKeyDown, tabIndex: -1, "data-test-id": dataTestId, style: {
236
+ _a)), ref: mergeRefs__default['default']([ref, wrapperRef]), onKeyDown: handleKeyDown, onClick: handleBackdropClick, tabIndex: -1, "data-test-id": dataTestId, style: {
228
237
  zIndex: computedZIndex,
229
238
  } },
230
- Backdrop && (React__default['default'].createElement(Backdrop, __assign({}, backdropProps, { className: cn__default['default'](backdropProps.className, styles__default['default'].backdrop), open: open, onClick: handleBackdropClick }))),
231
239
  React__default['default'].createElement(reactTransitionGroup.CSSTransition, __assign({ appear: true, timeout: 200, classNames: styles__default['default'] }, transitionProps, { in: open, onEntered: handleEntered, onExited: handleExited }),
232
240
  React__default['default'].createElement("div", { className: cn__default['default'](styles__default['default'].component, className), ref: componentRef },
233
241
  React__default['default'].createElement("div", { className: cn__default['default'](styles__default['default'].content, contentClassName) }, children))))))));
@@ -12,6 +12,7 @@ require('react-focus-lock');
12
12
  require('@alfalab/core-components-portal/dist/cssm');
13
13
  require('@alfalab/core-components-backdrop/dist/cssm');
14
14
  require('@alfalab/core-components-stack/dist/cssm');
15
+ require('@alfalab/core-components-global-store/dist/cssm');
15
16
  var utils = require('./utils.js');
16
17
  require('./index.module.css');
17
18
 
@@ -23,3 +24,4 @@ exports.handleContainer = utils.handleContainer;
23
24
  exports.hasScrollbar = utils.hasScrollbar;
24
25
  exports.isScrolledToBottom = utils.isScrolledToBottom;
25
26
  exports.isScrolledToTop = utils.isScrolledToTop;
27
+ exports.restoreContainerStyles = utils.restoreContainerStyles;
@@ -40,7 +40,7 @@
40
40
  display: none;
41
41
  }
42
42
  .backdrop {
43
- z-index: -1;
43
+ z-index: 0;
44
44
  }
45
45
  .appear,
46
46
  .enter {
@@ -1,5 +1,6 @@
1
1
  declare function isScrolledToTop(target: HTMLElement): boolean;
2
2
  declare function isScrolledToBottom(target: HTMLElement): boolean;
3
3
  declare function hasScrollbar(target: HTMLElement): boolean;
4
- declare const handleContainer: (container: HTMLElement) => () => void;
5
- export { isScrolledToTop, isScrolledToBottom, hasScrollbar, handleContainer };
4
+ declare const restoreContainerStyles: (container: HTMLElement) => void;
5
+ declare const handleContainer: (container?: HTMLElement | undefined) => void;
6
+ export { isScrolledToTop, isScrolledToBottom, hasScrollbar, restoreContainerStyles, handleContainer };
@@ -2,6 +2,8 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ var coreComponentsGlobalStore = require('@alfalab/core-components-global-store/dist/cssm');
6
+
5
7
  function isScrolledToTop(target) {
6
8
  return target.scrollTop <= 0;
7
9
  }
@@ -32,12 +34,40 @@ var isOverflowing = function (container) {
32
34
  var getPaddingRight = function (node) {
33
35
  return parseInt(window.getComputedStyle(node).paddingRight, 10) || 0;
34
36
  };
37
+ var restoreContainerStyles = function (container) {
38
+ var modalRestoreStyles = coreComponentsGlobalStore.getModalStore().getRestoreStyles();
39
+ var index = modalRestoreStyles.findIndex(function (s) { return s.container === container; });
40
+ var existingStyles = modalRestoreStyles[index];
41
+ if (!existingStyles)
42
+ return;
43
+ existingStyles.modals -= 1;
44
+ if (existingStyles.modals <= 0) {
45
+ modalRestoreStyles.splice(index, 1);
46
+ existingStyles.styles.forEach(function (_a) {
47
+ var value = _a.value, el = _a.el, key = _a.key;
48
+ if (value) {
49
+ el.style.setProperty(key, value);
50
+ }
51
+ else {
52
+ el.style.removeProperty(key);
53
+ }
54
+ });
55
+ }
56
+ };
35
57
  var handleContainer = function (container) {
36
- var restoreStyle = [];
58
+ if (!container)
59
+ return;
60
+ var modalRestoreStyles = coreComponentsGlobalStore.getModalStore().getRestoreStyles();
61
+ var existingStyles = modalRestoreStyles.find(function (s) { return s.container === container; });
62
+ if (existingStyles) {
63
+ existingStyles.modals += 1;
64
+ return;
65
+ }
66
+ var containerStyles = [];
37
67
  if (isOverflowing(container)) {
38
68
  // Вычисляет размер до применения `overflow hidden` для избежания скачков
39
69
  var scrollbarSize = getScrollbarSize();
40
- restoreStyle.push({
70
+ containerStyles.push({
41
71
  value: container.style.paddingRight,
42
72
  key: 'padding-right',
43
73
  el: container,
@@ -56,27 +86,22 @@ var handleContainer = function (container) {
56
86
  : container;
57
87
  // Блокируем скролл даже если отсутствует скроллбар
58
88
  if (scrollContainer.style.overflow !== 'hidden') {
59
- restoreStyle.push({
89
+ containerStyles.push({
60
90
  value: scrollContainer.style.overflow,
61
91
  key: 'overflow',
62
92
  el: scrollContainer,
63
93
  });
64
94
  }
65
95
  scrollContainer.style.overflow = 'hidden';
66
- return function () {
67
- restoreStyle.forEach(function (_a) {
68
- var value = _a.value, el = _a.el, key = _a.key;
69
- if (value) {
70
- el.style.setProperty(key, value);
71
- }
72
- else {
73
- el.style.removeProperty(key);
74
- }
75
- });
76
- };
96
+ modalRestoreStyles.push({
97
+ container: container,
98
+ modals: 1,
99
+ styles: containerStyles,
100
+ });
77
101
  };
78
102
 
79
103
  exports.handleContainer = handleContainer;
80
104
  exports.hasScrollbar = hasScrollbar;
81
105
  exports.isScrolledToBottom = isScrolledToBottom;
82
106
  exports.isScrolledToTop = isScrolledToTop;
107
+ exports.restoreContainerStyles = restoreContainerStyles;
@@ -1,4 +1,4 @@
1
- import React, { forwardRef, useState, useRef, useMemo, useCallback, useEffect } from 'react';
1
+ import React, { forwardRef, useState, useRef, useCallback, useMemo, useEffect } from 'react';
2
2
  import cn from 'classnames';
3
3
  import mergeRefs from 'react-merge-refs';
4
4
  import { ResizeObserver } from 'resize-observer';
@@ -7,7 +7,8 @@ import FocusLock from 'react-focus-lock';
7
7
  import { Portal } from '@alfalab/core-components-portal/dist/esm';
8
8
  import { Backdrop } from '@alfalab/core-components-backdrop/dist/esm';
9
9
  import { stackingOrder, Stack } from '@alfalab/core-components-stack/dist/esm';
10
- import { isScrolledToTop, isScrolledToBottom, handleContainer, hasScrollbar } from './utils.js';
10
+ import '@alfalab/core-components-global-store/dist/esm';
11
+ import { isScrolledToTop, isScrolledToBottom, handleContainer, restoreContainerStyles, hasScrollbar } from './utils.js';
11
12
 
12
13
  /*! *****************************************************************************
13
14
  Copyright (c) Microsoft Corporation.
@@ -36,7 +37,7 @@ var __assign = function () {
36
37
  return __assign.apply(this, arguments);
37
38
  };
38
39
 
39
- var styles = {"component":"base-modal__component_5xaig","wrapper":"base-modal__wrapper_5xaig","content":"base-modal__content_5xaig","hidden":"base-modal__hidden_5xaig","backdrop":"base-modal__backdrop_5xaig","appear":"base-modal__appear_5xaig","enter":"base-modal__enter_5xaig","appearActive":"base-modal__appearActive_5xaig","enterActive":"base-modal__enterActive_5xaig","exit":"base-modal__exit_5xaig","exitActive":"base-modal__exitActive_5xaig","exitDone":"base-modal__exitDone_5xaig"};
40
+ var styles = {"component":"base-modal__component_rp8e5","wrapper":"base-modal__wrapper_rp8e5","content":"base-modal__content_rp8e5","hidden":"base-modal__hidden_rp8e5","backdrop":"base-modal__backdrop_rp8e5","appear":"base-modal__appear_rp8e5","enter":"base-modal__enter_rp8e5","appearActive":"base-modal__appearActive_rp8e5","enterActive":"base-modal__enterActive_rp8e5","exit":"base-modal__exit_rp8e5","exitActive":"base-modal__exitActive_rp8e5","exitDone":"base-modal__exitDone_rp8e5"};
40
41
  require('./index.css')
41
42
 
42
43
  var BaseModalContext = React.createContext({
@@ -62,7 +63,7 @@ var BaseModal = forwardRef(function (_a, ref) {
62
63
  var wrapperRef = useRef(null);
63
64
  var scrollableNodeRef = useRef(null);
64
65
  var contentNodeRef = useRef(null);
65
- var restoreContainerStyles = useRef(null);
66
+ var restoreContainerStylesRef = useRef(null);
66
67
  var checkToHasScrollBar = function () {
67
68
  if (scrollableNodeRef.current) {
68
69
  var scrollExists = hasScrollbar(scrollableNodeRef.current);
@@ -71,6 +72,9 @@ var BaseModal = forwardRef(function (_a, ref) {
71
72
  }
72
73
  };
73
74
  var shouldRender = keepMounted || open || !exited;
75
+ var getContainer = useCallback(function () {
76
+ return (container ? container() : document.body);
77
+ }, [container]);
74
78
  var resizeObserver = useMemo(function () { return new ResizeObserver(checkToHasScrollBar); }, []);
75
79
  var addResizeHandle = useCallback(function () {
76
80
  if (scrollableNodeRef.current)
@@ -113,7 +117,7 @@ var BaseModal = forwardRef(function (_a, ref) {
113
117
  return null;
114
118
  }, [onBackdropClick, onClose, onEscapeKeyDown]);
115
119
  var handleBackdropClick = function (event) {
116
- if (!disableBackdropClick) {
120
+ if (!disableBackdropClick && event.target === wrapperRef.current) {
117
121
  handleClose(event, 'backdropClick');
118
122
  }
119
123
  };
@@ -162,27 +166,29 @@ var BaseModal = forwardRef(function (_a, ref) {
162
166
  }
163
167
  if (onUnmount)
164
168
  onUnmount();
165
- if (restoreContainerStyles.current) {
166
- restoreContainerStyles.current();
167
- restoreContainerStyles.current = null;
169
+ if (restoreContainerStylesRef.current) {
170
+ restoreContainerStylesRef.current();
168
171
  }
169
172
  }, [handleScroll, onUnmount, removeResizeHandle, transitionProps]);
170
173
  useEffect(function () {
171
174
  if (open) {
172
- restoreContainerStyles.current = handleContainer((container ? container() : document.body));
175
+ handleContainer(getContainer());
176
+ restoreContainerStylesRef.current = function () {
177
+ restoreContainerStylesRef.current = null;
178
+ restoreContainerStyles(getContainer());
179
+ };
173
180
  }
174
- // eslint-disable-next-line react-hooks/exhaustive-deps
175
- }, [open]);
181
+ }, [getContainer, open]);
176
182
  useEffect(function () {
177
183
  if (open)
178
184
  setExited(false);
179
185
  }, [open]);
180
186
  useEffect(function () {
181
187
  return function () {
182
- resizeObserver.disconnect();
183
- if (restoreContainerStyles.current) {
184
- restoreContainerStyles.current();
188
+ if (restoreContainerStylesRef.current) {
189
+ restoreContainerStylesRef.current();
185
190
  }
191
+ resizeObserver.disconnect();
186
192
  };
187
193
  // eslint-disable-next-line react-hooks/exhaustive-deps
188
194
  }, []);
@@ -212,12 +218,14 @@ var BaseModal = forwardRef(function (_a, ref) {
212
218
  return (React.createElement(Portal, { getPortalContainer: container },
213
219
  React.createElement(BaseModalContext.Provider, { value: contextValue },
214
220
  React.createElement(FocusLock, { autoFocus: !disableAutoFocus, disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus },
221
+ Backdrop$1 && (React.createElement(Backdrop$1, __assign({}, backdropProps, { className: cn(backdropProps.className, styles.backdrop), open: open, style: {
222
+ zIndex: computedZIndex,
223
+ } }))),
215
224
  React.createElement("div", { role: 'dialog', className: cn(styles.wrapper, wrapperClassName, (_a = {},
216
225
  _a[styles.hidden] = !open && exited,
217
- _a)), ref: mergeRefs([ref, wrapperRef]), onKeyDown: handleKeyDown, tabIndex: -1, "data-test-id": dataTestId, style: {
226
+ _a)), ref: mergeRefs([ref, wrapperRef]), onKeyDown: handleKeyDown, onClick: handleBackdropClick, tabIndex: -1, "data-test-id": dataTestId, style: {
218
227
  zIndex: computedZIndex,
219
228
  } },
220
- Backdrop$1 && (React.createElement(Backdrop$1, __assign({}, backdropProps, { className: cn(backdropProps.className, styles.backdrop), open: open, onClick: handleBackdropClick }))),
221
229
  React.createElement(CSSTransition, __assign({ appear: true, timeout: 200, classNames: styles }, transitionProps, { in: open, onEntered: handleEntered, onExited: handleExited }),
222
230
  React.createElement("div", { className: cn(styles.component, className), ref: componentRef },
223
231
  React.createElement("div", { className: cn(styles.content, contentClassName) }, children))))))));
@@ -1,4 +1,4 @@
1
- /* hash: 5xaig */
1
+ /* hash: 1pbe4 */
2
2
  :root {
3
3
  --color-light-bg-primary: #fff;
4
4
  }
@@ -10,14 +10,14 @@
10
10
 
11
11
  /* Hard up */
12
12
  }
13
- .base-modal__component_5xaig {
13
+ .base-modal__component_rp8e5 {
14
14
  position: relative;
15
15
  box-sizing: border-box;
16
16
  background: var(--color-light-bg-primary);
17
17
  margin: auto;
18
18
  flex-shrink: 0;
19
19
  }
20
- .base-modal__wrapper_5xaig {
20
+ .base-modal__wrapper_rp8e5 {
21
21
  position: fixed;
22
22
  top: 0;
23
23
  left: 0;
@@ -30,33 +30,33 @@
30
30
  align-items: center;
31
31
  outline: 0;
32
32
  }
33
- .base-modal__content_5xaig {
33
+ .base-modal__content_rp8e5 {
34
34
  width: 100%;
35
35
  height: 100%;
36
36
  display: flex;
37
37
  flex-direction: column;
38
38
  flex: 1;
39
39
  }
40
- .base-modal__hidden_5xaig {
40
+ .base-modal__hidden_rp8e5 {
41
41
  display: none;
42
42
  }
43
- .base-modal__backdrop_5xaig {
44
- z-index: -1;
43
+ .base-modal__backdrop_rp8e5 {
44
+ z-index: 0;
45
45
  }
46
- .base-modal__appear_5xaig,
47
- .base-modal__enter_5xaig {
46
+ .base-modal__appear_rp8e5,
47
+ .base-modal__enter_rp8e5 {
48
48
  opacity: 0;
49
49
  }
50
- .base-modal__appearActive_5xaig,
51
- .base-modal__enterActive_5xaig {
50
+ .base-modal__appearActive_rp8e5,
51
+ .base-modal__enterActive_rp8e5 {
52
52
  opacity: 1;
53
53
  transition: opacity 200ms ease-in;
54
54
  }
55
- .base-modal__exit_5xaig {
55
+ .base-modal__exit_rp8e5 {
56
56
  opacity: 1;
57
57
  }
58
- .base-modal__exitActive_5xaig,
59
- .base-modal__exitDone_5xaig {
58
+ .base-modal__exitActive_rp8e5,
59
+ .base-modal__exitDone_rp8e5 {
60
60
  opacity: 0;
61
61
  transition: opacity 200ms ease-out;
62
62
  }
package/dist/esm/index.js CHANGED
@@ -8,4 +8,5 @@ import 'react-focus-lock';
8
8
  import '@alfalab/core-components-portal/dist/esm';
9
9
  import '@alfalab/core-components-backdrop/dist/esm';
10
10
  import '@alfalab/core-components-stack/dist/esm';
11
- export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop } from './utils.js';
11
+ import '@alfalab/core-components-global-store/dist/esm';
12
+ export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles } from './utils.js';
@@ -1,5 +1,6 @@
1
1
  declare function isScrolledToTop(target: HTMLElement): boolean;
2
2
  declare function isScrolledToBottom(target: HTMLElement): boolean;
3
3
  declare function hasScrollbar(target: HTMLElement): boolean;
4
- declare const handleContainer: (container: HTMLElement) => () => void;
5
- export { isScrolledToTop, isScrolledToBottom, hasScrollbar, handleContainer };
4
+ declare const restoreContainerStyles: (container: HTMLElement) => void;
5
+ declare const handleContainer: (container?: HTMLElement | undefined) => void;
6
+ export { isScrolledToTop, isScrolledToBottom, hasScrollbar, restoreContainerStyles, handleContainer };
package/dist/esm/utils.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { getModalStore } from '@alfalab/core-components-global-store/dist/esm';
2
+
1
3
  function isScrolledToTop(target) {
2
4
  return target.scrollTop <= 0;
3
5
  }
@@ -28,12 +30,40 @@ var isOverflowing = function (container) {
28
30
  var getPaddingRight = function (node) {
29
31
  return parseInt(window.getComputedStyle(node).paddingRight, 10) || 0;
30
32
  };
33
+ var restoreContainerStyles = function (container) {
34
+ var modalRestoreStyles = getModalStore().getRestoreStyles();
35
+ var index = modalRestoreStyles.findIndex(function (s) { return s.container === container; });
36
+ var existingStyles = modalRestoreStyles[index];
37
+ if (!existingStyles)
38
+ return;
39
+ existingStyles.modals -= 1;
40
+ if (existingStyles.modals <= 0) {
41
+ modalRestoreStyles.splice(index, 1);
42
+ existingStyles.styles.forEach(function (_a) {
43
+ var value = _a.value, el = _a.el, key = _a.key;
44
+ if (value) {
45
+ el.style.setProperty(key, value);
46
+ }
47
+ else {
48
+ el.style.removeProperty(key);
49
+ }
50
+ });
51
+ }
52
+ };
31
53
  var handleContainer = function (container) {
32
- var restoreStyle = [];
54
+ if (!container)
55
+ return;
56
+ var modalRestoreStyles = getModalStore().getRestoreStyles();
57
+ var existingStyles = modalRestoreStyles.find(function (s) { return s.container === container; });
58
+ if (existingStyles) {
59
+ existingStyles.modals += 1;
60
+ return;
61
+ }
62
+ var containerStyles = [];
33
63
  if (isOverflowing(container)) {
34
64
  // Вычисляет размер до применения `overflow hidden` для избежания скачков
35
65
  var scrollbarSize = getScrollbarSize();
36
- restoreStyle.push({
66
+ containerStyles.push({
37
67
  value: container.style.paddingRight,
38
68
  key: 'padding-right',
39
69
  el: container,
@@ -52,24 +82,18 @@ var handleContainer = function (container) {
52
82
  : container;
53
83
  // Блокируем скролл даже если отсутствует скроллбар
54
84
  if (scrollContainer.style.overflow !== 'hidden') {
55
- restoreStyle.push({
85
+ containerStyles.push({
56
86
  value: scrollContainer.style.overflow,
57
87
  key: 'overflow',
58
88
  el: scrollContainer,
59
89
  });
60
90
  }
61
91
  scrollContainer.style.overflow = 'hidden';
62
- return function () {
63
- restoreStyle.forEach(function (_a) {
64
- var value = _a.value, el = _a.el, key = _a.key;
65
- if (value) {
66
- el.style.setProperty(key, value);
67
- }
68
- else {
69
- el.style.removeProperty(key);
70
- }
71
- });
72
- };
92
+ modalRestoreStyles.push({
93
+ container: container,
94
+ modals: 1,
95
+ styles: containerStyles,
96
+ });
73
97
  };
74
98
 
75
- export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop };
99
+ export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles };
package/dist/index.css CHANGED
@@ -1,4 +1,4 @@
1
- /* hash: 5xaig */
1
+ /* hash: 1pbe4 */
2
2
  :root {
3
3
  --color-light-bg-primary: #fff;
4
4
  }
@@ -10,14 +10,14 @@
10
10
 
11
11
  /* Hard up */
12
12
  }
13
- .base-modal__component_5xaig {
13
+ .base-modal__component_rp8e5 {
14
14
  position: relative;
15
15
  box-sizing: border-box;
16
16
  background: var(--color-light-bg-primary);
17
17
  margin: auto;
18
18
  flex-shrink: 0;
19
19
  }
20
- .base-modal__wrapper_5xaig {
20
+ .base-modal__wrapper_rp8e5 {
21
21
  position: fixed;
22
22
  top: 0;
23
23
  left: 0;
@@ -30,33 +30,33 @@
30
30
  align-items: center;
31
31
  outline: 0;
32
32
  }
33
- .base-modal__content_5xaig {
33
+ .base-modal__content_rp8e5 {
34
34
  width: 100%;
35
35
  height: 100%;
36
36
  display: flex;
37
37
  flex-direction: column;
38
38
  flex: 1;
39
39
  }
40
- .base-modal__hidden_5xaig {
40
+ .base-modal__hidden_rp8e5 {
41
41
  display: none;
42
42
  }
43
- .base-modal__backdrop_5xaig {
44
- z-index: -1;
43
+ .base-modal__backdrop_rp8e5 {
44
+ z-index: 0;
45
45
  }
46
- .base-modal__appear_5xaig,
47
- .base-modal__enter_5xaig {
46
+ .base-modal__appear_rp8e5,
47
+ .base-modal__enter_rp8e5 {
48
48
  opacity: 0;
49
49
  }
50
- .base-modal__appearActive_5xaig,
51
- .base-modal__enterActive_5xaig {
50
+ .base-modal__appearActive_rp8e5,
51
+ .base-modal__enterActive_rp8e5 {
52
52
  opacity: 1;
53
53
  transition: opacity 200ms ease-in;
54
54
  }
55
- .base-modal__exit_5xaig {
55
+ .base-modal__exit_rp8e5 {
56
56
  opacity: 1;
57
57
  }
58
- .base-modal__exitActive_5xaig,
59
- .base-modal__exitDone_5xaig {
58
+ .base-modal__exitActive_rp8e5,
59
+ .base-modal__exitDone_rp8e5 {
60
60
  opacity: 0;
61
61
  transition: opacity 200ms ease-out;
62
62
  }
package/dist/index.js CHANGED
@@ -12,6 +12,7 @@ require('react-focus-lock');
12
12
  require('@alfalab/core-components-portal');
13
13
  require('@alfalab/core-components-backdrop');
14
14
  require('@alfalab/core-components-stack');
15
+ require('@alfalab/core-components-global-store');
15
16
  var utils = require('./utils.js');
16
17
 
17
18
 
@@ -22,3 +23,4 @@ exports.handleContainer = utils.handleContainer;
22
23
  exports.hasScrollbar = utils.hasScrollbar;
23
24
  exports.isScrolledToBottom = utils.isScrolledToBottom;
24
25
  exports.isScrolledToTop = utils.isScrolledToTop;
26
+ exports.restoreContainerStyles = utils.restoreContainerStyles;
@@ -1,4 +1,4 @@
1
- import React, { forwardRef, useState, useRef, useMemo, useCallback, useEffect } from 'react';
1
+ import React, { forwardRef, useState, useRef, useCallback, useMemo, useEffect } from 'react';
2
2
  import cn from 'classnames';
3
3
  import mergeRefs from 'react-merge-refs';
4
4
  import { ResizeObserver } from 'resize-observer';
@@ -7,9 +7,10 @@ import FocusLock from 'react-focus-lock';
7
7
  import { Portal } from '@alfalab/core-components-portal/dist/modern';
8
8
  import { Backdrop } from '@alfalab/core-components-backdrop/dist/modern';
9
9
  import { stackingOrder, Stack } from '@alfalab/core-components-stack/dist/modern';
10
- import { isScrolledToTop, isScrolledToBottom, handleContainer, hasScrollbar } from './utils.js';
10
+ import '@alfalab/core-components-global-store/dist/modern';
11
+ import { isScrolledToTop, isScrolledToBottom, handleContainer, restoreContainerStyles, hasScrollbar } from './utils.js';
11
12
 
12
- var styles = {"component":"base-modal__component_5xaig","wrapper":"base-modal__wrapper_5xaig","content":"base-modal__content_5xaig","hidden":"base-modal__hidden_5xaig","backdrop":"base-modal__backdrop_5xaig","appear":"base-modal__appear_5xaig","enter":"base-modal__enter_5xaig","appearActive":"base-modal__appearActive_5xaig","enterActive":"base-modal__enterActive_5xaig","exit":"base-modal__exit_5xaig","exitActive":"base-modal__exitActive_5xaig","exitDone":"base-modal__exitDone_5xaig"};
13
+ var styles = {"component":"base-modal__component_rp8e5","wrapper":"base-modal__wrapper_rp8e5","content":"base-modal__content_rp8e5","hidden":"base-modal__hidden_rp8e5","backdrop":"base-modal__backdrop_rp8e5","appear":"base-modal__appear_rp8e5","enter":"base-modal__enter_rp8e5","appearActive":"base-modal__appearActive_rp8e5","enterActive":"base-modal__enterActive_rp8e5","exit":"base-modal__exit_rp8e5","exitActive":"base-modal__exitActive_rp8e5","exitDone":"base-modal__exitDone_rp8e5"};
13
14
  require('./index.css')
14
15
 
15
16
  /* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
@@ -35,7 +36,7 @@ const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrap
35
36
  const wrapperRef = useRef(null);
36
37
  const scrollableNodeRef = useRef(null);
37
38
  const contentNodeRef = useRef(null);
38
- const restoreContainerStyles = useRef(null);
39
+ const restoreContainerStylesRef = useRef(null);
39
40
  const checkToHasScrollBar = () => {
40
41
  if (scrollableNodeRef.current) {
41
42
  const scrollExists = hasScrollbar(scrollableNodeRef.current);
@@ -44,6 +45,9 @@ const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrap
44
45
  }
45
46
  };
46
47
  const shouldRender = keepMounted || open || !exited;
48
+ const getContainer = useCallback(() => {
49
+ return (container ? container() : document.body);
50
+ }, [container]);
47
51
  const resizeObserver = useMemo(() => new ResizeObserver(checkToHasScrollBar), []);
48
52
  const addResizeHandle = useCallback(() => {
49
53
  if (scrollableNodeRef.current)
@@ -86,7 +90,7 @@ const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrap
86
90
  return null;
87
91
  }, [onBackdropClick, onClose, onEscapeKeyDown]);
88
92
  const handleBackdropClick = (event) => {
89
- if (!disableBackdropClick) {
93
+ if (!disableBackdropClick && event.target === wrapperRef.current) {
90
94
  handleClose(event, 'backdropClick');
91
95
  }
92
96
  };
@@ -135,27 +139,29 @@ const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrap
135
139
  }
136
140
  if (onUnmount)
137
141
  onUnmount();
138
- if (restoreContainerStyles.current) {
139
- restoreContainerStyles.current();
140
- restoreContainerStyles.current = null;
142
+ if (restoreContainerStylesRef.current) {
143
+ restoreContainerStylesRef.current();
141
144
  }
142
145
  }, [handleScroll, onUnmount, removeResizeHandle, transitionProps]);
143
146
  useEffect(() => {
144
147
  if (open) {
145
- restoreContainerStyles.current = handleContainer((container ? container() : document.body));
148
+ handleContainer(getContainer());
149
+ restoreContainerStylesRef.current = () => {
150
+ restoreContainerStylesRef.current = null;
151
+ restoreContainerStyles(getContainer());
152
+ };
146
153
  }
147
- // eslint-disable-next-line react-hooks/exhaustive-deps
148
- }, [open]);
154
+ }, [getContainer, open]);
149
155
  useEffect(() => {
150
156
  if (open)
151
157
  setExited(false);
152
158
  }, [open]);
153
159
  useEffect(() => {
154
160
  return () => {
155
- resizeObserver.disconnect();
156
- if (restoreContainerStyles.current) {
157
- restoreContainerStyles.current();
161
+ if (restoreContainerStylesRef.current) {
162
+ restoreContainerStylesRef.current();
158
163
  }
164
+ resizeObserver.disconnect();
159
165
  };
160
166
  // eslint-disable-next-line react-hooks/exhaustive-deps
161
167
  }, []);
@@ -183,12 +189,14 @@ const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrap
183
189
  return (React.createElement(Stack, { value: zIndex }, computedZIndex => (React.createElement(Portal, { getPortalContainer: container },
184
190
  React.createElement(BaseModalContext.Provider, { value: contextValue },
185
191
  React.createElement(FocusLock, { autoFocus: !disableAutoFocus, disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus },
192
+ Backdrop$1 && (React.createElement(Backdrop$1, Object.assign({}, backdropProps, { className: cn(backdropProps.className, styles.backdrop), open: open, style: {
193
+ zIndex: computedZIndex,
194
+ } }))),
186
195
  React.createElement("div", { role: 'dialog', className: cn(styles.wrapper, wrapperClassName, {
187
196
  [styles.hidden]: !open && exited,
188
- }), ref: mergeRefs([ref, wrapperRef]), onKeyDown: handleKeyDown, tabIndex: -1, "data-test-id": dataTestId, style: {
197
+ }), ref: mergeRefs([ref, wrapperRef]), onKeyDown: handleKeyDown, onClick: handleBackdropClick, tabIndex: -1, "data-test-id": dataTestId, style: {
189
198
  zIndex: computedZIndex,
190
199
  } },
191
- Backdrop$1 && (React.createElement(Backdrop$1, Object.assign({}, backdropProps, { className: cn(backdropProps.className, styles.backdrop), open: open, onClick: handleBackdropClick }))),
192
200
  React.createElement(CSSTransition, Object.assign({ appear: true, timeout: 200, classNames: styles }, transitionProps, { in: open, onEntered: handleEntered, onExited: handleExited }),
193
201
  React.createElement("div", { className: cn(styles.component, className), ref: componentRef },
194
202
  React.createElement("div", { className: cn(styles.content, contentClassName) }, children))))))))));
@@ -1,4 +1,4 @@
1
- /* hash: 5xaig */
1
+ /* hash: 1pbe4 */
2
2
  :root {
3
3
  --color-light-bg-primary: #fff;
4
4
  }
@@ -10,14 +10,14 @@
10
10
 
11
11
  /* Hard up */
12
12
  }
13
- .base-modal__component_5xaig {
13
+ .base-modal__component_rp8e5 {
14
14
  position: relative;
15
15
  box-sizing: border-box;
16
16
  background: var(--color-light-bg-primary);
17
17
  margin: auto;
18
18
  flex-shrink: 0;
19
19
  }
20
- .base-modal__wrapper_5xaig {
20
+ .base-modal__wrapper_rp8e5 {
21
21
  position: fixed;
22
22
  top: 0;
23
23
  left: 0;
@@ -30,33 +30,33 @@
30
30
  align-items: center;
31
31
  outline: 0;
32
32
  }
33
- .base-modal__content_5xaig {
33
+ .base-modal__content_rp8e5 {
34
34
  width: 100%;
35
35
  height: 100%;
36
36
  display: flex;
37
37
  flex-direction: column;
38
38
  flex: 1;
39
39
  }
40
- .base-modal__hidden_5xaig {
40
+ .base-modal__hidden_rp8e5 {
41
41
  display: none;
42
42
  }
43
- .base-modal__backdrop_5xaig {
44
- z-index: -1;
43
+ .base-modal__backdrop_rp8e5 {
44
+ z-index: 0;
45
45
  }
46
- .base-modal__appear_5xaig,
47
- .base-modal__enter_5xaig {
46
+ .base-modal__appear_rp8e5,
47
+ .base-modal__enter_rp8e5 {
48
48
  opacity: 0;
49
49
  }
50
- .base-modal__appearActive_5xaig,
51
- .base-modal__enterActive_5xaig {
50
+ .base-modal__appearActive_rp8e5,
51
+ .base-modal__enterActive_rp8e5 {
52
52
  opacity: 1;
53
53
  transition: opacity 200ms ease-in;
54
54
  }
55
- .base-modal__exit_5xaig {
55
+ .base-modal__exit_rp8e5 {
56
56
  opacity: 1;
57
57
  }
58
- .base-modal__exitActive_5xaig,
59
- .base-modal__exitDone_5xaig {
58
+ .base-modal__exitActive_rp8e5,
59
+ .base-modal__exitDone_rp8e5 {
60
60
  opacity: 0;
61
61
  transition: opacity 200ms ease-out;
62
62
  }
@@ -7,5 +7,6 @@ import 'react-focus-lock';
7
7
  import '@alfalab/core-components-portal/dist/modern';
8
8
  import '@alfalab/core-components-backdrop/dist/modern';
9
9
  import '@alfalab/core-components-stack/dist/modern';
10
- export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop } from './utils.js';
10
+ import '@alfalab/core-components-global-store/dist/modern';
11
+ export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles } from './utils.js';
11
12
  export { BaseModal, BaseModalContext } from './Component.js';
@@ -1,5 +1,6 @@
1
1
  declare function isScrolledToTop(target: HTMLElement): boolean;
2
2
  declare function isScrolledToBottom(target: HTMLElement): boolean;
3
3
  declare function hasScrollbar(target: HTMLElement): boolean;
4
- declare const handleContainer: (container: HTMLElement) => () => void;
5
- export { isScrolledToTop, isScrolledToBottom, hasScrollbar, handleContainer };
4
+ declare const restoreContainerStyles: (container: HTMLElement) => void;
5
+ declare const handleContainer: (container?: HTMLElement | undefined) => void;
6
+ export { isScrolledToTop, isScrolledToBottom, hasScrollbar, restoreContainerStyles, handleContainer };
@@ -1,3 +1,5 @@
1
+ import { getModalStore } from '@alfalab/core-components-global-store/dist/modern';
2
+
1
3
  function isScrolledToTop(target) {
2
4
  return target.scrollTop <= 0;
3
5
  }
@@ -28,12 +30,39 @@ const isOverflowing = (container) => {
28
30
  const getPaddingRight = (node) => {
29
31
  return parseInt(window.getComputedStyle(node).paddingRight, 10) || 0;
30
32
  };
33
+ const restoreContainerStyles = (container) => {
34
+ const modalRestoreStyles = getModalStore().getRestoreStyles();
35
+ const index = modalRestoreStyles.findIndex(s => s.container === container);
36
+ const existingStyles = modalRestoreStyles[index];
37
+ if (!existingStyles)
38
+ return;
39
+ existingStyles.modals -= 1;
40
+ if (existingStyles.modals <= 0) {
41
+ modalRestoreStyles.splice(index, 1);
42
+ existingStyles.styles.forEach(({ value, el, key }) => {
43
+ if (value) {
44
+ el.style.setProperty(key, value);
45
+ }
46
+ else {
47
+ el.style.removeProperty(key);
48
+ }
49
+ });
50
+ }
51
+ };
31
52
  const handleContainer = (container) => {
32
- const restoreStyle = [];
53
+ if (!container)
54
+ return;
55
+ const modalRestoreStyles = getModalStore().getRestoreStyles();
56
+ const existingStyles = modalRestoreStyles.find(s => s.container === container);
57
+ if (existingStyles) {
58
+ existingStyles.modals += 1;
59
+ return;
60
+ }
61
+ const containerStyles = [];
33
62
  if (isOverflowing(container)) {
34
63
  // Вычисляет размер до применения `overflow hidden` для избежания скачков
35
64
  const scrollbarSize = getScrollbarSize();
36
- restoreStyle.push({
65
+ containerStyles.push({
37
66
  value: container.style.paddingRight,
38
67
  key: 'padding-right',
39
68
  el: container,
@@ -52,23 +81,18 @@ const handleContainer = (container) => {
52
81
  : container;
53
82
  // Блокируем скролл даже если отсутствует скроллбар
54
83
  if (scrollContainer.style.overflow !== 'hidden') {
55
- restoreStyle.push({
84
+ containerStyles.push({
56
85
  value: scrollContainer.style.overflow,
57
86
  key: 'overflow',
58
87
  el: scrollContainer,
59
88
  });
60
89
  }
61
90
  scrollContainer.style.overflow = 'hidden';
62
- return () => {
63
- restoreStyle.forEach(({ value, el, key }) => {
64
- if (value) {
65
- el.style.setProperty(key, value);
66
- }
67
- else {
68
- el.style.removeProperty(key);
69
- }
70
- });
71
- };
91
+ modalRestoreStyles.push({
92
+ container,
93
+ modals: 1,
94
+ styles: containerStyles,
95
+ });
72
96
  };
73
97
 
74
- export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop };
98
+ export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles };
package/dist/utils.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  declare function isScrolledToTop(target: HTMLElement): boolean;
2
2
  declare function isScrolledToBottom(target: HTMLElement): boolean;
3
3
  declare function hasScrollbar(target: HTMLElement): boolean;
4
- declare const handleContainer: (container: HTMLElement) => () => void;
5
- export { isScrolledToTop, isScrolledToBottom, hasScrollbar, handleContainer };
4
+ declare const restoreContainerStyles: (container: HTMLElement) => void;
5
+ declare const handleContainer: (container?: HTMLElement | undefined) => void;
6
+ export { isScrolledToTop, isScrolledToBottom, hasScrollbar, restoreContainerStyles, handleContainer };
package/dist/utils.js CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ var coreComponentsGlobalStore = require('@alfalab/core-components-global-store');
6
+
5
7
  function isScrolledToTop(target) {
6
8
  return target.scrollTop <= 0;
7
9
  }
@@ -32,12 +34,40 @@ var isOverflowing = function (container) {
32
34
  var getPaddingRight = function (node) {
33
35
  return parseInt(window.getComputedStyle(node).paddingRight, 10) || 0;
34
36
  };
37
+ var restoreContainerStyles = function (container) {
38
+ var modalRestoreStyles = coreComponentsGlobalStore.getModalStore().getRestoreStyles();
39
+ var index = modalRestoreStyles.findIndex(function (s) { return s.container === container; });
40
+ var existingStyles = modalRestoreStyles[index];
41
+ if (!existingStyles)
42
+ return;
43
+ existingStyles.modals -= 1;
44
+ if (existingStyles.modals <= 0) {
45
+ modalRestoreStyles.splice(index, 1);
46
+ existingStyles.styles.forEach(function (_a) {
47
+ var value = _a.value, el = _a.el, key = _a.key;
48
+ if (value) {
49
+ el.style.setProperty(key, value);
50
+ }
51
+ else {
52
+ el.style.removeProperty(key);
53
+ }
54
+ });
55
+ }
56
+ };
35
57
  var handleContainer = function (container) {
36
- var restoreStyle = [];
58
+ if (!container)
59
+ return;
60
+ var modalRestoreStyles = coreComponentsGlobalStore.getModalStore().getRestoreStyles();
61
+ var existingStyles = modalRestoreStyles.find(function (s) { return s.container === container; });
62
+ if (existingStyles) {
63
+ existingStyles.modals += 1;
64
+ return;
65
+ }
66
+ var containerStyles = [];
37
67
  if (isOverflowing(container)) {
38
68
  // Вычисляет размер до применения `overflow hidden` для избежания скачков
39
69
  var scrollbarSize = getScrollbarSize();
40
- restoreStyle.push({
70
+ containerStyles.push({
41
71
  value: container.style.paddingRight,
42
72
  key: 'padding-right',
43
73
  el: container,
@@ -56,27 +86,22 @@ var handleContainer = function (container) {
56
86
  : container;
57
87
  // Блокируем скролл даже если отсутствует скроллбар
58
88
  if (scrollContainer.style.overflow !== 'hidden') {
59
- restoreStyle.push({
89
+ containerStyles.push({
60
90
  value: scrollContainer.style.overflow,
61
91
  key: 'overflow',
62
92
  el: scrollContainer,
63
93
  });
64
94
  }
65
95
  scrollContainer.style.overflow = 'hidden';
66
- return function () {
67
- restoreStyle.forEach(function (_a) {
68
- var value = _a.value, el = _a.el, key = _a.key;
69
- if (value) {
70
- el.style.setProperty(key, value);
71
- }
72
- else {
73
- el.style.removeProperty(key);
74
- }
75
- });
76
- };
96
+ modalRestoreStyles.push({
97
+ container: container,
98
+ modals: 1,
99
+ styles: containerStyles,
100
+ });
77
101
  };
78
102
 
79
103
  exports.handleContainer = handleContainer;
80
104
  exports.hasScrollbar = hasScrollbar;
81
105
  exports.isScrolledToBottom = isScrolledToBottom;
82
106
  exports.isScrolledToTop = isScrolledToTop;
107
+ exports.restoreContainerStyles = restoreContainerStyles;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfalab/core-components-base-modal",
3
- "version": "2.1.1",
3
+ "version": "3.1.0",
4
4
  "description": "BaseModal component",
5
5
  "keywords": [],
6
6
  "license": "MIT",
@@ -15,9 +15,10 @@
15
15
  "access": "public"
16
16
  },
17
17
  "dependencies": {
18
- "@alfalab/core-components-backdrop": "^1.1.2",
19
- "@alfalab/core-components-portal": "^1.4.6",
20
- "@alfalab/core-components-stack": "^2.0.0",
18
+ "@alfalab/core-components-backdrop": "^2.0.1",
19
+ "@alfalab/core-components-global-store": "^1.1.0",
20
+ "@alfalab/core-components-portal": "^2.0.1",
21
+ "@alfalab/core-components-stack": "^3.0.1",
21
22
  "classnames": "^2.2.6",
22
23
  "react-focus-lock": "^2.5.0",
23
24
  "react-merge-refs": "^1.1.0",
@@ -30,5 +31,5 @@
30
31
  "peerDependencies": {
31
32
  "react": "^16.9.0 || ^17.0.1"
32
33
  },
33
- "gitHead": "3112f69ce8a9753de0a31708c19f671ac2ff4734"
34
+ "gitHead": "d35b2d43cbc90ecb7665c682a2de13733bc03eb0"
34
35
  }