@loomhq/lens 10.63.10 → 10.64.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.
|
@@ -13,6 +13,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
13
13
|
import FocusTrap from 'focus-trap-react';
|
|
14
14
|
import { getColorValue, getPlacement, getRadius, getShadow, getSize, getSizeValue, u, } from '../../utilities';
|
|
15
15
|
import React, { useEffect } from 'react';
|
|
16
|
+
import { usePreventScroll } from '../../hooks/use-prevent-scroll';
|
|
16
17
|
import Backdrop from '../backdrop/backdrop';
|
|
17
18
|
import Container from '../container/container';
|
|
18
19
|
import IconButton from '../icon-button/icon-button';
|
|
@@ -111,9 +112,6 @@ export const ModalCard = (_a) => {
|
|
|
111
112
|
// TODO: LNS-151: Abstract into useKeyDown hook for reuse
|
|
112
113
|
var { children, onCloseClick, isOpen, maxWidth = 60, maxHeight = '70vh', placement = 'center', ariaLabel, ref } = _a, props = __rest(_a, ["children", "onCloseClick", "isOpen", "maxWidth", "maxHeight", "placement", "ariaLabel", "ref"]);
|
|
113
114
|
useEffect(() => {
|
|
114
|
-
if (!isOpen) {
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
115
|
const keyListener = e => {
|
|
118
116
|
if (e.key === 'Escape') {
|
|
119
117
|
e.preventDefault();
|
|
@@ -125,6 +123,7 @@ export const ModalCard = (_a) => {
|
|
|
125
123
|
window.removeEventListener('keydown', keyListener);
|
|
126
124
|
};
|
|
127
125
|
}, [isOpen, onCloseClick]);
|
|
126
|
+
usePreventScroll('body', isOpen);
|
|
128
127
|
return (React.createElement(FocusTrap, { active: isOpen, focusTrapOptions: {
|
|
129
128
|
clickOutsideDeactivates: false,
|
|
130
129
|
allowOutsideClick: true,
|
package/dist/hooks/index.js
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Usage:
|
|
3
|
+
* usePreventScroll(<level>, <boolean-condition>);
|
|
4
|
+
*
|
|
5
|
+
* `level` allows you to control whether the styles
|
|
6
|
+
* are passed to html or body, whichever level makes more sense
|
|
7
|
+
* for your application.
|
|
8
|
+
**/
|
|
9
|
+
export declare function usePreventScroll(level: 'body' | 'html', enabled?: boolean): void;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { useLayoutEffect } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Usage:
|
|
4
|
+
* usePreventScroll(<level>, <boolean-condition>);
|
|
5
|
+
*
|
|
6
|
+
* `level` allows you to control whether the styles
|
|
7
|
+
* are passed to html or body, whichever level makes more sense
|
|
8
|
+
* for your application.
|
|
9
|
+
**/
|
|
10
|
+
export function usePreventScroll(level, enabled) {
|
|
11
|
+
const safeDocument = document;
|
|
12
|
+
useLayoutEffect(() => {
|
|
13
|
+
const html = safeDocument === null || safeDocument === void 0 ? void 0 : safeDocument.documentElement;
|
|
14
|
+
const body = safeDocument === null || safeDocument === void 0 ? void 0 : safeDocument.body;
|
|
15
|
+
if (safeDocument == undefined || !html || !body) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (enabled) {
|
|
19
|
+
// Add styles if enabled
|
|
20
|
+
const scrollBarWidth = window.innerWidth - html.clientWidth;
|
|
21
|
+
const bodyPaddingRight = parseInt(window.getComputedStyle(body).getPropertyValue('padding-right'),
|
|
22
|
+
/* Force radixValue to be base-10 system to avoid errors:
|
|
23
|
+
* https://stackoverflow.com/questions/6611824/why-do-we-need-to-use-radix-parameter-when-calling-parseint
|
|
24
|
+
*/
|
|
25
|
+
10) || 0;
|
|
26
|
+
/**
|
|
27
|
+
* [1] iOS and desktop Safari bug: Requires position to make `overflow: hidden`
|
|
28
|
+
* prevent scrolling.
|
|
29
|
+
* [2] Desktop Safari bug: Must override overflow in both directions
|
|
30
|
+
* since `overflowY` won't prevent scroll if `overflowX` is applied.
|
|
31
|
+
* [3] paddingRight takes into account scrollbars by running a check.
|
|
32
|
+
**/
|
|
33
|
+
switch (level) {
|
|
34
|
+
case 'html': {
|
|
35
|
+
html.style.position = 'relative'; /* [1] */
|
|
36
|
+
html.style.overflow = 'hidden'; /* [2] */
|
|
37
|
+
body.style.paddingRight = `${bodyPaddingRight +
|
|
38
|
+
scrollBarWidth}px`; /* [3] */
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
case 'body': {
|
|
42
|
+
body.style.setProperty('position', 'relative'); /* [1] */
|
|
43
|
+
body.style.setProperty('overflow', 'hidden'); /* [2] */
|
|
44
|
+
body.style.setProperty('padding-right', `${bodyPaddingRight + scrollBarWidth}px`); /* [3] */
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
default:
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return () => {
|
|
52
|
+
switch (level) {
|
|
53
|
+
case 'html': {
|
|
54
|
+
// TODO(LNS-221): Preserve previous style states rather than resetting to empty values for more robust utility
|
|
55
|
+
html.style.position = ''; /* [1] */
|
|
56
|
+
html.style.overflow = ''; /* [2] */
|
|
57
|
+
body.style.paddingRight = ''; /* [3] */
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
case 'body': {
|
|
61
|
+
body.style.removeProperty('position'); /* [1] */
|
|
62
|
+
body.style.removeProperty('overflow'); /* [2] */
|
|
63
|
+
body.style.removeProperty('padding-right'); /* [3] */
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
default:
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
// TODO(LNS-215): Clear styles on return to make utility more extendable for other uses
|
|
71
|
+
}, [safeDocument, enabled, level]);
|
|
72
|
+
}
|