@alfalab/core-components-base-modal 3.0.1 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/dist/Component.d.ts +4 -0
- package/dist/Component.js +36 -27
- package/dist/cssm/Component.d.ts +4 -0
- package/dist/cssm/Component.js +35 -26
- package/dist/cssm/index.js +2 -0
- package/dist/cssm/index.module.css +1 -1
- package/dist/cssm/utils.d.ts +3 -2
- package/dist/cssm/utils.js +39 -14
- package/dist/esm/Component.d.ts +4 -0
- package/dist/esm/Component.js +38 -29
- package/dist/esm/index.css +14 -14
- package/dist/esm/index.js +2 -1
- package/dist/esm/utils.d.ts +3 -2
- package/dist/esm/utils.js +39 -15
- package/dist/index.css +14 -14
- package/dist/index.js +2 -0
- package/dist/modern/Component.d.ts +4 -0
- package/dist/modern/Component.js +32 -23
- package/dist/modern/index.css +14 -14
- package/dist/modern/index.js +2 -1
- package/dist/modern/utils.d.ts +3 -2
- package/dist/modern/utils.js +38 -14
- package/dist/utils.d.ts +3 -2
- package/dist/utils.js +39 -14
- package/package.json +3 -2
package/dist/esm/Component.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { forwardRef, useState, useRef,
|
|
1
|
+
import React, { forwardRef, useState, useRef, useCallback, useMemo, useEffect } from 'react';
|
|
2
2
|
import cn from 'classnames';
|
|
3
3
|
import mergeRefs from 'react-merge-refs';
|
|
4
4
|
import { ResizeObserver } from 'resize-observer';
|
|
@@ -7,7 +7,8 @@ import FocusLock from 'react-focus-lock';
|
|
|
7
7
|
import { Portal } from '@alfalab/core-components-portal/dist/esm';
|
|
8
8
|
import { Backdrop } from '@alfalab/core-components-backdrop/dist/esm';
|
|
9
9
|
import { stackingOrder, Stack } from '@alfalab/core-components-stack/dist/esm';
|
|
10
|
-
import
|
|
10
|
+
import '@alfalab/core-components-global-store/dist/esm';
|
|
11
|
+
import { isScrolledToTop, isScrolledToBottom, handleContainer, restoreContainerStyles, hasScrollbar } from './utils.js';
|
|
11
12
|
|
|
12
13
|
/*! *****************************************************************************
|
|
13
14
|
Copyright (c) Microsoft Corporation.
|
|
@@ -36,7 +37,7 @@ var __assign = function () {
|
|
|
36
37
|
return __assign.apply(this, arguments);
|
|
37
38
|
};
|
|
38
39
|
|
|
39
|
-
var styles = {"component":"base-
|
|
40
|
+
var styles = {"component":"base-modal__component_pvkw5","wrapper":"base-modal__wrapper_pvkw5","content":"base-modal__content_pvkw5","hidden":"base-modal__hidden_pvkw5","backdrop":"base-modal__backdrop_pvkw5","appear":"base-modal__appear_pvkw5","enter":"base-modal__enter_pvkw5","appearActive":"base-modal__appearActive_pvkw5","enterActive":"base-modal__enterActive_pvkw5","exit":"base-modal__exit_pvkw5","exitActive":"base-modal__exitActive_pvkw5","exitDone":"base-modal__exitDone_pvkw5"};
|
|
40
41
|
require('./index.css')
|
|
41
42
|
|
|
42
43
|
var BaseModalContext = React.createContext({
|
|
@@ -51,18 +52,18 @@ var BaseModalContext = React.createContext({
|
|
|
51
52
|
onClose: function () { return null; },
|
|
52
53
|
});
|
|
53
54
|
var BaseModal = forwardRef(function (_a, ref) {
|
|
54
|
-
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;
|
|
55
|
-
var
|
|
56
|
-
var
|
|
57
|
-
var
|
|
58
|
-
var
|
|
59
|
-
var
|
|
60
|
-
var
|
|
61
|
-
var
|
|
55
|
+
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;
|
|
56
|
+
var _o = useState(!open), exited = _o[0], setExited = _o[1];
|
|
57
|
+
var _p = useState(false), hasScroll = _p[0], setHasScroll = _p[1];
|
|
58
|
+
var _q = useState(false), hasHeader = _q[0], setHasHeader = _q[1];
|
|
59
|
+
var _r = useState(false), hasFooter = _r[0], setHasFooter = _r[1];
|
|
60
|
+
var _s = useState(false), headerHighlighted = _s[0], setHeaderHighlighted = _s[1];
|
|
61
|
+
var _t = useState(false), footerHighlighted = _t[0], setFooterHighlighted = _t[1];
|
|
62
|
+
var componentNodeRef = useRef(null);
|
|
62
63
|
var wrapperRef = useRef(null);
|
|
63
64
|
var scrollableNodeRef = useRef(null);
|
|
64
65
|
var contentNodeRef = useRef(null);
|
|
65
|
-
var
|
|
66
|
+
var restoreContainerStylesRef = useRef(null);
|
|
66
67
|
var checkToHasScrollBar = function () {
|
|
67
68
|
if (scrollableNodeRef.current) {
|
|
68
69
|
var scrollExists = hasScrollbar(scrollableNodeRef.current);
|
|
@@ -71,6 +72,9 @@ var BaseModal = forwardRef(function (_a, ref) {
|
|
|
71
72
|
}
|
|
72
73
|
};
|
|
73
74
|
var shouldRender = keepMounted || open || !exited;
|
|
75
|
+
var getContainer = useCallback(function () {
|
|
76
|
+
return (container ? container() : document.body);
|
|
77
|
+
}, [container]);
|
|
74
78
|
var resizeObserver = useMemo(function () { return new ResizeObserver(checkToHasScrollBar); }, []);
|
|
75
79
|
var addResizeHandle = useCallback(function () {
|
|
76
80
|
if (scrollableNodeRef.current)
|
|
@@ -89,15 +93,16 @@ var BaseModal = forwardRef(function (_a, ref) {
|
|
|
89
93
|
}
|
|
90
94
|
}, [resizeObserver]);
|
|
91
95
|
var handleScroll = useCallback(function () {
|
|
92
|
-
if (!scrollableNodeRef.current || !
|
|
96
|
+
if (!scrollableNodeRef.current || !componentNodeRef.current)
|
|
93
97
|
return;
|
|
94
98
|
if (hasHeader) {
|
|
95
99
|
setHeaderHighlighted(!isScrolledToTop(scrollableNodeRef.current) &&
|
|
96
|
-
|
|
100
|
+
componentNodeRef.current.getBoundingClientRect().top <= 0);
|
|
97
101
|
}
|
|
98
102
|
if (hasFooter) {
|
|
99
103
|
setFooterHighlighted(!isScrolledToBottom(scrollableNodeRef.current) &&
|
|
100
|
-
|
|
104
|
+
componentNodeRef.current.getBoundingClientRect().bottom >=
|
|
105
|
+
window.innerHeight);
|
|
101
106
|
}
|
|
102
107
|
}, [hasFooter, hasHeader]);
|
|
103
108
|
var handleClose = useCallback(function (event, reason) {
|
|
@@ -113,7 +118,7 @@ var BaseModal = forwardRef(function (_a, ref) {
|
|
|
113
118
|
return null;
|
|
114
119
|
}, [onBackdropClick, onClose, onEscapeKeyDown]);
|
|
115
120
|
var handleBackdropClick = function (event) {
|
|
116
|
-
if (!disableBackdropClick) {
|
|
121
|
+
if (!disableBackdropClick && event.target === wrapperRef.current) {
|
|
117
122
|
handleClose(event, 'backdropClick');
|
|
118
123
|
}
|
|
119
124
|
};
|
|
@@ -135,7 +140,7 @@ var BaseModal = forwardRef(function (_a, ref) {
|
|
|
135
140
|
if (scrollHandler === 'wrapper')
|
|
136
141
|
return wrapperRef.current;
|
|
137
142
|
if (scrollHandler === 'content')
|
|
138
|
-
return
|
|
143
|
+
return componentNodeRef.current;
|
|
139
144
|
return scrollHandler.current || wrapperRef.current;
|
|
140
145
|
}, [scrollHandler]);
|
|
141
146
|
var handleEntered = useCallback(function (node, isAppearing) {
|
|
@@ -162,27 +167,29 @@ var BaseModal = forwardRef(function (_a, ref) {
|
|
|
162
167
|
}
|
|
163
168
|
if (onUnmount)
|
|
164
169
|
onUnmount();
|
|
165
|
-
if (
|
|
166
|
-
|
|
167
|
-
restoreContainerStyles.current = null;
|
|
170
|
+
if (restoreContainerStylesRef.current) {
|
|
171
|
+
restoreContainerStylesRef.current();
|
|
168
172
|
}
|
|
169
173
|
}, [handleScroll, onUnmount, removeResizeHandle, transitionProps]);
|
|
170
174
|
useEffect(function () {
|
|
171
175
|
if (open) {
|
|
172
|
-
|
|
176
|
+
handleContainer(getContainer());
|
|
177
|
+
restoreContainerStylesRef.current = function () {
|
|
178
|
+
restoreContainerStylesRef.current = null;
|
|
179
|
+
restoreContainerStyles(getContainer());
|
|
180
|
+
};
|
|
173
181
|
}
|
|
174
|
-
|
|
175
|
-
}, [open]);
|
|
182
|
+
}, [getContainer, open]);
|
|
176
183
|
useEffect(function () {
|
|
177
184
|
if (open)
|
|
178
185
|
setExited(false);
|
|
179
186
|
}, [open]);
|
|
180
187
|
useEffect(function () {
|
|
181
188
|
return function () {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
restoreContainerStyles.current();
|
|
189
|
+
if (restoreContainerStylesRef.current) {
|
|
190
|
+
restoreContainerStylesRef.current();
|
|
185
191
|
}
|
|
192
|
+
resizeObserver.disconnect();
|
|
186
193
|
};
|
|
187
194
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
188
195
|
}, []);
|
|
@@ -212,14 +219,16 @@ var BaseModal = forwardRef(function (_a, ref) {
|
|
|
212
219
|
return (React.createElement(Portal, { getPortalContainer: container },
|
|
213
220
|
React.createElement(BaseModalContext.Provider, { value: contextValue },
|
|
214
221
|
React.createElement(FocusLock, { autoFocus: !disableAutoFocus, disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus },
|
|
222
|
+
Backdrop$1 && (React.createElement(Backdrop$1, __assign({}, backdropProps, { className: cn(backdropProps.className, styles.backdrop), open: open, style: {
|
|
223
|
+
zIndex: computedZIndex,
|
|
224
|
+
} }))),
|
|
215
225
|
React.createElement("div", { role: 'dialog', className: cn(styles.wrapper, wrapperClassName, (_a = {},
|
|
216
226
|
_a[styles.hidden] = !open && exited,
|
|
217
|
-
_a)), ref: mergeRefs([ref, wrapperRef]), onKeyDown: handleKeyDown, tabIndex: -1, "data-test-id": dataTestId, style: {
|
|
227
|
+
_a)), ref: mergeRefs([ref, wrapperRef]), onKeyDown: handleKeyDown, onClick: handleBackdropClick, tabIndex: -1, "data-test-id": dataTestId, style: {
|
|
218
228
|
zIndex: computedZIndex,
|
|
219
229
|
} },
|
|
220
|
-
Backdrop$1 && (React.createElement(Backdrop$1, __assign({}, backdropProps, { className: cn(backdropProps.className, styles.backdrop), open: open, onClick: handleBackdropClick }))),
|
|
221
230
|
React.createElement(CSSTransition, __assign({ appear: true, timeout: 200, classNames: styles }, transitionProps, { in: open, onEntered: handleEntered, onExited: handleExited }),
|
|
222
|
-
React.createElement("div", { className: cn(styles.component, className), ref: componentRef },
|
|
231
|
+
React.createElement("div", { className: cn(styles.component, className), ref: mergeRefs([componentRef, componentNodeRef]) },
|
|
223
232
|
React.createElement("div", { className: cn(styles.content, contentClassName) }, children))))))));
|
|
224
233
|
}));
|
|
225
234
|
});
|
package/dist/esm/index.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* hash:
|
|
1
|
+
/* hash: zuxb3 */
|
|
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-
|
|
13
|
+
.base-modal__component_pvkw5 {
|
|
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-
|
|
20
|
+
.base-modal__wrapper_pvkw5 {
|
|
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-
|
|
33
|
+
.base-modal__content_pvkw5 {
|
|
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-
|
|
40
|
+
.base-modal__hidden_pvkw5 {
|
|
41
41
|
display: none;
|
|
42
42
|
}
|
|
43
|
-
.base-
|
|
44
|
-
z-index:
|
|
43
|
+
.base-modal__backdrop_pvkw5 {
|
|
44
|
+
z-index: 0;
|
|
45
45
|
}
|
|
46
|
-
.base-
|
|
47
|
-
.base-
|
|
46
|
+
.base-modal__appear_pvkw5,
|
|
47
|
+
.base-modal__enter_pvkw5 {
|
|
48
48
|
opacity: 0;
|
|
49
49
|
}
|
|
50
|
-
.base-
|
|
51
|
-
.base-
|
|
50
|
+
.base-modal__appearActive_pvkw5,
|
|
51
|
+
.base-modal__enterActive_pvkw5 {
|
|
52
52
|
opacity: 1;
|
|
53
53
|
transition: opacity 200ms ease-in;
|
|
54
54
|
}
|
|
55
|
-
.base-
|
|
55
|
+
.base-modal__exit_pvkw5 {
|
|
56
56
|
opacity: 1;
|
|
57
57
|
}
|
|
58
|
-
.base-
|
|
59
|
-
.base-
|
|
58
|
+
.base-modal__exitActive_pvkw5,
|
|
59
|
+
.base-modal__exitDone_pvkw5 {
|
|
60
60
|
opacity: 0;
|
|
61
61
|
transition: opacity 200ms ease-out;
|
|
62
62
|
}
|
package/dist/esm/index.js
CHANGED
|
@@ -8,4 +8,5 @@ import 'react-focus-lock';
|
|
|
8
8
|
import '@alfalab/core-components-portal/dist/esm';
|
|
9
9
|
import '@alfalab/core-components-backdrop/dist/esm';
|
|
10
10
|
import '@alfalab/core-components-stack/dist/esm';
|
|
11
|
-
|
|
11
|
+
import '@alfalab/core-components-global-store/dist/esm';
|
|
12
|
+
export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles } from './utils.js';
|
package/dist/esm/utils.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
declare function isScrolledToTop(target: HTMLElement): boolean;
|
|
2
2
|
declare function isScrolledToBottom(target: HTMLElement): boolean;
|
|
3
3
|
declare function hasScrollbar(target: HTMLElement): boolean;
|
|
4
|
-
declare const
|
|
5
|
-
|
|
4
|
+
declare const restoreContainerStyles: (container: HTMLElement) => void;
|
|
5
|
+
declare const handleContainer: (container?: HTMLElement | undefined) => void;
|
|
6
|
+
export { isScrolledToTop, isScrolledToBottom, hasScrollbar, restoreContainerStyles, handleContainer };
|
package/dist/esm/utils.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { getModalStore } from '@alfalab/core-components-global-store/dist/esm';
|
|
2
|
+
|
|
1
3
|
function isScrolledToTop(target) {
|
|
2
4
|
return target.scrollTop <= 0;
|
|
3
5
|
}
|
|
@@ -28,12 +30,40 @@ var isOverflowing = function (container) {
|
|
|
28
30
|
var getPaddingRight = function (node) {
|
|
29
31
|
return parseInt(window.getComputedStyle(node).paddingRight, 10) || 0;
|
|
30
32
|
};
|
|
33
|
+
var restoreContainerStyles = function (container) {
|
|
34
|
+
var modalRestoreStyles = getModalStore().getRestoreStyles();
|
|
35
|
+
var index = modalRestoreStyles.findIndex(function (s) { return s.container === container; });
|
|
36
|
+
var existingStyles = modalRestoreStyles[index];
|
|
37
|
+
if (!existingStyles)
|
|
38
|
+
return;
|
|
39
|
+
existingStyles.modals -= 1;
|
|
40
|
+
if (existingStyles.modals <= 0) {
|
|
41
|
+
modalRestoreStyles.splice(index, 1);
|
|
42
|
+
existingStyles.styles.forEach(function (_a) {
|
|
43
|
+
var value = _a.value, el = _a.el, key = _a.key;
|
|
44
|
+
if (value) {
|
|
45
|
+
el.style.setProperty(key, value);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
el.style.removeProperty(key);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
};
|
|
31
53
|
var handleContainer = function (container) {
|
|
32
|
-
|
|
54
|
+
if (!container)
|
|
55
|
+
return;
|
|
56
|
+
var modalRestoreStyles = getModalStore().getRestoreStyles();
|
|
57
|
+
var existingStyles = modalRestoreStyles.find(function (s) { return s.container === container; });
|
|
58
|
+
if (existingStyles) {
|
|
59
|
+
existingStyles.modals += 1;
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
var containerStyles = [];
|
|
33
63
|
if (isOverflowing(container)) {
|
|
34
64
|
// Вычисляет размер до применения `overflow hidden` для избежания скачков
|
|
35
65
|
var scrollbarSize = getScrollbarSize();
|
|
36
|
-
|
|
66
|
+
containerStyles.push({
|
|
37
67
|
value: container.style.paddingRight,
|
|
38
68
|
key: 'padding-right',
|
|
39
69
|
el: container,
|
|
@@ -52,24 +82,18 @@ var handleContainer = function (container) {
|
|
|
52
82
|
: container;
|
|
53
83
|
// Блокируем скролл даже если отсутствует скроллбар
|
|
54
84
|
if (scrollContainer.style.overflow !== 'hidden') {
|
|
55
|
-
|
|
85
|
+
containerStyles.push({
|
|
56
86
|
value: scrollContainer.style.overflow,
|
|
57
87
|
key: 'overflow',
|
|
58
88
|
el: scrollContainer,
|
|
59
89
|
});
|
|
60
90
|
}
|
|
61
91
|
scrollContainer.style.overflow = 'hidden';
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
el.style.removeProperty(key);
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
};
|
|
92
|
+
modalRestoreStyles.push({
|
|
93
|
+
container: container,
|
|
94
|
+
modals: 1,
|
|
95
|
+
styles: containerStyles,
|
|
96
|
+
});
|
|
73
97
|
};
|
|
74
98
|
|
|
75
|
-
export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop };
|
|
99
|
+
export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles };
|
package/dist/index.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* hash:
|
|
1
|
+
/* hash: zuxb3 */
|
|
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-
|
|
13
|
+
.base-modal__component_pvkw5 {
|
|
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-
|
|
20
|
+
.base-modal__wrapper_pvkw5 {
|
|
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-
|
|
33
|
+
.base-modal__content_pvkw5 {
|
|
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-
|
|
40
|
+
.base-modal__hidden_pvkw5 {
|
|
41
41
|
display: none;
|
|
42
42
|
}
|
|
43
|
-
.base-
|
|
44
|
-
z-index:
|
|
43
|
+
.base-modal__backdrop_pvkw5 {
|
|
44
|
+
z-index: 0;
|
|
45
45
|
}
|
|
46
|
-
.base-
|
|
47
|
-
.base-
|
|
46
|
+
.base-modal__appear_pvkw5,
|
|
47
|
+
.base-modal__enter_pvkw5 {
|
|
48
48
|
opacity: 0;
|
|
49
49
|
}
|
|
50
|
-
.base-
|
|
51
|
-
.base-
|
|
50
|
+
.base-modal__appearActive_pvkw5,
|
|
51
|
+
.base-modal__enterActive_pvkw5 {
|
|
52
52
|
opacity: 1;
|
|
53
53
|
transition: opacity 200ms ease-in;
|
|
54
54
|
}
|
|
55
|
-
.base-
|
|
55
|
+
.base-modal__exit_pvkw5 {
|
|
56
56
|
opacity: 1;
|
|
57
57
|
}
|
|
58
|
-
.base-
|
|
59
|
-
.base-
|
|
58
|
+
.base-modal__exitActive_pvkw5,
|
|
59
|
+
.base-modal__exitDone_pvkw5 {
|
|
60
60
|
opacity: 0;
|
|
61
61
|
transition: opacity 200ms ease-out;
|
|
62
62
|
}
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,7 @@ require('react-focus-lock');
|
|
|
12
12
|
require('@alfalab/core-components-portal');
|
|
13
13
|
require('@alfalab/core-components-backdrop');
|
|
14
14
|
require('@alfalab/core-components-stack');
|
|
15
|
+
require('@alfalab/core-components-global-store');
|
|
15
16
|
var utils = require('./utils.js');
|
|
16
17
|
|
|
17
18
|
|
|
@@ -22,3 +23,4 @@ exports.handleContainer = utils.handleContainer;
|
|
|
22
23
|
exports.hasScrollbar = utils.hasScrollbar;
|
|
23
24
|
exports.isScrolledToBottom = utils.isScrolledToBottom;
|
|
24
25
|
exports.isScrolledToTop = utils.isScrolledToTop;
|
|
26
|
+
exports.restoreContainerStyles = utils.restoreContainerStyles;
|
|
@@ -108,6 +108,10 @@ type BaseModalProps = {
|
|
|
108
108
|
* z-index компонента
|
|
109
109
|
*/
|
|
110
110
|
zIndex?: number;
|
|
111
|
+
/**
|
|
112
|
+
* Реф, который должен быть установлен компонентной области
|
|
113
|
+
*/
|
|
114
|
+
componentRef?: MutableRefObject<HTMLDivElement | null>;
|
|
111
115
|
};
|
|
112
116
|
type BaseModalContext = {
|
|
113
117
|
hasFooter?: boolean;
|
package/dist/modern/Component.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { forwardRef, useState, useRef,
|
|
1
|
+
import React, { forwardRef, useState, useRef, useCallback, useMemo, useEffect } from 'react';
|
|
2
2
|
import cn from 'classnames';
|
|
3
3
|
import mergeRefs from 'react-merge-refs';
|
|
4
4
|
import { ResizeObserver } from 'resize-observer';
|
|
@@ -7,9 +7,10 @@ import FocusLock from 'react-focus-lock';
|
|
|
7
7
|
import { Portal } from '@alfalab/core-components-portal/dist/modern';
|
|
8
8
|
import { Backdrop } from '@alfalab/core-components-backdrop/dist/modern';
|
|
9
9
|
import { stackingOrder, Stack } from '@alfalab/core-components-stack/dist/modern';
|
|
10
|
-
import
|
|
10
|
+
import '@alfalab/core-components-global-store/dist/modern';
|
|
11
|
+
import { isScrolledToTop, isScrolledToBottom, handleContainer, restoreContainerStyles, hasScrollbar } from './utils.js';
|
|
11
12
|
|
|
12
|
-
var styles = {"component":"base-
|
|
13
|
+
var styles = {"component":"base-modal__component_pvkw5","wrapper":"base-modal__wrapper_pvkw5","content":"base-modal__content_pvkw5","hidden":"base-modal__hidden_pvkw5","backdrop":"base-modal__backdrop_pvkw5","appear":"base-modal__appear_pvkw5","enter":"base-modal__enter_pvkw5","appearActive":"base-modal__appearActive_pvkw5","enterActive":"base-modal__enterActive_pvkw5","exit":"base-modal__exit_pvkw5","exitActive":"base-modal__exitActive_pvkw5","exitDone":"base-modal__exitDone_pvkw5"};
|
|
13
14
|
require('./index.css')
|
|
14
15
|
|
|
15
16
|
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
|
|
@@ -24,18 +25,18 @@ const BaseModalContext = React.createContext({
|
|
|
24
25
|
setHasFooter: () => null,
|
|
25
26
|
onClose: () => null,
|
|
26
27
|
});
|
|
27
|
-
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, }, ref) => {
|
|
28
|
+
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) => {
|
|
28
29
|
const [exited, setExited] = useState(!open);
|
|
29
30
|
const [hasScroll, setHasScroll] = useState(false);
|
|
30
31
|
const [hasHeader, setHasHeader] = useState(false);
|
|
31
32
|
const [hasFooter, setHasFooter] = useState(false);
|
|
32
33
|
const [headerHighlighted, setHeaderHighlighted] = useState(false);
|
|
33
34
|
const [footerHighlighted, setFooterHighlighted] = useState(false);
|
|
34
|
-
const
|
|
35
|
+
const componentNodeRef = useRef(null);
|
|
35
36
|
const wrapperRef = useRef(null);
|
|
36
37
|
const scrollableNodeRef = useRef(null);
|
|
37
38
|
const contentNodeRef = useRef(null);
|
|
38
|
-
const
|
|
39
|
+
const restoreContainerStylesRef = useRef(null);
|
|
39
40
|
const checkToHasScrollBar = () => {
|
|
40
41
|
if (scrollableNodeRef.current) {
|
|
41
42
|
const scrollExists = hasScrollbar(scrollableNodeRef.current);
|
|
@@ -44,6 +45,9 @@ const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrap
|
|
|
44
45
|
}
|
|
45
46
|
};
|
|
46
47
|
const shouldRender = keepMounted || open || !exited;
|
|
48
|
+
const getContainer = useCallback(() => {
|
|
49
|
+
return (container ? container() : document.body);
|
|
50
|
+
}, [container]);
|
|
47
51
|
const resizeObserver = useMemo(() => new ResizeObserver(checkToHasScrollBar), []);
|
|
48
52
|
const addResizeHandle = useCallback(() => {
|
|
49
53
|
if (scrollableNodeRef.current)
|
|
@@ -62,15 +66,16 @@ const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrap
|
|
|
62
66
|
}
|
|
63
67
|
}, [resizeObserver]);
|
|
64
68
|
const handleScroll = useCallback(() => {
|
|
65
|
-
if (!scrollableNodeRef.current || !
|
|
69
|
+
if (!scrollableNodeRef.current || !componentNodeRef.current)
|
|
66
70
|
return;
|
|
67
71
|
if (hasHeader) {
|
|
68
72
|
setHeaderHighlighted(!isScrolledToTop(scrollableNodeRef.current) &&
|
|
69
|
-
|
|
73
|
+
componentNodeRef.current.getBoundingClientRect().top <= 0);
|
|
70
74
|
}
|
|
71
75
|
if (hasFooter) {
|
|
72
76
|
setFooterHighlighted(!isScrolledToBottom(scrollableNodeRef.current) &&
|
|
73
|
-
|
|
77
|
+
componentNodeRef.current.getBoundingClientRect().bottom >=
|
|
78
|
+
window.innerHeight);
|
|
74
79
|
}
|
|
75
80
|
}, [hasFooter, hasHeader]);
|
|
76
81
|
const handleClose = useCallback((event, reason) => {
|
|
@@ -86,7 +91,7 @@ const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrap
|
|
|
86
91
|
return null;
|
|
87
92
|
}, [onBackdropClick, onClose, onEscapeKeyDown]);
|
|
88
93
|
const handleBackdropClick = (event) => {
|
|
89
|
-
if (!disableBackdropClick) {
|
|
94
|
+
if (!disableBackdropClick && event.target === wrapperRef.current) {
|
|
90
95
|
handleClose(event, 'backdropClick');
|
|
91
96
|
}
|
|
92
97
|
};
|
|
@@ -108,7 +113,7 @@ const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrap
|
|
|
108
113
|
if (scrollHandler === 'wrapper')
|
|
109
114
|
return wrapperRef.current;
|
|
110
115
|
if (scrollHandler === 'content')
|
|
111
|
-
return
|
|
116
|
+
return componentNodeRef.current;
|
|
112
117
|
return scrollHandler.current || wrapperRef.current;
|
|
113
118
|
}, [scrollHandler]);
|
|
114
119
|
const handleEntered = useCallback((node, isAppearing) => {
|
|
@@ -135,27 +140,29 @@ const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrap
|
|
|
135
140
|
}
|
|
136
141
|
if (onUnmount)
|
|
137
142
|
onUnmount();
|
|
138
|
-
if (
|
|
139
|
-
|
|
140
|
-
restoreContainerStyles.current = null;
|
|
143
|
+
if (restoreContainerStylesRef.current) {
|
|
144
|
+
restoreContainerStylesRef.current();
|
|
141
145
|
}
|
|
142
146
|
}, [handleScroll, onUnmount, removeResizeHandle, transitionProps]);
|
|
143
147
|
useEffect(() => {
|
|
144
148
|
if (open) {
|
|
145
|
-
|
|
149
|
+
handleContainer(getContainer());
|
|
150
|
+
restoreContainerStylesRef.current = () => {
|
|
151
|
+
restoreContainerStylesRef.current = null;
|
|
152
|
+
restoreContainerStyles(getContainer());
|
|
153
|
+
};
|
|
146
154
|
}
|
|
147
|
-
|
|
148
|
-
}, [open]);
|
|
155
|
+
}, [getContainer, open]);
|
|
149
156
|
useEffect(() => {
|
|
150
157
|
if (open)
|
|
151
158
|
setExited(false);
|
|
152
159
|
}, [open]);
|
|
153
160
|
useEffect(() => {
|
|
154
161
|
return () => {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
restoreContainerStyles.current();
|
|
162
|
+
if (restoreContainerStylesRef.current) {
|
|
163
|
+
restoreContainerStylesRef.current();
|
|
158
164
|
}
|
|
165
|
+
resizeObserver.disconnect();
|
|
159
166
|
};
|
|
160
167
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
161
168
|
}, []);
|
|
@@ -183,14 +190,16 @@ const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrap
|
|
|
183
190
|
return (React.createElement(Stack, { value: zIndex }, computedZIndex => (React.createElement(Portal, { getPortalContainer: container },
|
|
184
191
|
React.createElement(BaseModalContext.Provider, { value: contextValue },
|
|
185
192
|
React.createElement(FocusLock, { autoFocus: !disableAutoFocus, disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus },
|
|
193
|
+
Backdrop$1 && (React.createElement(Backdrop$1, Object.assign({}, backdropProps, { className: cn(backdropProps.className, styles.backdrop), open: open, style: {
|
|
194
|
+
zIndex: computedZIndex,
|
|
195
|
+
} }))),
|
|
186
196
|
React.createElement("div", { role: 'dialog', className: cn(styles.wrapper, wrapperClassName, {
|
|
187
197
|
[styles.hidden]: !open && exited,
|
|
188
|
-
}), ref: mergeRefs([ref, wrapperRef]), onKeyDown: handleKeyDown, tabIndex: -1, "data-test-id": dataTestId, style: {
|
|
198
|
+
}), ref: mergeRefs([ref, wrapperRef]), onKeyDown: handleKeyDown, onClick: handleBackdropClick, tabIndex: -1, "data-test-id": dataTestId, style: {
|
|
189
199
|
zIndex: computedZIndex,
|
|
190
200
|
} },
|
|
191
|
-
Backdrop$1 && (React.createElement(Backdrop$1, Object.assign({}, backdropProps, { className: cn(backdropProps.className, styles.backdrop), open: open, onClick: handleBackdropClick }))),
|
|
192
201
|
React.createElement(CSSTransition, Object.assign({ appear: true, timeout: 200, classNames: styles }, transitionProps, { in: open, onEntered: handleEntered, onExited: handleExited }),
|
|
193
|
-
React.createElement("div", { className: cn(styles.component, className), ref: componentRef },
|
|
202
|
+
React.createElement("div", { className: cn(styles.component, className), ref: mergeRefs([componentRef, componentNodeRef]) },
|
|
194
203
|
React.createElement("div", { className: cn(styles.content, contentClassName) }, children))))))))));
|
|
195
204
|
});
|
|
196
205
|
|
package/dist/modern/index.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* hash:
|
|
1
|
+
/* hash: zuxb3 */
|
|
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-
|
|
13
|
+
.base-modal__component_pvkw5 {
|
|
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-
|
|
20
|
+
.base-modal__wrapper_pvkw5 {
|
|
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-
|
|
33
|
+
.base-modal__content_pvkw5 {
|
|
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-
|
|
40
|
+
.base-modal__hidden_pvkw5 {
|
|
41
41
|
display: none;
|
|
42
42
|
}
|
|
43
|
-
.base-
|
|
44
|
-
z-index:
|
|
43
|
+
.base-modal__backdrop_pvkw5 {
|
|
44
|
+
z-index: 0;
|
|
45
45
|
}
|
|
46
|
-
.base-
|
|
47
|
-
.base-
|
|
46
|
+
.base-modal__appear_pvkw5,
|
|
47
|
+
.base-modal__enter_pvkw5 {
|
|
48
48
|
opacity: 0;
|
|
49
49
|
}
|
|
50
|
-
.base-
|
|
51
|
-
.base-
|
|
50
|
+
.base-modal__appearActive_pvkw5,
|
|
51
|
+
.base-modal__enterActive_pvkw5 {
|
|
52
52
|
opacity: 1;
|
|
53
53
|
transition: opacity 200ms ease-in;
|
|
54
54
|
}
|
|
55
|
-
.base-
|
|
55
|
+
.base-modal__exit_pvkw5 {
|
|
56
56
|
opacity: 1;
|
|
57
57
|
}
|
|
58
|
-
.base-
|
|
59
|
-
.base-
|
|
58
|
+
.base-modal__exitActive_pvkw5,
|
|
59
|
+
.base-modal__exitDone_pvkw5 {
|
|
60
60
|
opacity: 0;
|
|
61
61
|
transition: opacity 200ms ease-out;
|
|
62
62
|
}
|
package/dist/modern/index.js
CHANGED
|
@@ -7,5 +7,6 @@ import 'react-focus-lock';
|
|
|
7
7
|
import '@alfalab/core-components-portal/dist/modern';
|
|
8
8
|
import '@alfalab/core-components-backdrop/dist/modern';
|
|
9
9
|
import '@alfalab/core-components-stack/dist/modern';
|
|
10
|
-
|
|
10
|
+
import '@alfalab/core-components-global-store/dist/modern';
|
|
11
|
+
export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles } from './utils.js';
|
|
11
12
|
export { BaseModal, BaseModalContext } from './Component.js';
|