@alfalab/core-components-base-modal 4.1.3 → 4.2.1

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.
Files changed (33) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/{dist/Component.d.ts → Component.d.ts} +5 -0
  3. package/{dist/Component.js → Component.js} +33 -23
  4. package/{dist/modern → cssm}/Component.d.ts +5 -0
  5. package/{dist/cssm → cssm}/Component.js +36 -26
  6. package/{dist/cssm → cssm}/index.d.ts +0 -0
  7. package/{dist/cssm → cssm}/index.js +5 -4
  8. package/{dist/cssm → cssm}/index.module.css +0 -0
  9. package/{dist/cssm → cssm}/utils.d.ts +2 -1
  10. package/{dist/cssm → cssm}/utils.js +20 -13
  11. package/{dist/cssm → esm}/Component.d.ts +5 -0
  12. package/{dist/esm → esm}/Component.js +38 -28
  13. package/{dist/modern → esm}/index.css +13 -13
  14. package/{dist/esm → esm}/index.d.ts +0 -0
  15. package/esm/index.js +12 -0
  16. package/{dist/esm → esm}/utils.d.ts +2 -1
  17. package/{dist/esm → esm}/utils.js +20 -14
  18. package/{dist/esm/index.css → index.css} +13 -13
  19. package/{dist/index.d.ts → index.d.ts} +0 -0
  20. package/{dist/index.js → index.js} +1 -0
  21. package/{dist/esm → modern}/Component.d.ts +5 -0
  22. package/{dist/modern → modern}/Component.js +31 -22
  23. package/{dist → modern}/index.css +13 -13
  24. package/{dist/modern → modern}/index.d.ts +0 -0
  25. package/modern/index.js +12 -0
  26. package/{dist/modern → modern}/utils.d.ts +2 -1
  27. package/{dist/modern → modern}/utils.js +20 -14
  28. package/package.json +10 -13
  29. package/{dist/send-stats.js → send-stats.js} +0 -0
  30. package/{dist/utils.d.ts → utils.d.ts} +2 -1
  31. package/{dist/utils.js → utils.js} +19 -12
  32. package/dist/esm/index.js +0 -12
  33. package/dist/modern/index.js +0 -12
package/CHANGELOG.md CHANGED
@@ -3,6 +3,47 @@
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
+ ## [4.2.1](https://github.com/core-ds/core-components/compare/@alfalab/core-components-base-modal@4.2.0...@alfalab/core-components-base-modal@4.2.1) (2022-07-18)
7
+
8
+ **Note:** Version bump only for package @alfalab/core-components-base-modal
9
+
10
+
11
+
12
+
13
+
14
+ # [4.2.0](https://github.com/core-ds/core-components/compare/@alfalab/core-components-base-modal@4.1.5...@alfalab/core-components-base-modal@4.2.0) (2022-07-15)
15
+
16
+
17
+ ### Features
18
+
19
+ * **bottom-sheet:** add props for disable blocking scroll and modal wrapper classname ([#147](https://github.com/core-ds/core-components/issues/147)) ([a873c20](https://github.com/core-ds/core-components/commit/a873c2035d4885c1b8e5ffae02ce75c4826d1e71))
20
+
21
+
22
+
23
+
24
+
25
+ ## [4.1.5](https://github.com/core-ds/core-components/compare/@alfalab/core-components-base-modal@4.1.4...@alfalab/core-components-base-modal@4.1.5) (2022-07-15)
26
+
27
+
28
+ ### Bug Fixes
29
+
30
+ * bump packages version ([#153](https://github.com/core-ds/core-components/issues/153)) ([fd3e082](https://github.com/core-ds/core-components/commit/fd3e08205672129cdce04e1000c673f2cd9c10da))
31
+
32
+
33
+
34
+
35
+
36
+ ## [4.1.4](https://github.com/core-ds/core-components/compare/@alfalab/core-components-base-modal@4.1.3...@alfalab/core-components-base-modal@4.1.4) (2022-07-14)
37
+
38
+
39
+ ### Bug Fixes
40
+
41
+ * **base-modal:** fix overflow hidden bug ([#128](https://github.com/core-ds/core-components/issues/128)) ([eb953b9](https://github.com/core-ds/core-components/commit/eb953b9866dae8c28bf8265d6884cdf1544ae63c))
42
+
43
+
44
+
45
+
46
+
6
47
  ## [4.1.3](https://github.com/core-ds/core-components/compare/@alfalab/core-components-base-modal@4.1.2...@alfalab/core-components-base-modal@4.1.3) (2022-07-11)
7
48
 
8
49
 
@@ -251,4 +292,5 @@ remove z-index, add stack component
251
292
 
252
293
  ### Features
253
294
 
295
+
254
296
  * **backdrop:** add component ([948a6c2](https://github.com/core-ds/core-components/commit/948a6c2fb5ec58edb2d087691ce4713d75da6e35))
@@ -49,6 +49,11 @@ type BaseModalProps = {
49
49
  * @default false
50
50
  */
51
51
  disableBackdropClick?: boolean;
52
+ /**
53
+ * Отключает блокировку скролла при открытии модального окна
54
+ * @default false
55
+ */
56
+ disableBlockingScroll?: boolean;
52
57
  /**
53
58
  * Содержимое модалки всегда в DOM
54
59
  * @default false
@@ -48,7 +48,7 @@ var __assign = function () {
48
48
  return __assign.apply(this, arguments);
49
49
  };
50
50
 
51
- var styles = {"component":"base-modal__component_12xfo","wrapper":"base-modal__wrapper_12xfo","content":"base-modal__content_12xfo","hidden":"base-modal__hidden_12xfo","backdrop":"base-modal__backdrop_12xfo","appear":"base-modal__appear_12xfo","enter":"base-modal__enter_12xfo","appearActive":"base-modal__appearActive_12xfo","enterActive":"base-modal__enterActive_12xfo","exit":"base-modal__exit_12xfo","exitActive":"base-modal__exitActive_12xfo","exitDone":"base-modal__exitDone_12xfo"};
51
+ var styles = {"component":"base-modal__component_1xxjn","wrapper":"base-modal__wrapper_1xxjn","content":"base-modal__content_1xxjn","hidden":"base-modal__hidden_1xxjn","backdrop":"base-modal__backdrop_1xxjn","appear":"base-modal__appear_1xxjn","enter":"base-modal__enter_1xxjn","appearActive":"base-modal__appearActive_1xxjn","enterActive":"base-modal__enterActive_1xxjn","exit":"base-modal__exit_1xxjn","exitActive":"base-modal__exitActive_1xxjn","exitDone":"base-modal__exitDone_1xxjn"};
52
52
  require('./index.css')
53
53
 
54
54
  var BaseModalContext = React__default['default'].createContext({
@@ -65,14 +65,14 @@ var BaseModalContext = React__default['default'].createContext({
65
65
  onClose: function () { return null; },
66
66
  });
67
67
  var BaseModal = React.forwardRef(function (_a, ref) {
68
- var open = _a.open, container = _a.container, children = _a.children, _b = _a.scrollHandler, scrollHandler = _b === void 0 ? 'wrapper' : _b, _c = _a.Backdrop, Backdrop = _c === void 0 ? coreComponentsBackdrop.Backdrop : _c, _d = _a.backdropProps, backdropProps = _d === void 0 ? {} : _d, _e = _a.transitionProps, transitionProps = _e === void 0 ? {} : _e, disableBackdropClick = _a.disableBackdropClick, _f = _a.disableAutoFocus, disableAutoFocus = _f === void 0 ? false : _f, _g = _a.disableFocusLock, disableFocusLock = _g === void 0 ? false : _g, _h = _a.disableEscapeKeyDown, disableEscapeKeyDown = _h === void 0 ? false : _h, _j = _a.disableRestoreFocus, disableRestoreFocus = _j === void 0 ? false : _j, _k = _a.keepMounted, keepMounted = _k === void 0 ? false : _k, className = _a.className, contentClassName = _a.contentClassName, wrapperClassName = _a.wrapperClassName, onBackdropClick = _a.onBackdropClick, onClose = _a.onClose, onEscapeKeyDown = _a.onEscapeKeyDown, onMount = _a.onMount, onUnmount = _a.onUnmount, dataTestId = _a.dataTestId, _l = _a.zIndex, zIndex = _l === void 0 ? coreComponentsStack.stackingOrder.MODAL : _l, _m = _a.componentRef, componentRef = _m === void 0 ? null : _m;
69
- var _o = React.useState(!open), exited = _o[0], setExited = _o[1];
70
- var _p = React.useState(false), hasScroll = _p[0], setHasScroll = _p[1];
71
- var _q = React.useState(false), hasHeader = _q[0], setHasHeader = _q[1];
72
- var _r = React.useState(false), hasFooter = _r[0], setHasFooter = _r[1];
73
- var _s = React.useState(false), headerHighlighted = _s[0], setHeaderHighlighted = _s[1];
74
- var _t = React.useState(false), footerHighlighted = _t[0], setFooterHighlighted = _t[1];
75
- var _u = React.useState(0), headerOffset = _u[0], setHeaderOffset = _u[1];
68
+ var open = _a.open, container = _a.container, children = _a.children, _b = _a.scrollHandler, scrollHandler = _b === void 0 ? 'wrapper' : _b, _c = _a.Backdrop, Backdrop = _c === void 0 ? coreComponentsBackdrop.Backdrop : _c, _d = _a.backdropProps, backdropProps = _d === void 0 ? {} : _d, _e = _a.transitionProps, transitionProps = _e === void 0 ? {} : _e, disableBackdropClick = _a.disableBackdropClick, _f = _a.disableAutoFocus, disableAutoFocus = _f === void 0 ? false : _f, _g = _a.disableFocusLock, disableFocusLock = _g === void 0 ? false : _g, _h = _a.disableEscapeKeyDown, disableEscapeKeyDown = _h === void 0 ? false : _h, _j = _a.disableRestoreFocus, disableRestoreFocus = _j === void 0 ? false : _j, _k = _a.disableBlockingScroll, disableBlockingScroll = _k === void 0 ? false : _k, _l = _a.keepMounted, keepMounted = _l === void 0 ? false : _l, className = _a.className, contentClassName = _a.contentClassName, wrapperClassName = _a.wrapperClassName, onBackdropClick = _a.onBackdropClick, onClose = _a.onClose, onEscapeKeyDown = _a.onEscapeKeyDown, onMount = _a.onMount, onUnmount = _a.onUnmount, dataTestId = _a.dataTestId, _m = _a.zIndex, zIndex = _m === void 0 ? coreComponentsStack.stackingOrder.MODAL : _m, _o = _a.componentRef, componentRef = _o === void 0 ? null : _o;
69
+ var _p = React.useState(null), exited = _p[0], setExited = _p[1];
70
+ var _q = React.useState(false), hasScroll = _q[0], setHasScroll = _q[1];
71
+ var _r = React.useState(false), hasHeader = _r[0], setHasHeader = _r[1];
72
+ var _s = React.useState(false), hasFooter = _s[0], setHasFooter = _s[1];
73
+ var _t = React.useState(false), headerHighlighted = _t[0], setHeaderHighlighted = _t[1];
74
+ var _u = React.useState(false), footerHighlighted = _u[0], setFooterHighlighted = _u[1];
75
+ var _v = React.useState(0), headerOffset = _v[0], setHeaderOffset = _v[1];
76
76
  var componentNodeRef = React.useRef(null);
77
77
  var wrapperRef = React.useRef(null);
78
78
  var scrollableNodeRef = React.useRef(null);
@@ -87,7 +87,8 @@ var BaseModal = React.forwardRef(function (_a, ref) {
87
87
  setHasScroll(scrollExists);
88
88
  }
89
89
  };
90
- var shouldRender = keepMounted || open || !exited;
90
+ var isExited = exited || exited === null;
91
+ var shouldRender = keepMounted || open || !isExited;
91
92
  var getContainer = React.useCallback(function () {
92
93
  return (container ? container() : document.body);
93
94
  }, [container]);
@@ -137,7 +138,15 @@ var BaseModal = React.forwardRef(function (_a, ref) {
137
138
  return null;
138
139
  }, [onBackdropClick, onClose, onEscapeKeyDown]);
139
140
  var handleBackdropMouseDown = function (event) {
140
- if (!disableBackdropClick) {
141
+ var _a;
142
+ var clickedOnScrollbar = false;
143
+ var clientWidth = (_a = event.target) === null || _a === void 0 ? void 0 : _a.clientWidth;
144
+ if (event.clientX && clientWidth) {
145
+ // Устанавливаем смещение для абсолютно спозиционированного скроллбара в OSX в 17px.
146
+ var offset = utils.getScrollbarSize() === 0 ? 17 : 0;
147
+ clickedOnScrollbar = event.clientX + offset > clientWidth;
148
+ }
149
+ if (!disableBackdropClick && !clickedOnScrollbar) {
141
150
  mouseDownTarget.current = event.target;
142
151
  }
143
152
  };
@@ -147,6 +156,7 @@ var BaseModal = React.forwardRef(function (_a, ref) {
147
156
  mouseDownTarget.current === wrapperRef.current) {
148
157
  handleClose(event, 'backdropClick');
149
158
  }
159
+ mouseDownTarget.current = undefined;
150
160
  };
151
161
  var handleKeyDown = React.useCallback(function (event) {
152
162
  /*
@@ -198,18 +208,18 @@ var BaseModal = React.forwardRef(function (_a, ref) {
198
208
  }
199
209
  }, [handleScroll, onUnmount, removeResizeHandle, transitionProps]);
200
210
  React.useEffect(function () {
201
- if (open) {
202
- utils.handleContainer(getContainer());
203
- restoreContainerStylesRef.current = function () {
204
- restoreContainerStylesRef.current = null;
205
- utils.restoreContainerStyles(getContainer());
206
- };
207
- }
208
- }, [getContainer, open]);
209
- React.useEffect(function () {
210
- if (open)
211
+ if (open && isExited) {
212
+ if (!disableBlockingScroll) {
213
+ var el_1 = getContainer();
214
+ utils.handleContainer(el_1);
215
+ restoreContainerStylesRef.current = function () {
216
+ restoreContainerStylesRef.current = null;
217
+ utils.restoreContainerStyles(el_1);
218
+ };
219
+ }
211
220
  setExited(false);
212
- }, [open]);
221
+ }
222
+ }, [getContainer, open, disableBlockingScroll, isExited]);
213
223
  React.useEffect(function () {
214
224
  var ResizeObserver = window.ResizeObserver || resizeObserver.ResizeObserver;
215
225
  resizeObserverRef.current = new ResizeObserver(checkToHasScrollBar);
@@ -256,7 +266,7 @@ var BaseModal = React.forwardRef(function (_a, ref) {
256
266
  zIndex: computedZIndex,
257
267
  } }))),
258
268
  React__default['default'].createElement("div", { role: 'dialog', className: cn__default['default'](styles.wrapper, wrapperClassName, (_a = {},
259
- _a[styles.hidden] = !open && exited,
269
+ _a[styles.hidden] = !open && isExited,
260
270
  _a)), ref: mergeRefs__default['default']([ref, wrapperRef]), onKeyDown: handleKeyDown, onMouseDown: handleBackdropMouseDown, onMouseUp: handleBackdropMouseUp, tabIndex: -1, "data-test-id": dataTestId, style: {
261
271
  zIndex: computedZIndex,
262
272
  } },
@@ -49,6 +49,11 @@ type BaseModalProps = {
49
49
  * @default false
50
50
  */
51
51
  disableBackdropClick?: boolean;
52
+ /**
53
+ * Отключает блокировку скролла при открытии модального окна
54
+ * @default false
55
+ */
56
+ disableBlockingScroll?: boolean;
52
57
  /**
53
58
  * Содержимое модалки всегда в DOM
54
59
  * @default false
@@ -8,10 +8,10 @@ var mergeRefs = require('react-merge-refs');
8
8
  var resizeObserver = require('@juggle/resize-observer');
9
9
  var reactTransitionGroup = require('react-transition-group');
10
10
  var FocusLock = require('react-focus-lock');
11
- var coreComponentsPortal = require('@alfalab/core-components-portal/dist/cssm');
12
- var coreComponentsBackdrop = require('@alfalab/core-components-backdrop/dist/cssm');
13
- var coreComponentsStack = require('@alfalab/core-components-stack/dist/cssm');
14
- require('@alfalab/core-components-global-store/dist/cssm');
11
+ var coreComponentsPortal = require('@alfalab/core-components-portal/cssm');
12
+ var coreComponentsBackdrop = require('@alfalab/core-components-backdrop/cssm');
13
+ var coreComponentsStack = require('@alfalab/core-components-stack/cssm');
14
+ require('@alfalab/core-components-global-store/cssm');
15
15
  var utils = require('./utils.js');
16
16
  var styles = require('./index.module.css');
17
17
 
@@ -64,14 +64,14 @@ var BaseModalContext = React__default['default'].createContext({
64
64
  onClose: function () { return null; },
65
65
  });
66
66
  var BaseModal = React.forwardRef(function (_a, ref) {
67
- var open = _a.open, container = _a.container, children = _a.children, _b = _a.scrollHandler, scrollHandler = _b === void 0 ? 'wrapper' : _b, _c = _a.Backdrop, Backdrop = _c === void 0 ? coreComponentsBackdrop.Backdrop : _c, _d = _a.backdropProps, backdropProps = _d === void 0 ? {} : _d, _e = _a.transitionProps, transitionProps = _e === void 0 ? {} : _e, disableBackdropClick = _a.disableBackdropClick, _f = _a.disableAutoFocus, disableAutoFocus = _f === void 0 ? false : _f, _g = _a.disableFocusLock, disableFocusLock = _g === void 0 ? false : _g, _h = _a.disableEscapeKeyDown, disableEscapeKeyDown = _h === void 0 ? false : _h, _j = _a.disableRestoreFocus, disableRestoreFocus = _j === void 0 ? false : _j, _k = _a.keepMounted, keepMounted = _k === void 0 ? false : _k, className = _a.className, contentClassName = _a.contentClassName, wrapperClassName = _a.wrapperClassName, onBackdropClick = _a.onBackdropClick, onClose = _a.onClose, onEscapeKeyDown = _a.onEscapeKeyDown, onMount = _a.onMount, onUnmount = _a.onUnmount, dataTestId = _a.dataTestId, _l = _a.zIndex, zIndex = _l === void 0 ? coreComponentsStack.stackingOrder.MODAL : _l, _m = _a.componentRef, componentRef = _m === void 0 ? null : _m;
68
- var _o = React.useState(!open), exited = _o[0], setExited = _o[1];
69
- var _p = React.useState(false), hasScroll = _p[0], setHasScroll = _p[1];
70
- var _q = React.useState(false), hasHeader = _q[0], setHasHeader = _q[1];
71
- var _r = React.useState(false), hasFooter = _r[0], setHasFooter = _r[1];
72
- var _s = React.useState(false), headerHighlighted = _s[0], setHeaderHighlighted = _s[1];
73
- var _t = React.useState(false), footerHighlighted = _t[0], setFooterHighlighted = _t[1];
74
- var _u = React.useState(0), headerOffset = _u[0], setHeaderOffset = _u[1];
67
+ var open = _a.open, container = _a.container, children = _a.children, _b = _a.scrollHandler, scrollHandler = _b === void 0 ? 'wrapper' : _b, _c = _a.Backdrop, Backdrop = _c === void 0 ? coreComponentsBackdrop.Backdrop : _c, _d = _a.backdropProps, backdropProps = _d === void 0 ? {} : _d, _e = _a.transitionProps, transitionProps = _e === void 0 ? {} : _e, disableBackdropClick = _a.disableBackdropClick, _f = _a.disableAutoFocus, disableAutoFocus = _f === void 0 ? false : _f, _g = _a.disableFocusLock, disableFocusLock = _g === void 0 ? false : _g, _h = _a.disableEscapeKeyDown, disableEscapeKeyDown = _h === void 0 ? false : _h, _j = _a.disableRestoreFocus, disableRestoreFocus = _j === void 0 ? false : _j, _k = _a.disableBlockingScroll, disableBlockingScroll = _k === void 0 ? false : _k, _l = _a.keepMounted, keepMounted = _l === void 0 ? false : _l, className = _a.className, contentClassName = _a.contentClassName, wrapperClassName = _a.wrapperClassName, onBackdropClick = _a.onBackdropClick, onClose = _a.onClose, onEscapeKeyDown = _a.onEscapeKeyDown, onMount = _a.onMount, onUnmount = _a.onUnmount, dataTestId = _a.dataTestId, _m = _a.zIndex, zIndex = _m === void 0 ? coreComponentsStack.stackingOrder.MODAL : _m, _o = _a.componentRef, componentRef = _o === void 0 ? null : _o;
68
+ var _p = React.useState(null), exited = _p[0], setExited = _p[1];
69
+ var _q = React.useState(false), hasScroll = _q[0], setHasScroll = _q[1];
70
+ var _r = React.useState(false), hasHeader = _r[0], setHasHeader = _r[1];
71
+ var _s = React.useState(false), hasFooter = _s[0], setHasFooter = _s[1];
72
+ var _t = React.useState(false), headerHighlighted = _t[0], setHeaderHighlighted = _t[1];
73
+ var _u = React.useState(false), footerHighlighted = _u[0], setFooterHighlighted = _u[1];
74
+ var _v = React.useState(0), headerOffset = _v[0], setHeaderOffset = _v[1];
75
75
  var componentNodeRef = React.useRef(null);
76
76
  var wrapperRef = React.useRef(null);
77
77
  var scrollableNodeRef = React.useRef(null);
@@ -86,7 +86,8 @@ var BaseModal = React.forwardRef(function (_a, ref) {
86
86
  setHasScroll(scrollExists);
87
87
  }
88
88
  };
89
- var shouldRender = keepMounted || open || !exited;
89
+ var isExited = exited || exited === null;
90
+ var shouldRender = keepMounted || open || !isExited;
90
91
  var getContainer = React.useCallback(function () {
91
92
  return (container ? container() : document.body);
92
93
  }, [container]);
@@ -136,7 +137,15 @@ var BaseModal = React.forwardRef(function (_a, ref) {
136
137
  return null;
137
138
  }, [onBackdropClick, onClose, onEscapeKeyDown]);
138
139
  var handleBackdropMouseDown = function (event) {
139
- if (!disableBackdropClick) {
140
+ var _a;
141
+ var clickedOnScrollbar = false;
142
+ var clientWidth = (_a = event.target) === null || _a === void 0 ? void 0 : _a.clientWidth;
143
+ if (event.clientX && clientWidth) {
144
+ // Устанавливаем смещение для абсолютно спозиционированного скроллбара в OSX в 17px.
145
+ var offset = utils.getScrollbarSize() === 0 ? 17 : 0;
146
+ clickedOnScrollbar = event.clientX + offset > clientWidth;
147
+ }
148
+ if (!disableBackdropClick && !clickedOnScrollbar) {
140
149
  mouseDownTarget.current = event.target;
141
150
  }
142
151
  };
@@ -146,6 +155,7 @@ var BaseModal = React.forwardRef(function (_a, ref) {
146
155
  mouseDownTarget.current === wrapperRef.current) {
147
156
  handleClose(event, 'backdropClick');
148
157
  }
158
+ mouseDownTarget.current = undefined;
149
159
  };
150
160
  var handleKeyDown = React.useCallback(function (event) {
151
161
  /*
@@ -197,18 +207,18 @@ var BaseModal = React.forwardRef(function (_a, ref) {
197
207
  }
198
208
  }, [handleScroll, onUnmount, removeResizeHandle, transitionProps]);
199
209
  React.useEffect(function () {
200
- if (open) {
201
- utils.handleContainer(getContainer());
202
- restoreContainerStylesRef.current = function () {
203
- restoreContainerStylesRef.current = null;
204
- utils.restoreContainerStyles(getContainer());
205
- };
206
- }
207
- }, [getContainer, open]);
208
- React.useEffect(function () {
209
- if (open)
210
+ if (open && isExited) {
211
+ if (!disableBlockingScroll) {
212
+ var el_1 = getContainer();
213
+ utils.handleContainer(el_1);
214
+ restoreContainerStylesRef.current = function () {
215
+ restoreContainerStylesRef.current = null;
216
+ utils.restoreContainerStyles(el_1);
217
+ };
218
+ }
210
219
  setExited(false);
211
- }, [open]);
220
+ }
221
+ }, [getContainer, open, disableBlockingScroll, isExited]);
212
222
  React.useEffect(function () {
213
223
  var ResizeObserver = window.ResizeObserver || resizeObserver.ResizeObserver;
214
224
  resizeObserverRef.current = new ResizeObserver(checkToHasScrollBar);
@@ -255,7 +265,7 @@ var BaseModal = React.forwardRef(function (_a, ref) {
255
265
  zIndex: computedZIndex,
256
266
  } }))),
257
267
  React__default['default'].createElement("div", { role: 'dialog', className: cn__default['default'](styles__default['default'].wrapper, wrapperClassName, (_a = {},
258
- _a[styles__default['default'].hidden] = !open && exited,
268
+ _a[styles__default['default'].hidden] = !open && isExited,
259
269
  _a)), ref: mergeRefs__default['default']([ref, wrapperRef]), onKeyDown: handleKeyDown, onMouseDown: handleBackdropMouseDown, onMouseUp: handleBackdropMouseUp, tabIndex: -1, "data-test-id": dataTestId, style: {
260
270
  zIndex: computedZIndex,
261
271
  } },
File without changes
@@ -9,10 +9,10 @@ require('react-merge-refs');
9
9
  require('@juggle/resize-observer');
10
10
  require('react-transition-group');
11
11
  require('react-focus-lock');
12
- require('@alfalab/core-components-portal/dist/cssm');
13
- require('@alfalab/core-components-backdrop/dist/cssm');
14
- require('@alfalab/core-components-stack/dist/cssm');
15
- require('@alfalab/core-components-global-store/dist/cssm');
12
+ require('@alfalab/core-components-portal/cssm');
13
+ require('@alfalab/core-components-backdrop/cssm');
14
+ require('@alfalab/core-components-stack/cssm');
15
+ require('@alfalab/core-components-global-store/cssm');
16
16
  var utils = require('./utils.js');
17
17
  require('./index.module.css');
18
18
 
@@ -20,6 +20,7 @@ require('./index.module.css');
20
20
 
21
21
  exports.BaseModal = Component.BaseModal;
22
22
  exports.BaseModalContext = Component.BaseModalContext;
23
+ exports.getScrollbarSize = utils.getScrollbarSize;
23
24
  exports.handleContainer = utils.handleContainer;
24
25
  exports.hasScrollbar = utils.hasScrollbar;
25
26
  exports.isScrolledToBottom = utils.isScrolledToBottom;
File without changes
@@ -1,6 +1,7 @@
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 getScrollbarSize: () => number;
4
5
  declare const restoreContainerStyles: (container: HTMLElement) => void;
5
6
  declare const handleContainer: (container?: HTMLElement | undefined) => void;
6
- export { isScrolledToTop, isScrolledToBottom, hasScrollbar, restoreContainerStyles, handleContainer };
7
+ export { isScrolledToTop, isScrolledToBottom, hasScrollbar, getScrollbarSize, restoreContainerStyles, handleContainer };
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var coreComponentsGlobalStore = require('@alfalab/core-components-global-store/dist/cssm');
5
+ var coreComponentsGlobalStore = require('@alfalab/core-components-global-store/cssm');
6
6
 
7
7
  function isScrolledToTop(target) {
8
8
  return target.scrollTop <= 0;
@@ -13,18 +13,24 @@ function isScrolledToBottom(target) {
13
13
  function hasScrollbar(target) {
14
14
  return target.scrollHeight > target.clientHeight;
15
15
  }
16
- var getScrollbarSize = function () {
17
- var scrollDiv = document.createElement('div');
18
- scrollDiv.style.width = '99px';
19
- scrollDiv.style.height = '99px';
20
- scrollDiv.style.position = 'absolute';
21
- scrollDiv.style.top = '-9999px';
22
- scrollDiv.style.overflow = 'scroll';
23
- document.body.appendChild(scrollDiv);
24
- var scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth;
25
- document.body.removeChild(scrollDiv);
26
- return scrollbarSize;
27
- };
16
+ var getScrollbarSize = (function () {
17
+ var cachedSize;
18
+ return function () {
19
+ if (cachedSize !== undefined)
20
+ return cachedSize;
21
+ var scrollDiv = document.createElement('div');
22
+ scrollDiv.style.width = '99px';
23
+ scrollDiv.style.height = '99px';
24
+ scrollDiv.style.position = 'absolute';
25
+ scrollDiv.style.top = '-9999px';
26
+ scrollDiv.style.overflow = 'scroll';
27
+ document.body.appendChild(scrollDiv);
28
+ var scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth;
29
+ document.body.removeChild(scrollDiv);
30
+ cachedSize = scrollbarSize;
31
+ return scrollbarSize;
32
+ };
33
+ })();
28
34
  var isOverflowing = function (container) {
29
35
  if (document.body === container) {
30
36
  return window.innerWidth > document.documentElement.clientWidth;
@@ -100,6 +106,7 @@ var handleContainer = function (container) {
100
106
  });
101
107
  };
102
108
 
109
+ exports.getScrollbarSize = getScrollbarSize;
103
110
  exports.handleContainer = handleContainer;
104
111
  exports.hasScrollbar = hasScrollbar;
105
112
  exports.isScrolledToBottom = isScrolledToBottom;
@@ -49,6 +49,11 @@ type BaseModalProps = {
49
49
  * @default false
50
50
  */
51
51
  disableBackdropClick?: boolean;
52
+ /**
53
+ * Отключает блокировку скролла при открытии модального окна
54
+ * @default false
55
+ */
56
+ disableBlockingScroll?: boolean;
52
57
  /**
53
58
  * Содержимое модалки всегда в DOM
54
59
  * @default false
@@ -4,11 +4,11 @@ import mergeRefs from 'react-merge-refs';
4
4
  import { ResizeObserver } from '@juggle/resize-observer';
5
5
  import { CSSTransition } from 'react-transition-group';
6
6
  import FocusLock from 'react-focus-lock';
7
- import { Portal } from '@alfalab/core-components-portal/dist/esm';
8
- import { Backdrop } from '@alfalab/core-components-backdrop/dist/esm';
9
- import { stackingOrder, Stack } from '@alfalab/core-components-stack/dist/esm';
10
- import '@alfalab/core-components-global-store/dist/esm';
11
- import { isScrolledToTop, isScrolledToBottom, handleContainer, restoreContainerStyles, hasScrollbar } from './utils.js';
7
+ import { Portal } from '@alfalab/core-components-portal/esm';
8
+ import { Backdrop } from '@alfalab/core-components-backdrop/esm';
9
+ import { stackingOrder, Stack } from '@alfalab/core-components-stack/esm';
10
+ import '@alfalab/core-components-global-store/esm';
11
+ import { isScrolledToTop, isScrolledToBottom, handleContainer, restoreContainerStyles, hasScrollbar, getScrollbarSize } from './utils.js';
12
12
 
13
13
  /*! *****************************************************************************
14
14
  Copyright (c) Microsoft Corporation.
@@ -37,7 +37,7 @@ var __assign = function () {
37
37
  return __assign.apply(this, arguments);
38
38
  };
39
39
 
40
- var styles = {"component":"base-modal__component_12xfo","wrapper":"base-modal__wrapper_12xfo","content":"base-modal__content_12xfo","hidden":"base-modal__hidden_12xfo","backdrop":"base-modal__backdrop_12xfo","appear":"base-modal__appear_12xfo","enter":"base-modal__enter_12xfo","appearActive":"base-modal__appearActive_12xfo","enterActive":"base-modal__enterActive_12xfo","exit":"base-modal__exit_12xfo","exitActive":"base-modal__exitActive_12xfo","exitDone":"base-modal__exitDone_12xfo"};
40
+ var styles = {"component":"base-modal__component_1xxjn","wrapper":"base-modal__wrapper_1xxjn","content":"base-modal__content_1xxjn","hidden":"base-modal__hidden_1xxjn","backdrop":"base-modal__backdrop_1xxjn","appear":"base-modal__appear_1xxjn","enter":"base-modal__enter_1xxjn","appearActive":"base-modal__appearActive_1xxjn","enterActive":"base-modal__enterActive_1xxjn","exit":"base-modal__exit_1xxjn","exitActive":"base-modal__exitActive_1xxjn","exitDone":"base-modal__exitDone_1xxjn"};
41
41
  require('./index.css')
42
42
 
43
43
  var BaseModalContext = React.createContext({
@@ -54,14 +54,14 @@ var BaseModalContext = React.createContext({
54
54
  onClose: function () { return null; },
55
55
  });
56
56
  var BaseModal = forwardRef(function (_a, ref) {
57
- var open = _a.open, container = _a.container, children = _a.children, _b = _a.scrollHandler, scrollHandler = _b === void 0 ? 'wrapper' : _b, _c = _a.Backdrop, Backdrop$1 = _c === void 0 ? Backdrop : _c, _d = _a.backdropProps, backdropProps = _d === void 0 ? {} : _d, _e = _a.transitionProps, transitionProps = _e === void 0 ? {} : _e, disableBackdropClick = _a.disableBackdropClick, _f = _a.disableAutoFocus, disableAutoFocus = _f === void 0 ? false : _f, _g = _a.disableFocusLock, disableFocusLock = _g === void 0 ? false : _g, _h = _a.disableEscapeKeyDown, disableEscapeKeyDown = _h === void 0 ? false : _h, _j = _a.disableRestoreFocus, disableRestoreFocus = _j === void 0 ? false : _j, _k = _a.keepMounted, keepMounted = _k === void 0 ? false : _k, className = _a.className, contentClassName = _a.contentClassName, wrapperClassName = _a.wrapperClassName, onBackdropClick = _a.onBackdropClick, onClose = _a.onClose, onEscapeKeyDown = _a.onEscapeKeyDown, onMount = _a.onMount, onUnmount = _a.onUnmount, dataTestId = _a.dataTestId, _l = _a.zIndex, zIndex = _l === void 0 ? stackingOrder.MODAL : _l, _m = _a.componentRef, componentRef = _m === void 0 ? null : _m;
58
- var _o = useState(!open), exited = _o[0], setExited = _o[1];
59
- var _p = useState(false), hasScroll = _p[0], setHasScroll = _p[1];
60
- var _q = useState(false), hasHeader = _q[0], setHasHeader = _q[1];
61
- var _r = useState(false), hasFooter = _r[0], setHasFooter = _r[1];
62
- var _s = useState(false), headerHighlighted = _s[0], setHeaderHighlighted = _s[1];
63
- var _t = useState(false), footerHighlighted = _t[0], setFooterHighlighted = _t[1];
64
- var _u = useState(0), headerOffset = _u[0], setHeaderOffset = _u[1];
57
+ var open = _a.open, container = _a.container, children = _a.children, _b = _a.scrollHandler, scrollHandler = _b === void 0 ? 'wrapper' : _b, _c = _a.Backdrop, Backdrop$1 = _c === void 0 ? Backdrop : _c, _d = _a.backdropProps, backdropProps = _d === void 0 ? {} : _d, _e = _a.transitionProps, transitionProps = _e === void 0 ? {} : _e, disableBackdropClick = _a.disableBackdropClick, _f = _a.disableAutoFocus, disableAutoFocus = _f === void 0 ? false : _f, _g = _a.disableFocusLock, disableFocusLock = _g === void 0 ? false : _g, _h = _a.disableEscapeKeyDown, disableEscapeKeyDown = _h === void 0 ? false : _h, _j = _a.disableRestoreFocus, disableRestoreFocus = _j === void 0 ? false : _j, _k = _a.disableBlockingScroll, disableBlockingScroll = _k === void 0 ? false : _k, _l = _a.keepMounted, keepMounted = _l === void 0 ? false : _l, className = _a.className, contentClassName = _a.contentClassName, wrapperClassName = _a.wrapperClassName, onBackdropClick = _a.onBackdropClick, onClose = _a.onClose, onEscapeKeyDown = _a.onEscapeKeyDown, onMount = _a.onMount, onUnmount = _a.onUnmount, dataTestId = _a.dataTestId, _m = _a.zIndex, zIndex = _m === void 0 ? stackingOrder.MODAL : _m, _o = _a.componentRef, componentRef = _o === void 0 ? null : _o;
58
+ var _p = useState(null), exited = _p[0], setExited = _p[1];
59
+ var _q = useState(false), hasScroll = _q[0], setHasScroll = _q[1];
60
+ var _r = useState(false), hasHeader = _r[0], setHasHeader = _r[1];
61
+ var _s = useState(false), hasFooter = _s[0], setHasFooter = _s[1];
62
+ var _t = useState(false), headerHighlighted = _t[0], setHeaderHighlighted = _t[1];
63
+ var _u = useState(false), footerHighlighted = _u[0], setFooterHighlighted = _u[1];
64
+ var _v = useState(0), headerOffset = _v[0], setHeaderOffset = _v[1];
65
65
  var componentNodeRef = useRef(null);
66
66
  var wrapperRef = useRef(null);
67
67
  var scrollableNodeRef = useRef(null);
@@ -76,7 +76,8 @@ var BaseModal = forwardRef(function (_a, ref) {
76
76
  setHasScroll(scrollExists);
77
77
  }
78
78
  };
79
- var shouldRender = keepMounted || open || !exited;
79
+ var isExited = exited || exited === null;
80
+ var shouldRender = keepMounted || open || !isExited;
80
81
  var getContainer = useCallback(function () {
81
82
  return (container ? container() : document.body);
82
83
  }, [container]);
@@ -126,7 +127,15 @@ var BaseModal = forwardRef(function (_a, ref) {
126
127
  return null;
127
128
  }, [onBackdropClick, onClose, onEscapeKeyDown]);
128
129
  var handleBackdropMouseDown = function (event) {
129
- if (!disableBackdropClick) {
130
+ var _a;
131
+ var clickedOnScrollbar = false;
132
+ var clientWidth = (_a = event.target) === null || _a === void 0 ? void 0 : _a.clientWidth;
133
+ if (event.clientX && clientWidth) {
134
+ // Устанавливаем смещение для абсолютно спозиционированного скроллбара в OSX в 17px.
135
+ var offset = getScrollbarSize() === 0 ? 17 : 0;
136
+ clickedOnScrollbar = event.clientX + offset > clientWidth;
137
+ }
138
+ if (!disableBackdropClick && !clickedOnScrollbar) {
130
139
  mouseDownTarget.current = event.target;
131
140
  }
132
141
  };
@@ -136,6 +145,7 @@ var BaseModal = forwardRef(function (_a, ref) {
136
145
  mouseDownTarget.current === wrapperRef.current) {
137
146
  handleClose(event, 'backdropClick');
138
147
  }
148
+ mouseDownTarget.current = undefined;
139
149
  };
140
150
  var handleKeyDown = useCallback(function (event) {
141
151
  /*
@@ -187,18 +197,18 @@ var BaseModal = forwardRef(function (_a, ref) {
187
197
  }
188
198
  }, [handleScroll, onUnmount, removeResizeHandle, transitionProps]);
189
199
  useEffect(function () {
190
- if (open) {
191
- handleContainer(getContainer());
192
- restoreContainerStylesRef.current = function () {
193
- restoreContainerStylesRef.current = null;
194
- restoreContainerStyles(getContainer());
195
- };
196
- }
197
- }, [getContainer, open]);
198
- useEffect(function () {
199
- if (open)
200
+ if (open && isExited) {
201
+ if (!disableBlockingScroll) {
202
+ var el_1 = getContainer();
203
+ handleContainer(el_1);
204
+ restoreContainerStylesRef.current = function () {
205
+ restoreContainerStylesRef.current = null;
206
+ restoreContainerStyles(el_1);
207
+ };
208
+ }
200
209
  setExited(false);
201
- }, [open]);
210
+ }
211
+ }, [getContainer, open, disableBlockingScroll, isExited]);
202
212
  useEffect(function () {
203
213
  var ResizeObserver$1 = window.ResizeObserver || ResizeObserver;
204
214
  resizeObserverRef.current = new ResizeObserver$1(checkToHasScrollBar);
@@ -245,7 +255,7 @@ var BaseModal = forwardRef(function (_a, ref) {
245
255
  zIndex: computedZIndex,
246
256
  } }))),
247
257
  React.createElement("div", { role: 'dialog', className: cn(styles.wrapper, wrapperClassName, (_a = {},
248
- _a[styles.hidden] = !open && exited,
258
+ _a[styles.hidden] = !open && isExited,
249
259
  _a)), ref: mergeRefs([ref, wrapperRef]), onKeyDown: handleKeyDown, onMouseDown: handleBackdropMouseDown, onMouseUp: handleBackdropMouseUp, tabIndex: -1, "data-test-id": dataTestId, style: {
250
260
  zIndex: computedZIndex,
251
261
  } },
@@ -1,4 +1,4 @@
1
- /* hash: 12lf3 */
1
+ /* hash: 1z9ex */
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_12xfo {
13
+ .base-modal__component_1xxjn {
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_12xfo {
20
+ .base-modal__wrapper_1xxjn {
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_12xfo {
33
+ .base-modal__content_1xxjn {
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_12xfo {
40
+ .base-modal__hidden_1xxjn {
41
41
  display: none;
42
42
  }
43
- .base-modal__backdrop_12xfo {
43
+ .base-modal__backdrop_1xxjn {
44
44
  z-index: 0;
45
45
  }
46
- .base-modal__appear_12xfo,
47
- .base-modal__enter_12xfo {
46
+ .base-modal__appear_1xxjn,
47
+ .base-modal__enter_1xxjn {
48
48
  opacity: 0;
49
49
  }
50
- .base-modal__appearActive_12xfo,
51
- .base-modal__enterActive_12xfo {
50
+ .base-modal__appearActive_1xxjn,
51
+ .base-modal__enterActive_1xxjn {
52
52
  opacity: 1;
53
53
  transition: opacity 200ms ease-in;
54
54
  }
55
- .base-modal__exit_12xfo {
55
+ .base-modal__exit_1xxjn {
56
56
  opacity: 1;
57
57
  }
58
- .base-modal__exitActive_12xfo,
59
- .base-modal__exitDone_12xfo {
58
+ .base-modal__exitActive_1xxjn,
59
+ .base-modal__exitDone_1xxjn {
60
60
  opacity: 0;
61
61
  transition: opacity 200ms ease-out;
62
62
  }
File without changes
package/esm/index.js ADDED
@@ -0,0 +1,12 @@
1
+ export { BaseModal, BaseModalContext } from './Component.js';
2
+ import 'react';
3
+ import 'classnames';
4
+ import 'react-merge-refs';
5
+ import '@juggle/resize-observer';
6
+ import 'react-transition-group';
7
+ import 'react-focus-lock';
8
+ import '@alfalab/core-components-portal/esm';
9
+ import '@alfalab/core-components-backdrop/esm';
10
+ import '@alfalab/core-components-stack/esm';
11
+ import '@alfalab/core-components-global-store/esm';
12
+ export { getScrollbarSize, handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles } from './utils.js';
@@ -1,6 +1,7 @@
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 getScrollbarSize: () => number;
4
5
  declare const restoreContainerStyles: (container: HTMLElement) => void;
5
6
  declare const handleContainer: (container?: HTMLElement | undefined) => void;
6
- export { isScrolledToTop, isScrolledToBottom, hasScrollbar, restoreContainerStyles, handleContainer };
7
+ export { isScrolledToTop, isScrolledToBottom, hasScrollbar, getScrollbarSize, restoreContainerStyles, handleContainer };
@@ -1,4 +1,4 @@
1
- import { getModalStore } from '@alfalab/core-components-global-store/dist/esm';
1
+ import { getModalStore } from '@alfalab/core-components-global-store/esm';
2
2
 
3
3
  function isScrolledToTop(target) {
4
4
  return target.scrollTop <= 0;
@@ -9,18 +9,24 @@ function isScrolledToBottom(target) {
9
9
  function hasScrollbar(target) {
10
10
  return target.scrollHeight > target.clientHeight;
11
11
  }
12
- var getScrollbarSize = function () {
13
- var scrollDiv = document.createElement('div');
14
- scrollDiv.style.width = '99px';
15
- scrollDiv.style.height = '99px';
16
- scrollDiv.style.position = 'absolute';
17
- scrollDiv.style.top = '-9999px';
18
- scrollDiv.style.overflow = 'scroll';
19
- document.body.appendChild(scrollDiv);
20
- var scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth;
21
- document.body.removeChild(scrollDiv);
22
- return scrollbarSize;
23
- };
12
+ var getScrollbarSize = (function () {
13
+ var cachedSize;
14
+ return function () {
15
+ if (cachedSize !== undefined)
16
+ return cachedSize;
17
+ var scrollDiv = document.createElement('div');
18
+ scrollDiv.style.width = '99px';
19
+ scrollDiv.style.height = '99px';
20
+ scrollDiv.style.position = 'absolute';
21
+ scrollDiv.style.top = '-9999px';
22
+ scrollDiv.style.overflow = 'scroll';
23
+ document.body.appendChild(scrollDiv);
24
+ var scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth;
25
+ document.body.removeChild(scrollDiv);
26
+ cachedSize = scrollbarSize;
27
+ return scrollbarSize;
28
+ };
29
+ })();
24
30
  var isOverflowing = function (container) {
25
31
  if (document.body === container) {
26
32
  return window.innerWidth > document.documentElement.clientWidth;
@@ -96,4 +102,4 @@ var handleContainer = function (container) {
96
102
  });
97
103
  };
98
104
 
99
- export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles };
105
+ export { getScrollbarSize, handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles };
@@ -1,4 +1,4 @@
1
- /* hash: 12lf3 */
1
+ /* hash: 1z9ex */
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_12xfo {
13
+ .base-modal__component_1xxjn {
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_12xfo {
20
+ .base-modal__wrapper_1xxjn {
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_12xfo {
33
+ .base-modal__content_1xxjn {
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_12xfo {
40
+ .base-modal__hidden_1xxjn {
41
41
  display: none;
42
42
  }
43
- .base-modal__backdrop_12xfo {
43
+ .base-modal__backdrop_1xxjn {
44
44
  z-index: 0;
45
45
  }
46
- .base-modal__appear_12xfo,
47
- .base-modal__enter_12xfo {
46
+ .base-modal__appear_1xxjn,
47
+ .base-modal__enter_1xxjn {
48
48
  opacity: 0;
49
49
  }
50
- .base-modal__appearActive_12xfo,
51
- .base-modal__enterActive_12xfo {
50
+ .base-modal__appearActive_1xxjn,
51
+ .base-modal__enterActive_1xxjn {
52
52
  opacity: 1;
53
53
  transition: opacity 200ms ease-in;
54
54
  }
55
- .base-modal__exit_12xfo {
55
+ .base-modal__exit_1xxjn {
56
56
  opacity: 1;
57
57
  }
58
- .base-modal__exitActive_12xfo,
59
- .base-modal__exitDone_12xfo {
58
+ .base-modal__exitActive_1xxjn,
59
+ .base-modal__exitDone_1xxjn {
60
60
  opacity: 0;
61
61
  transition: opacity 200ms ease-out;
62
62
  }
File without changes
@@ -19,6 +19,7 @@ var utils = require('./utils.js');
19
19
 
20
20
  exports.BaseModal = Component.BaseModal;
21
21
  exports.BaseModalContext = Component.BaseModalContext;
22
+ exports.getScrollbarSize = utils.getScrollbarSize;
22
23
  exports.handleContainer = utils.handleContainer;
23
24
  exports.hasScrollbar = utils.hasScrollbar;
24
25
  exports.isScrolledToBottom = utils.isScrolledToBottom;
@@ -49,6 +49,11 @@ type BaseModalProps = {
49
49
  * @default false
50
50
  */
51
51
  disableBackdropClick?: boolean;
52
+ /**
53
+ * Отключает блокировку скролла при открытии модального окна
54
+ * @default false
55
+ */
56
+ disableBlockingScroll?: boolean;
52
57
  /**
53
58
  * Содержимое модалки всегда в DOM
54
59
  * @default false
@@ -4,13 +4,13 @@ import mergeRefs from 'react-merge-refs';
4
4
  import { ResizeObserver } from '@juggle/resize-observer';
5
5
  import { CSSTransition } from 'react-transition-group';
6
6
  import FocusLock from 'react-focus-lock';
7
- import { Portal } from '@alfalab/core-components-portal/dist/modern';
8
- import { Backdrop } from '@alfalab/core-components-backdrop/dist/modern';
9
- import { stackingOrder, Stack } from '@alfalab/core-components-stack/dist/modern';
10
- import '@alfalab/core-components-global-store/dist/modern';
11
- import { isScrolledToTop, isScrolledToBottom, handleContainer, restoreContainerStyles, hasScrollbar } from './utils.js';
7
+ import { Portal } from '@alfalab/core-components-portal/modern';
8
+ import { Backdrop } from '@alfalab/core-components-backdrop/modern';
9
+ import { stackingOrder, Stack } from '@alfalab/core-components-stack/modern';
10
+ import '@alfalab/core-components-global-store/modern';
11
+ import { isScrolledToTop, isScrolledToBottom, handleContainer, restoreContainerStyles, hasScrollbar, getScrollbarSize } from './utils.js';
12
12
 
13
- var styles = {"component":"base-modal__component_12xfo","wrapper":"base-modal__wrapper_12xfo","content":"base-modal__content_12xfo","hidden":"base-modal__hidden_12xfo","backdrop":"base-modal__backdrop_12xfo","appear":"base-modal__appear_12xfo","enter":"base-modal__enter_12xfo","appearActive":"base-modal__appearActive_12xfo","enterActive":"base-modal__enterActive_12xfo","exit":"base-modal__exit_12xfo","exitActive":"base-modal__exitActive_12xfo","exitDone":"base-modal__exitDone_12xfo"};
13
+ var styles = {"component":"base-modal__component_1xxjn","wrapper":"base-modal__wrapper_1xxjn","content":"base-modal__content_1xxjn","hidden":"base-modal__hidden_1xxjn","backdrop":"base-modal__backdrop_1xxjn","appear":"base-modal__appear_1xxjn","enter":"base-modal__enter_1xxjn","appearActive":"base-modal__appearActive_1xxjn","enterActive":"base-modal__enterActive_1xxjn","exit":"base-modal__exit_1xxjn","exitActive":"base-modal__exitActive_1xxjn","exitDone":"base-modal__exitDone_1xxjn"};
14
14
  require('./index.css')
15
15
 
16
16
  /* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
@@ -27,8 +27,8 @@ const BaseModalContext = React.createContext({
27
27
  setHasFooter: () => null,
28
28
  onClose: () => null,
29
29
  });
30
- const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrapper', Backdrop: Backdrop$1 = Backdrop, backdropProps = {}, transitionProps = {}, disableBackdropClick, disableAutoFocus = false, disableFocusLock = false, disableEscapeKeyDown = false, disableRestoreFocus = false, keepMounted = false, className, contentClassName, wrapperClassName, onBackdropClick, onClose, onEscapeKeyDown, onMount, onUnmount, dataTestId, zIndex = stackingOrder.MODAL, componentRef = null, }, ref) => {
31
- const [exited, setExited] = useState(!open);
30
+ const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrapper', Backdrop: Backdrop$1 = Backdrop, backdropProps = {}, transitionProps = {}, disableBackdropClick, disableAutoFocus = false, disableFocusLock = false, disableEscapeKeyDown = false, disableRestoreFocus = false, disableBlockingScroll = false, keepMounted = false, className, contentClassName, wrapperClassName, onBackdropClick, onClose, onEscapeKeyDown, onMount, onUnmount, dataTestId, zIndex = stackingOrder.MODAL, componentRef = null, }, ref) => {
31
+ const [exited, setExited] = useState(null);
32
32
  const [hasScroll, setHasScroll] = useState(false);
33
33
  const [hasHeader, setHasHeader] = useState(false);
34
34
  const [hasFooter, setHasFooter] = useState(false);
@@ -49,7 +49,8 @@ const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrap
49
49
  setHasScroll(scrollExists);
50
50
  }
51
51
  };
52
- const shouldRender = keepMounted || open || !exited;
52
+ const isExited = exited || exited === null;
53
+ const shouldRender = keepMounted || open || !isExited;
53
54
  const getContainer = useCallback(() => {
54
55
  return (container ? container() : document.body);
55
56
  }, [container]);
@@ -99,7 +100,14 @@ const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrap
99
100
  return null;
100
101
  }, [onBackdropClick, onClose, onEscapeKeyDown]);
101
102
  const handleBackdropMouseDown = (event) => {
102
- if (!disableBackdropClick) {
103
+ let clickedOnScrollbar = false;
104
+ const clientWidth = event.target?.clientWidth;
105
+ if (event.clientX && clientWidth) {
106
+ // Устанавливаем смещение для абсолютно спозиционированного скроллбара в OSX в 17px.
107
+ const offset = getScrollbarSize() === 0 ? 17 : 0;
108
+ clickedOnScrollbar = event.clientX + offset > clientWidth;
109
+ }
110
+ if (!disableBackdropClick && !clickedOnScrollbar) {
103
111
  mouseDownTarget.current = event.target;
104
112
  }
105
113
  };
@@ -109,6 +117,7 @@ const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrap
109
117
  mouseDownTarget.current === wrapperRef.current) {
110
118
  handleClose(event, 'backdropClick');
111
119
  }
120
+ mouseDownTarget.current = undefined;
112
121
  };
113
122
  const handleKeyDown = useCallback((event) => {
114
123
  /*
@@ -160,18 +169,18 @@ const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrap
160
169
  }
161
170
  }, [handleScroll, onUnmount, removeResizeHandle, transitionProps]);
162
171
  useEffect(() => {
163
- if (open) {
164
- handleContainer(getContainer());
165
- restoreContainerStylesRef.current = () => {
166
- restoreContainerStylesRef.current = null;
167
- restoreContainerStyles(getContainer());
168
- };
169
- }
170
- }, [getContainer, open]);
171
- useEffect(() => {
172
- if (open)
172
+ if (open && isExited) {
173
+ if (!disableBlockingScroll) {
174
+ const el = getContainer();
175
+ handleContainer(el);
176
+ restoreContainerStylesRef.current = () => {
177
+ restoreContainerStylesRef.current = null;
178
+ restoreContainerStyles(el);
179
+ };
180
+ }
173
181
  setExited(false);
174
- }, [open]);
182
+ }
183
+ }, [getContainer, open, disableBlockingScroll, isExited]);
175
184
  useEffect(() => {
176
185
  const ResizeObserver$1 = window.ResizeObserver || ResizeObserver;
177
186
  resizeObserverRef.current = new ResizeObserver$1(checkToHasScrollBar);
@@ -216,7 +225,7 @@ const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrap
216
225
  zIndex: computedZIndex,
217
226
  } }))),
218
227
  React.createElement("div", { role: 'dialog', className: cn(styles.wrapper, wrapperClassName, {
219
- [styles.hidden]: !open && exited,
228
+ [styles.hidden]: !open && isExited,
220
229
  }), ref: mergeRefs([ref, wrapperRef]), onKeyDown: handleKeyDown, onMouseDown: handleBackdropMouseDown, onMouseUp: handleBackdropMouseUp, tabIndex: -1, "data-test-id": dataTestId, style: {
221
230
  zIndex: computedZIndex,
222
231
  } },
@@ -1,4 +1,4 @@
1
- /* hash: 12lf3 */
1
+ /* hash: 1z9ex */
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_12xfo {
13
+ .base-modal__component_1xxjn {
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_12xfo {
20
+ .base-modal__wrapper_1xxjn {
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_12xfo {
33
+ .base-modal__content_1xxjn {
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_12xfo {
40
+ .base-modal__hidden_1xxjn {
41
41
  display: none;
42
42
  }
43
- .base-modal__backdrop_12xfo {
43
+ .base-modal__backdrop_1xxjn {
44
44
  z-index: 0;
45
45
  }
46
- .base-modal__appear_12xfo,
47
- .base-modal__enter_12xfo {
46
+ .base-modal__appear_1xxjn,
47
+ .base-modal__enter_1xxjn {
48
48
  opacity: 0;
49
49
  }
50
- .base-modal__appearActive_12xfo,
51
- .base-modal__enterActive_12xfo {
50
+ .base-modal__appearActive_1xxjn,
51
+ .base-modal__enterActive_1xxjn {
52
52
  opacity: 1;
53
53
  transition: opacity 200ms ease-in;
54
54
  }
55
- .base-modal__exit_12xfo {
55
+ .base-modal__exit_1xxjn {
56
56
  opacity: 1;
57
57
  }
58
- .base-modal__exitActive_12xfo,
59
- .base-modal__exitDone_12xfo {
58
+ .base-modal__exitActive_1xxjn,
59
+ .base-modal__exitDone_1xxjn {
60
60
  opacity: 0;
61
61
  transition: opacity 200ms ease-out;
62
62
  }
File without changes
@@ -0,0 +1,12 @@
1
+ import 'react';
2
+ import 'classnames';
3
+ import 'react-merge-refs';
4
+ import '@juggle/resize-observer';
5
+ import 'react-transition-group';
6
+ import 'react-focus-lock';
7
+ import '@alfalab/core-components-portal/modern';
8
+ import '@alfalab/core-components-backdrop/modern';
9
+ import '@alfalab/core-components-stack/modern';
10
+ import '@alfalab/core-components-global-store/modern';
11
+ export { getScrollbarSize, handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles } from './utils.js';
12
+ export { BaseModal, BaseModalContext } from './Component.js';
@@ -1,6 +1,7 @@
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 getScrollbarSize: () => number;
4
5
  declare const restoreContainerStyles: (container: HTMLElement) => void;
5
6
  declare const handleContainer: (container?: HTMLElement | undefined) => void;
6
- export { isScrolledToTop, isScrolledToBottom, hasScrollbar, restoreContainerStyles, handleContainer };
7
+ export { isScrolledToTop, isScrolledToBottom, hasScrollbar, getScrollbarSize, restoreContainerStyles, handleContainer };
@@ -1,4 +1,4 @@
1
- import { getModalStore } from '@alfalab/core-components-global-store/dist/modern';
1
+ import { getModalStore } from '@alfalab/core-components-global-store/modern';
2
2
 
3
3
  function isScrolledToTop(target) {
4
4
  return target.scrollTop <= 0;
@@ -9,18 +9,24 @@ function isScrolledToBottom(target) {
9
9
  function hasScrollbar(target) {
10
10
  return target.scrollHeight > target.clientHeight;
11
11
  }
12
- const getScrollbarSize = () => {
13
- const scrollDiv = document.createElement('div');
14
- scrollDiv.style.width = '99px';
15
- scrollDiv.style.height = '99px';
16
- scrollDiv.style.position = 'absolute';
17
- scrollDiv.style.top = '-9999px';
18
- scrollDiv.style.overflow = 'scroll';
19
- document.body.appendChild(scrollDiv);
20
- const scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth;
21
- document.body.removeChild(scrollDiv);
22
- return scrollbarSize;
23
- };
12
+ const getScrollbarSize = (() => {
13
+ let cachedSize;
14
+ return () => {
15
+ if (cachedSize !== undefined)
16
+ return cachedSize;
17
+ const scrollDiv = document.createElement('div');
18
+ scrollDiv.style.width = '99px';
19
+ scrollDiv.style.height = '99px';
20
+ scrollDiv.style.position = 'absolute';
21
+ scrollDiv.style.top = '-9999px';
22
+ scrollDiv.style.overflow = 'scroll';
23
+ document.body.appendChild(scrollDiv);
24
+ const scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth;
25
+ document.body.removeChild(scrollDiv);
26
+ cachedSize = scrollbarSize;
27
+ return scrollbarSize;
28
+ };
29
+ })();
24
30
  const isOverflowing = (container) => {
25
31
  if (document.body === container) {
26
32
  return window.innerWidth > document.documentElement.clientWidth;
@@ -95,4 +101,4 @@ const handleContainer = (container) => {
95
101
  });
96
102
  };
97
103
 
98
- export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles };
104
+ export { getScrollbarSize, handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles };
package/package.json CHANGED
@@ -1,24 +1,22 @@
1
1
  {
2
2
  "name": "@alfalab/core-components-base-modal",
3
- "version": "4.1.3",
3
+ "version": "4.2.1",
4
4
  "description": "BaseModal component",
5
5
  "keywords": [],
6
6
  "license": "MIT",
7
- "main": "dist/index.js",
8
- "files": [
9
- "dist"
10
- ],
7
+ "main": "index.js",
11
8
  "scripts": {
12
- "postinstall": "node ./dist/send-stats.js > /dev/null 2>&1 || exit 0"
9
+ "postinstall": "node -e \"if (require('fs').existsSync('./send-stats.js')){require('./send-stats.js')} \""
13
10
  },
14
11
  "publishConfig": {
15
- "access": "public"
12
+ "access": "public",
13
+ "directory": "dist"
16
14
  },
17
15
  "dependencies": {
18
- "@alfalab/core-components-backdrop": "^2.1.0",
19
- "@alfalab/core-components-global-store": "^1.1.1",
20
- "@alfalab/core-components-portal": "^2.0.3",
21
- "@alfalab/core-components-stack": "^3.0.3",
16
+ "@alfalab/core-components-backdrop": "^2.1.3",
17
+ "@alfalab/core-components-global-store": "^1.1.2",
18
+ "@alfalab/core-components-portal": "^2.0.6",
19
+ "@alfalab/core-components-stack": "^3.0.5",
22
20
  "@juggle/resize-observer": "^3.3.1",
23
21
  "classnames": "^2.2.6",
24
22
  "react-focus-lock": "^2.5.0",
@@ -30,6 +28,5 @@
30
28
  },
31
29
  "peerDependencies": {
32
30
  "react": "^16.9.0 || ^17.0.1"
33
- },
34
- "gitHead": "62c863f937c2b78ab35b8ca55863b11a0ebdd631"
31
+ }
35
32
  }
File without changes
@@ -1,6 +1,7 @@
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 getScrollbarSize: () => number;
4
5
  declare const restoreContainerStyles: (container: HTMLElement) => void;
5
6
  declare const handleContainer: (container?: HTMLElement | undefined) => void;
6
- export { isScrolledToTop, isScrolledToBottom, hasScrollbar, restoreContainerStyles, handleContainer };
7
+ export { isScrolledToTop, isScrolledToBottom, hasScrollbar, getScrollbarSize, restoreContainerStyles, handleContainer };
@@ -13,18 +13,24 @@ function isScrolledToBottom(target) {
13
13
  function hasScrollbar(target) {
14
14
  return target.scrollHeight > target.clientHeight;
15
15
  }
16
- var getScrollbarSize = function () {
17
- var scrollDiv = document.createElement('div');
18
- scrollDiv.style.width = '99px';
19
- scrollDiv.style.height = '99px';
20
- scrollDiv.style.position = 'absolute';
21
- scrollDiv.style.top = '-9999px';
22
- scrollDiv.style.overflow = 'scroll';
23
- document.body.appendChild(scrollDiv);
24
- var scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth;
25
- document.body.removeChild(scrollDiv);
26
- return scrollbarSize;
27
- };
16
+ var getScrollbarSize = (function () {
17
+ var cachedSize;
18
+ return function () {
19
+ if (cachedSize !== undefined)
20
+ return cachedSize;
21
+ var scrollDiv = document.createElement('div');
22
+ scrollDiv.style.width = '99px';
23
+ scrollDiv.style.height = '99px';
24
+ scrollDiv.style.position = 'absolute';
25
+ scrollDiv.style.top = '-9999px';
26
+ scrollDiv.style.overflow = 'scroll';
27
+ document.body.appendChild(scrollDiv);
28
+ var scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth;
29
+ document.body.removeChild(scrollDiv);
30
+ cachedSize = scrollbarSize;
31
+ return scrollbarSize;
32
+ };
33
+ })();
28
34
  var isOverflowing = function (container) {
29
35
  if (document.body === container) {
30
36
  return window.innerWidth > document.documentElement.clientWidth;
@@ -100,6 +106,7 @@ var handleContainer = function (container) {
100
106
  });
101
107
  };
102
108
 
109
+ exports.getScrollbarSize = getScrollbarSize;
103
110
  exports.handleContainer = handleContainer;
104
111
  exports.hasScrollbar = hasScrollbar;
105
112
  exports.isScrolledToBottom = isScrolledToBottom;
package/dist/esm/index.js DELETED
@@ -1,12 +0,0 @@
1
- export { BaseModal, BaseModalContext } from './Component.js';
2
- import 'react';
3
- import 'classnames';
4
- import 'react-merge-refs';
5
- import '@juggle/resize-observer';
6
- import 'react-transition-group';
7
- import 'react-focus-lock';
8
- import '@alfalab/core-components-portal/dist/esm';
9
- import '@alfalab/core-components-backdrop/dist/esm';
10
- import '@alfalab/core-components-stack/dist/esm';
11
- import '@alfalab/core-components-global-store/dist/esm';
12
- export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles } from './utils.js';
@@ -1,12 +0,0 @@
1
- import 'react';
2
- import 'classnames';
3
- import 'react-merge-refs';
4
- import '@juggle/resize-observer';
5
- import 'react-transition-group';
6
- import 'react-focus-lock';
7
- import '@alfalab/core-components-portal/dist/modern';
8
- import '@alfalab/core-components-backdrop/dist/modern';
9
- import '@alfalab/core-components-stack/dist/modern';
10
- import '@alfalab/core-components-global-store/dist/modern';
11
- export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles } from './utils.js';
12
- export { BaseModal, BaseModalContext } from './Component.js';