@alfalab/core-components-base-modal 5.7.2 → 5.7.4

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/Component.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /// <reference types="react" />
2
2
  /// <reference types="react-transition-group" />
3
3
  import React from 'react';
4
- import { FC, KeyboardEvent, MouseEvent, MutableRefObject, ReactNode, Ref } from "react";
4
+ import { ComponentType, KeyboardEvent, MouseEvent, MutableRefObject, ReactNode, Ref } from "react";
5
5
  import { TransitionProps } from 'react-transition-group/Transition';
6
6
  import { BackdropProps } from "@alfalab/core-components-backdrop";
7
7
  import { PortalProps } from "@alfalab/core-components-portal";
@@ -13,7 +13,7 @@ type BaseModalProps = {
13
13
  /**
14
14
  * Компонент бэкдропа
15
15
  */
16
- Backdrop?: FC<BackdropProps>;
16
+ Backdrop?: ComponentType<BackdropProps>;
17
17
  /**
18
18
  * Свойства для Бэкдропа
19
19
  */
@@ -134,6 +134,10 @@ type BaseModalProps = {
134
134
  * Реф, который должен быть установлен компонентной области
135
135
  */
136
136
  componentRef?: MutableRefObject<HTMLDivElement | null>;
137
+ /**
138
+ * Блокирует скролл когда модальное окно открыто. Работает только на iOS.
139
+ */
140
+ iOSLock?: boolean;
137
141
  };
138
142
  type BaseModalContext = {
139
143
  parentRef: React.RefObject<HTMLDivElement>;
package/Component.js CHANGED
@@ -13,9 +13,9 @@ var coreComponentsBackdrop = require('@alfalab/core-components-backdrop');
13
13
  var coreComponentsPortal = require('@alfalab/core-components-portal');
14
14
  var coreComponentsShared = require('@alfalab/core-components-shared');
15
15
  var coreComponentsStack = require('@alfalab/core-components-stack');
16
+ var helpers_lockScroll = require('./helpers/lockScroll.js');
16
17
  var utils = require('./utils.js');
17
18
  require('./matches-polyfill.js');
18
- require('@alfalab/core-components-global-store');
19
19
 
20
20
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
21
21
 
@@ -24,7 +24,7 @@ var FocusLock__default = /*#__PURE__*/_interopDefaultCompat(FocusLock);
24
24
  var mergeRefs__default = /*#__PURE__*/_interopDefaultCompat(mergeRefs);
25
25
  var cn__default = /*#__PURE__*/_interopDefaultCompat(cn);
26
26
 
27
- var styles = {"component":"base-modal__component_1b68o","wrapper":"base-modal__wrapper_1b68o","content":"base-modal__content_1b68o","hidden":"base-modal__hidden_1b68o","backdrop":"base-modal__backdrop_1b68o","appear":"base-modal__appear_1b68o","enter":"base-modal__enter_1b68o","appearActive":"base-modal__appearActive_1b68o","enterActive":"base-modal__enterActive_1b68o","exit":"base-modal__exit_1b68o","exitActive":"base-modal__exitActive_1b68o","exitDone":"base-modal__exitDone_1b68o"};
27
+ var styles = {"component":"base-modal__component_1apcq","wrapper":"base-modal__wrapper_1apcq","content":"base-modal__content_1apcq","hidden":"base-modal__hidden_1apcq","backdrop":"base-modal__backdrop_1apcq","appear":"base-modal__appear_1apcq","enter":"base-modal__enter_1apcq","appearActive":"base-modal__appearActive_1apcq","enterActive":"base-modal__enterActive_1apcq","exit":"base-modal__exit_1apcq","exitActive":"base-modal__exitActive_1apcq","exitDone":"base-modal__exitDone_1apcq"};
28
28
  require('./index.css')
29
29
 
30
30
  // eslint-disable-next-line @typescript-eslint/no-redeclare
@@ -44,14 +44,14 @@ var BaseModalContext = React__default.default.createContext({
44
44
  onClose: function () { return null; },
45
45
  });
46
46
  var BaseModal = React.forwardRef(function (_a, ref) {
47
- 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, wrapperProps = _a.wrapperProps, contentProps = _a.contentProps, componentDivProps = _a.componentDivProps, 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, _p = _a.usePortal, usePortal = _p === void 0 ? true : _p;
48
- var _q = React.useState(null), exited = _q[0], setExited = _q[1];
49
- var _r = React.useState(false), hasScroll = _r[0], setHasScroll = _r[1];
50
- var _s = React.useState(false), hasHeader = _s[0], setHasHeader = _s[1];
51
- var _t = React.useState(false), hasFooter = _t[0], setHasFooter = _t[1];
52
- var _u = React.useState(false), headerHighlighted = _u[0], setHeaderHighlighted = _u[1];
53
- var _v = React.useState(false), footerHighlighted = _v[0], setFooterHighlighted = _v[1];
54
- var _w = React.useState(0), headerOffset = _w[0], setHeaderOffset = _w[1];
47
+ 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, wrapperProps = _a.wrapperProps, contentProps = _a.contentProps, componentDivProps = _a.componentDivProps, 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, _p = _a.usePortal, usePortal = _p === void 0 ? true : _p, _q = _a.iOSLock, iOSLock = _q === void 0 ? false : _q;
48
+ var _r = React.useState(null), exited = _r[0], setExited = _r[1];
49
+ var _s = React.useState(false), hasScroll = _s[0], setHasScroll = _s[1];
50
+ var _t = React.useState(false), hasHeader = _t[0], setHasHeader = _t[1];
51
+ var _u = React.useState(false), hasFooter = _u[0], setHasFooter = _u[1];
52
+ var _v = React.useState(false), headerHighlighted = _v[0], setHeaderHighlighted = _v[1];
53
+ var _w = React.useState(false), footerHighlighted = _w[0], setFooterHighlighted = _w[1];
54
+ var _x = React.useState(0), headerOffset = _x[0], setHeaderOffset = _x[1];
55
55
  var componentNodeRef = React.useRef(null);
56
56
  var wrapperRef = React.useRef(null);
57
57
  var scrollableNodeRef = React.useRef(null);
@@ -103,6 +103,9 @@ var BaseModal = React.forwardRef(function (_a, ref) {
103
103
  }
104
104
  }, [hasFooter, hasHeader, headerOffset]);
105
105
  var handleClose = React.useCallback(function (event, reason) {
106
+ if (iOSLock && coreComponentsShared.os.isIOS()) {
107
+ helpers_lockScroll.unlockScroll();
108
+ }
106
109
  if (onClose) {
107
110
  onClose(event, reason);
108
111
  }
@@ -113,7 +116,7 @@ var BaseModal = React.forwardRef(function (_a, ref) {
113
116
  onEscapeKeyDown(event);
114
117
  }
115
118
  return null;
116
- }, [onBackdropClick, onClose, onEscapeKeyDown]);
119
+ }, [onBackdropClick, onClose, onEscapeKeyDown, iOSLock]);
117
120
  var handleBackdropMouseDown = function (event) {
118
121
  var _a;
119
122
  var clickedOnScrollbar = false;
@@ -188,7 +191,12 @@ var BaseModal = React.forwardRef(function (_a, ref) {
188
191
  if (open && isExited) {
189
192
  if (!disableBlockingScroll) {
190
193
  var el_1 = getContainer();
191
- utils.handleContainer(el_1);
194
+ var shouldIOSLock = iOSLock && coreComponentsShared.os.isIOS();
195
+ utils.handleContainer(el_1, shouldIOSLock);
196
+ if (shouldIOSLock) {
197
+ helpers_lockScroll.syncHeight();
198
+ helpers_lockScroll.lockScroll();
199
+ }
192
200
  restoreContainerStylesRef.current = function () {
193
201
  restoreContainerStylesRef.current = null;
194
202
  utils.restoreContainerStyles(el_1);
@@ -196,7 +204,7 @@ var BaseModal = React.forwardRef(function (_a, ref) {
196
204
  }
197
205
  setExited(false);
198
206
  }
199
- }, [getContainer, open, disableBlockingScroll, isExited]);
207
+ }, [getContainer, open, disableBlockingScroll, isExited, iOSLock]);
200
208
  React.useEffect(function () {
201
209
  var ResizeObserver = window.ResizeObserver || resizeObserver.ResizeObserver;
202
210
  resizeObserverRef.current = new ResizeObserver(checkToHasScrollBar);
@@ -209,6 +217,12 @@ var BaseModal = React.forwardRef(function (_a, ref) {
209
217
  }
210
218
  };
211
219
  }, []);
220
+ React.useEffect(function () {
221
+ var _a;
222
+ if (disableAutoFocus || !open)
223
+ return;
224
+ (_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.focus();
225
+ }, [open, disableAutoFocus]);
212
226
  var contextValue = React.useMemo(function () { return ({
213
227
  parentRef: wrapperRef,
214
228
  componentRef: componentNodeRef,
@@ -237,7 +251,7 @@ var BaseModal = React.forwardRef(function (_a, ref) {
237
251
  var renderContent = function () { return (React__default.default.createElement(coreComponentsStack.Stack, { value: zIndex }, function (computedZIndex) {
238
252
  var _a;
239
253
  return (React__default.default.createElement(BaseModalContext.Provider, { value: contextValue },
240
- React__default.default.createElement(FocusLock__default.default, { autoFocus: !disableAutoFocus, disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus },
254
+ React__default.default.createElement(FocusLock__default.default, { disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus },
241
255
  Backdrop && (React__default.default.createElement(Backdrop, tslib.__assign({}, backdropProps, { className: cn__default.default(backdropProps.className, styles.backdrop), open: open, style: {
242
256
  zIndex: computedZIndex,
243
257
  } }))),
@@ -247,9 +261,7 @@ var BaseModal = React.forwardRef(function (_a, ref) {
247
261
  ref,
248
262
  wrapperRef,
249
263
  wrapperProps === null || wrapperProps === void 0 ? void 0 : wrapperProps.ref,
250
- ]), onKeyDown: handleKeyDown, onMouseDown: handleBackdropMouseDown, onMouseUp: handleBackdropMouseUp,
251
- // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
252
- tabIndex: 0, "data-test-id": dataTestId, style: {
264
+ ]), onKeyDown: handleKeyDown, onMouseDown: handleBackdropMouseDown, onMouseUp: handleBackdropMouseUp, tabIndex: -1, "data-test-id": dataTestId, style: {
253
265
  zIndex: computedZIndex,
254
266
  } }),
255
267
  React__default.default.createElement(reactTransitionGroup.CSSTransition, tslib.__assign({ appear: true, timeout: 200, classNames: styles, nodeRef: componentNodeRef }, transitionProps, { in: open, onEntered: handleEntered, onExited: handleExited }),
@@ -1,7 +1,7 @@
1
1
  /// <reference types="react" />
2
2
  /// <reference types="react-transition-group" />
3
3
  import React from 'react';
4
- import { FC, KeyboardEvent, MouseEvent, MutableRefObject, ReactNode, Ref } from "react";
4
+ import { ComponentType, KeyboardEvent, MouseEvent, MutableRefObject, ReactNode, Ref } from "react";
5
5
  import { TransitionProps } from 'react-transition-group/Transition';
6
6
  import { BackdropProps } from "@alfalab/core-components-backdrop";
7
7
  import { PortalProps } from "@alfalab/core-components-portal";
@@ -13,7 +13,7 @@ type BaseModalProps = {
13
13
  /**
14
14
  * Компонент бэкдропа
15
15
  */
16
- Backdrop?: FC<BackdropProps>;
16
+ Backdrop?: ComponentType<BackdropProps>;
17
17
  /**
18
18
  * Свойства для Бэкдропа
19
19
  */
@@ -134,6 +134,10 @@ type BaseModalProps = {
134
134
  * Реф, который должен быть установлен компонентной области
135
135
  */
136
136
  componentRef?: MutableRefObject<HTMLDivElement | null>;
137
+ /**
138
+ * Блокирует скролл когда модальное окно открыто. Работает только на iOS.
139
+ */
140
+ iOSLock?: boolean;
137
141
  };
138
142
  type BaseModalContext = {
139
143
  parentRef: React.RefObject<HTMLDivElement>;
package/cssm/Component.js CHANGED
@@ -13,10 +13,10 @@ var coreComponentsBackdrop = require('@alfalab/core-components-backdrop/cssm');
13
13
  var coreComponentsPortal = require('@alfalab/core-components-portal/cssm');
14
14
  var coreComponentsShared = require('@alfalab/core-components-shared/cssm');
15
15
  var coreComponentsStack = require('@alfalab/core-components-stack/cssm');
16
+ var helpers_lockScroll = require('./helpers/lockScroll.js');
16
17
  var utils = require('./utils.js');
17
18
  var styles = require('./index.module.css');
18
19
  require('./matches-polyfill.js');
19
- require('@alfalab/core-components-global-store/cssm');
20
20
 
21
21
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
22
22
 
@@ -43,14 +43,14 @@ var BaseModalContext = React__default.default.createContext({
43
43
  onClose: function () { return null; },
44
44
  });
45
45
  var BaseModal = React.forwardRef(function (_a, ref) {
46
- 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, wrapperProps = _a.wrapperProps, contentProps = _a.contentProps, componentDivProps = _a.componentDivProps, 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, _p = _a.usePortal, usePortal = _p === void 0 ? true : _p;
47
- var _q = React.useState(null), exited = _q[0], setExited = _q[1];
48
- var _r = React.useState(false), hasScroll = _r[0], setHasScroll = _r[1];
49
- var _s = React.useState(false), hasHeader = _s[0], setHasHeader = _s[1];
50
- var _t = React.useState(false), hasFooter = _t[0], setHasFooter = _t[1];
51
- var _u = React.useState(false), headerHighlighted = _u[0], setHeaderHighlighted = _u[1];
52
- var _v = React.useState(false), footerHighlighted = _v[0], setFooterHighlighted = _v[1];
53
- var _w = React.useState(0), headerOffset = _w[0], setHeaderOffset = _w[1];
46
+ 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, wrapperProps = _a.wrapperProps, contentProps = _a.contentProps, componentDivProps = _a.componentDivProps, 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, _p = _a.usePortal, usePortal = _p === void 0 ? true : _p, _q = _a.iOSLock, iOSLock = _q === void 0 ? false : _q;
47
+ var _r = React.useState(null), exited = _r[0], setExited = _r[1];
48
+ var _s = React.useState(false), hasScroll = _s[0], setHasScroll = _s[1];
49
+ var _t = React.useState(false), hasHeader = _t[0], setHasHeader = _t[1];
50
+ var _u = React.useState(false), hasFooter = _u[0], setHasFooter = _u[1];
51
+ var _v = React.useState(false), headerHighlighted = _v[0], setHeaderHighlighted = _v[1];
52
+ var _w = React.useState(false), footerHighlighted = _w[0], setFooterHighlighted = _w[1];
53
+ var _x = React.useState(0), headerOffset = _x[0], setHeaderOffset = _x[1];
54
54
  var componentNodeRef = React.useRef(null);
55
55
  var wrapperRef = React.useRef(null);
56
56
  var scrollableNodeRef = React.useRef(null);
@@ -102,6 +102,9 @@ var BaseModal = React.forwardRef(function (_a, ref) {
102
102
  }
103
103
  }, [hasFooter, hasHeader, headerOffset]);
104
104
  var handleClose = React.useCallback(function (event, reason) {
105
+ if (iOSLock && coreComponentsShared.os.isIOS()) {
106
+ helpers_lockScroll.unlockScroll();
107
+ }
105
108
  if (onClose) {
106
109
  onClose(event, reason);
107
110
  }
@@ -112,7 +115,7 @@ var BaseModal = React.forwardRef(function (_a, ref) {
112
115
  onEscapeKeyDown(event);
113
116
  }
114
117
  return null;
115
- }, [onBackdropClick, onClose, onEscapeKeyDown]);
118
+ }, [onBackdropClick, onClose, onEscapeKeyDown, iOSLock]);
116
119
  var handleBackdropMouseDown = function (event) {
117
120
  var _a;
118
121
  var clickedOnScrollbar = false;
@@ -187,7 +190,12 @@ var BaseModal = React.forwardRef(function (_a, ref) {
187
190
  if (open && isExited) {
188
191
  if (!disableBlockingScroll) {
189
192
  var el_1 = getContainer();
190
- utils.handleContainer(el_1);
193
+ var shouldIOSLock = iOSLock && coreComponentsShared.os.isIOS();
194
+ utils.handleContainer(el_1, shouldIOSLock);
195
+ if (shouldIOSLock) {
196
+ helpers_lockScroll.syncHeight();
197
+ helpers_lockScroll.lockScroll();
198
+ }
191
199
  restoreContainerStylesRef.current = function () {
192
200
  restoreContainerStylesRef.current = null;
193
201
  utils.restoreContainerStyles(el_1);
@@ -195,7 +203,7 @@ var BaseModal = React.forwardRef(function (_a, ref) {
195
203
  }
196
204
  setExited(false);
197
205
  }
198
- }, [getContainer, open, disableBlockingScroll, isExited]);
206
+ }, [getContainer, open, disableBlockingScroll, isExited, iOSLock]);
199
207
  React.useEffect(function () {
200
208
  var ResizeObserver = window.ResizeObserver || resizeObserver.ResizeObserver;
201
209
  resizeObserverRef.current = new ResizeObserver(checkToHasScrollBar);
@@ -208,6 +216,12 @@ var BaseModal = React.forwardRef(function (_a, ref) {
208
216
  }
209
217
  };
210
218
  }, []);
219
+ React.useEffect(function () {
220
+ var _a;
221
+ if (disableAutoFocus || !open)
222
+ return;
223
+ (_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.focus();
224
+ }, [open, disableAutoFocus]);
211
225
  var contextValue = React.useMemo(function () { return ({
212
226
  parentRef: wrapperRef,
213
227
  componentRef: componentNodeRef,
@@ -236,7 +250,7 @@ var BaseModal = React.forwardRef(function (_a, ref) {
236
250
  var renderContent = function () { return (React__default.default.createElement(coreComponentsStack.Stack, { value: zIndex }, function (computedZIndex) {
237
251
  var _a;
238
252
  return (React__default.default.createElement(BaseModalContext.Provider, { value: contextValue },
239
- React__default.default.createElement(FocusLock__default.default, { autoFocus: !disableAutoFocus, disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus },
253
+ React__default.default.createElement(FocusLock__default.default, { disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus },
240
254
  Backdrop && (React__default.default.createElement(Backdrop, tslib.__assign({}, backdropProps, { className: cn__default.default(backdropProps.className, styles__default.default.backdrop), open: open, style: {
241
255
  zIndex: computedZIndex,
242
256
  } }))),
@@ -246,9 +260,7 @@ var BaseModal = React.forwardRef(function (_a, ref) {
246
260
  ref,
247
261
  wrapperRef,
248
262
  wrapperProps === null || wrapperProps === void 0 ? void 0 : wrapperProps.ref,
249
- ]), onKeyDown: handleKeyDown, onMouseDown: handleBackdropMouseDown, onMouseUp: handleBackdropMouseUp,
250
- // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
251
- tabIndex: 0, "data-test-id": dataTestId, style: {
263
+ ]), onKeyDown: handleKeyDown, onMouseDown: handleBackdropMouseDown, onMouseUp: handleBackdropMouseUp, tabIndex: -1, "data-test-id": dataTestId, style: {
252
264
  zIndex: computedZIndex,
253
265
  } }),
254
266
  React__default.default.createElement(reactTransitionGroup.CSSTransition, tslib.__assign({ appear: true, timeout: 200, classNames: styles__default.default, nodeRef: componentNodeRef }, transitionProps, { in: open, onEntered: handleEntered, onExited: handleExited }),
@@ -0,0 +1,4 @@
1
+ declare const lockScroll: () => void;
2
+ declare const unlockScroll: () => void;
3
+ declare const syncHeight: () => void;
4
+ export { lockScroll, unlockScroll, syncHeight };
@@ -0,0 +1,20 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var scrollY;
6
+ var lockScroll = function () {
7
+ scrollY = window.scrollY;
8
+ document.body.classList.add('is-locked');
9
+ };
10
+ var unlockScroll = function () {
11
+ document.body.classList.remove('is-locked');
12
+ window.scrollTo(0, scrollY);
13
+ };
14
+ var syncHeight = function () {
15
+ document.body.style.setProperty('--window-inner-scrollY', "".concat(window.scrollY, "px"));
16
+ };
17
+
18
+ exports.lockScroll = lockScroll;
19
+ exports.syncHeight = syncHeight;
20
+ exports.unlockScroll = unlockScroll;
package/cssm/index.js CHANGED
@@ -4,20 +4,6 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var Component = require('./Component.js');
6
6
  var utils = require('./utils.js');
7
- require('tslib');
8
- require('react');
9
- require('react-focus-lock');
10
- require('react-merge-refs');
11
- require('react-transition-group');
12
- require('@juggle/resize-observer');
13
- require('classnames');
14
- require('@alfalab/core-components-backdrop/cssm');
15
- require('@alfalab/core-components-portal/cssm');
16
- require('@alfalab/core-components-shared/cssm');
17
- require('@alfalab/core-components-stack/cssm');
18
- require('./index.module.css');
19
- require('./matches-polyfill.js');
20
- require('@alfalab/core-components-global-store/cssm');
21
7
 
22
8
 
23
9
 
@@ -1,4 +1,4 @@
1
- :root {
1
+ :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
2
2
  } /* deprecated */ :root {
3
3
  --color-light-modal-bg-primary: #fff; /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
4
4
  } :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
@@ -14,6 +14,12 @@
14
14
  } :root {
15
15
  } :root {
16
16
  } :root {
17
+ } :root {
18
+ --window-inner-scrollY: 10px; /* fallback value to prevent ci error */
19
+ } body:global(.is-locked) {
20
+ margin-top: calc(var(--window-inner-scrollY) * -1);
21
+ position: fixed;
22
+ overflow: hidden;
17
23
  } .component {
18
24
  position: relative;
19
25
  box-sizing: border-box;
package/cssm/utils.d.ts CHANGED
@@ -2,5 +2,5 @@ declare function isScrolledToTop(target: HTMLElement): boolean;
2
2
  declare function isScrolledToBottom(target: HTMLElement): boolean;
3
3
  declare function hasScrollbar(target: HTMLElement): boolean;
4
4
  declare const restoreContainerStyles: (container: HTMLElement) => void;
5
- declare const handleContainer: (container?: HTMLElement) => void;
5
+ declare const handleContainer: (container?: HTMLElement, shouldIOSLock?: boolean) => void;
6
6
  export { isScrolledToTop, isScrolledToBottom, hasScrollbar, restoreContainerStyles, handleContainer };
package/cssm/utils.js CHANGED
@@ -43,7 +43,8 @@ var restoreContainerStyles = function (container) {
43
43
  });
44
44
  }
45
45
  };
46
- var handleContainer = function (container) {
46
+ var handleContainer = function (container, shouldIOSLock) {
47
+ if (shouldIOSLock === void 0) { shouldIOSLock = false; }
47
48
  if (!container)
48
49
  return;
49
50
  var modalRestoreStyles = coreComponentsGlobalStore.getModalStore().getRestoreStyles();
@@ -81,7 +82,9 @@ var handleContainer = function (container) {
81
82
  el: scrollContainer,
82
83
  });
83
84
  }
84
- scrollContainer.style.overflow = 'hidden';
85
+ if (!shouldIOSLock) {
86
+ scrollContainer.style.overflow = 'hidden';
87
+ }
85
88
  modalRestoreStyles.push({
86
89
  container: container,
87
90
  modals: 1,
@@ -1,7 +1,7 @@
1
1
  /// <reference types="react" />
2
2
  /// <reference types="react-transition-group" />
3
3
  import React from 'react';
4
- import { FC, KeyboardEvent, MouseEvent, MutableRefObject, ReactNode, Ref } from "react";
4
+ import { ComponentType, KeyboardEvent, MouseEvent, MutableRefObject, ReactNode, Ref } from "react";
5
5
  import { TransitionProps } from 'react-transition-group/Transition';
6
6
  import { BackdropProps } from "@alfalab/core-components-backdrop";
7
7
  import { PortalProps } from "@alfalab/core-components-portal";
@@ -13,7 +13,7 @@ type BaseModalProps = {
13
13
  /**
14
14
  * Компонент бэкдропа
15
15
  */
16
- Backdrop?: FC<BackdropProps>;
16
+ Backdrop?: ComponentType<BackdropProps>;
17
17
  /**
18
18
  * Свойства для Бэкдропа
19
19
  */
@@ -134,6 +134,10 @@ type BaseModalProps = {
134
134
  * Реф, который должен быть установлен компонентной области
135
135
  */
136
136
  componentRef?: MutableRefObject<HTMLDivElement | null>;
137
+ /**
138
+ * Блокирует скролл когда модальное окно открыто. Работает только на iOS.
139
+ */
140
+ iOSLock?: boolean;
137
141
  };
138
142
  type BaseModalContext = {
139
143
  parentRef: React.RefObject<HTMLDivElement>;
package/esm/Component.js CHANGED
@@ -7,13 +7,13 @@ import { ResizeObserver } from '@juggle/resize-observer';
7
7
  import cn from 'classnames';
8
8
  import { Backdrop } from '@alfalab/core-components-backdrop/esm';
9
9
  import { Portal } from '@alfalab/core-components-portal/esm';
10
- import { browser } from '@alfalab/core-components-shared/esm';
10
+ import { os, browser } from '@alfalab/core-components-shared/esm';
11
11
  import { stackingOrder, Stack } from '@alfalab/core-components-stack/esm';
12
+ import { unlockScroll, syncHeight, lockScroll } from './helpers/lockScroll.js';
12
13
  import { isScrolledToTop, isScrolledToBottom, handleContainer, restoreContainerStyles, hasScrollbar } from './utils.js';
13
14
  import './matches-polyfill.js';
14
- import '@alfalab/core-components-global-store/esm';
15
15
 
16
- var styles = {"component":"base-modal__component_1b68o","wrapper":"base-modal__wrapper_1b68o","content":"base-modal__content_1b68o","hidden":"base-modal__hidden_1b68o","backdrop":"base-modal__backdrop_1b68o","appear":"base-modal__appear_1b68o","enter":"base-modal__enter_1b68o","appearActive":"base-modal__appearActive_1b68o","enterActive":"base-modal__enterActive_1b68o","exit":"base-modal__exit_1b68o","exitActive":"base-modal__exitActive_1b68o","exitDone":"base-modal__exitDone_1b68o"};
16
+ var styles = {"component":"base-modal__component_1apcq","wrapper":"base-modal__wrapper_1apcq","content":"base-modal__content_1apcq","hidden":"base-modal__hidden_1apcq","backdrop":"base-modal__backdrop_1apcq","appear":"base-modal__appear_1apcq","enter":"base-modal__enter_1apcq","appearActive":"base-modal__appearActive_1apcq","enterActive":"base-modal__enterActive_1apcq","exit":"base-modal__exit_1apcq","exitActive":"base-modal__exitActive_1apcq","exitDone":"base-modal__exitDone_1apcq"};
17
17
  require('./index.css')
18
18
 
19
19
  // eslint-disable-next-line @typescript-eslint/no-redeclare
@@ -33,14 +33,14 @@ var BaseModalContext = React.createContext({
33
33
  onClose: function () { return null; },
34
34
  });
35
35
  var BaseModal = forwardRef(function (_a, ref) {
36
- 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, wrapperProps = _a.wrapperProps, contentProps = _a.contentProps, componentDivProps = _a.componentDivProps, 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, _p = _a.usePortal, usePortal = _p === void 0 ? true : _p;
37
- var _q = useState(null), exited = _q[0], setExited = _q[1];
38
- var _r = useState(false), hasScroll = _r[0], setHasScroll = _r[1];
39
- var _s = useState(false), hasHeader = _s[0], setHasHeader = _s[1];
40
- var _t = useState(false), hasFooter = _t[0], setHasFooter = _t[1];
41
- var _u = useState(false), headerHighlighted = _u[0], setHeaderHighlighted = _u[1];
42
- var _v = useState(false), footerHighlighted = _v[0], setFooterHighlighted = _v[1];
43
- var _w = useState(0), headerOffset = _w[0], setHeaderOffset = _w[1];
36
+ 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, wrapperProps = _a.wrapperProps, contentProps = _a.contentProps, componentDivProps = _a.componentDivProps, 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, _p = _a.usePortal, usePortal = _p === void 0 ? true : _p, _q = _a.iOSLock, iOSLock = _q === void 0 ? false : _q;
37
+ var _r = useState(null), exited = _r[0], setExited = _r[1];
38
+ var _s = useState(false), hasScroll = _s[0], setHasScroll = _s[1];
39
+ var _t = useState(false), hasHeader = _t[0], setHasHeader = _t[1];
40
+ var _u = useState(false), hasFooter = _u[0], setHasFooter = _u[1];
41
+ var _v = useState(false), headerHighlighted = _v[0], setHeaderHighlighted = _v[1];
42
+ var _w = useState(false), footerHighlighted = _w[0], setFooterHighlighted = _w[1];
43
+ var _x = useState(0), headerOffset = _x[0], setHeaderOffset = _x[1];
44
44
  var componentNodeRef = useRef(null);
45
45
  var wrapperRef = useRef(null);
46
46
  var scrollableNodeRef = useRef(null);
@@ -92,6 +92,9 @@ var BaseModal = forwardRef(function (_a, ref) {
92
92
  }
93
93
  }, [hasFooter, hasHeader, headerOffset]);
94
94
  var handleClose = useCallback(function (event, reason) {
95
+ if (iOSLock && os.isIOS()) {
96
+ unlockScroll();
97
+ }
95
98
  if (onClose) {
96
99
  onClose(event, reason);
97
100
  }
@@ -102,7 +105,7 @@ var BaseModal = forwardRef(function (_a, ref) {
102
105
  onEscapeKeyDown(event);
103
106
  }
104
107
  return null;
105
- }, [onBackdropClick, onClose, onEscapeKeyDown]);
108
+ }, [onBackdropClick, onClose, onEscapeKeyDown, iOSLock]);
106
109
  var handleBackdropMouseDown = function (event) {
107
110
  var _a;
108
111
  var clickedOnScrollbar = false;
@@ -177,7 +180,12 @@ var BaseModal = forwardRef(function (_a, ref) {
177
180
  if (open && isExited) {
178
181
  if (!disableBlockingScroll) {
179
182
  var el_1 = getContainer();
180
- handleContainer(el_1);
183
+ var shouldIOSLock = iOSLock && os.isIOS();
184
+ handleContainer(el_1, shouldIOSLock);
185
+ if (shouldIOSLock) {
186
+ syncHeight();
187
+ lockScroll();
188
+ }
181
189
  restoreContainerStylesRef.current = function () {
182
190
  restoreContainerStylesRef.current = null;
183
191
  restoreContainerStyles(el_1);
@@ -185,7 +193,7 @@ var BaseModal = forwardRef(function (_a, ref) {
185
193
  }
186
194
  setExited(false);
187
195
  }
188
- }, [getContainer, open, disableBlockingScroll, isExited]);
196
+ }, [getContainer, open, disableBlockingScroll, isExited, iOSLock]);
189
197
  useEffect(function () {
190
198
  var ResizeObserver$1 = window.ResizeObserver || ResizeObserver;
191
199
  resizeObserverRef.current = new ResizeObserver$1(checkToHasScrollBar);
@@ -198,6 +206,12 @@ var BaseModal = forwardRef(function (_a, ref) {
198
206
  }
199
207
  };
200
208
  }, []);
209
+ useEffect(function () {
210
+ var _a;
211
+ if (disableAutoFocus || !open)
212
+ return;
213
+ (_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.focus();
214
+ }, [open, disableAutoFocus]);
201
215
  var contextValue = useMemo(function () { return ({
202
216
  parentRef: wrapperRef,
203
217
  componentRef: componentNodeRef,
@@ -226,7 +240,7 @@ var BaseModal = forwardRef(function (_a, ref) {
226
240
  var renderContent = function () { return (React.createElement(Stack, { value: zIndex }, function (computedZIndex) {
227
241
  var _a;
228
242
  return (React.createElement(BaseModalContext.Provider, { value: contextValue },
229
- React.createElement(FocusLock, { autoFocus: !disableAutoFocus, disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus },
243
+ React.createElement(FocusLock, { disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus },
230
244
  Backdrop$1 && (React.createElement(Backdrop$1, __assign({}, backdropProps, { className: cn(backdropProps.className, styles.backdrop), open: open, style: {
231
245
  zIndex: computedZIndex,
232
246
  } }))),
@@ -236,9 +250,7 @@ var BaseModal = forwardRef(function (_a, ref) {
236
250
  ref,
237
251
  wrapperRef,
238
252
  wrapperProps === null || wrapperProps === void 0 ? void 0 : wrapperProps.ref,
239
- ]), onKeyDown: handleKeyDown, onMouseDown: handleBackdropMouseDown, onMouseUp: handleBackdropMouseUp,
240
- // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
241
- tabIndex: 0, "data-test-id": dataTestId, style: {
253
+ ]), onKeyDown: handleKeyDown, onMouseDown: handleBackdropMouseDown, onMouseUp: handleBackdropMouseUp, tabIndex: -1, "data-test-id": dataTestId, style: {
242
254
  zIndex: computedZIndex,
243
255
  } }),
244
256
  React.createElement(CSSTransition, __assign({ appear: true, timeout: 200, classNames: styles, nodeRef: componentNodeRef }, transitionProps, { in: open, onEntered: handleEntered, onExited: handleExited }),
@@ -0,0 +1,4 @@
1
+ declare const lockScroll: () => void;
2
+ declare const unlockScroll: () => void;
3
+ declare const syncHeight: () => void;
4
+ export { lockScroll, unlockScroll, syncHeight };
@@ -0,0 +1,14 @@
1
+ var scrollY;
2
+ var lockScroll = function () {
3
+ scrollY = window.scrollY;
4
+ document.body.classList.add('is-locked');
5
+ };
6
+ var unlockScroll = function () {
7
+ document.body.classList.remove('is-locked');
8
+ window.scrollTo(0, scrollY);
9
+ };
10
+ var syncHeight = function () {
11
+ document.body.style.setProperty('--window-inner-scrollY', "".concat(window.scrollY, "px"));
12
+ };
13
+
14
+ export { lockScroll, syncHeight, unlockScroll };