From cdc4b98b62b43d4e7253f731f2028e45d669acf5 Mon Sep 17 00:00:00 2001
From: sreetej1998 <41690429+sreetej1998@users.noreply.github.com>
Date: Tue, 22 Oct 2019 15:59:22 +0530
Subject: [PATCH] [Modal] Improve Gatsby support (#17972)
---
.../src/pages/components/modal/ServerModal.js | 7 +-
.../pages/components/modal/ServerModal.tsx | 7 +-
.../src/pages/components/modal/SpringModal.js | 2 +-
.../pages/components/modal/SpringModal.tsx | 2 +-
.../pages/components/popper/SpringPopper.js | 2 +-
.../pages/components/popper/SpringPopper.tsx | 2 +-
.../tree-view/CustomizedTreeView.js | 2 +-
.../tree-view/CustomizedTreeView.tsx | 2 +-
.../ClickAwayListener.test.js | 6 +-
packages/material-ui/src/Modal/Modal.test.js | 40 ++++++----
.../material-ui/src/Modal/ModalManager.js | 76 ++++++++++---------
.../material-ui/src/Popover/Popover.test.js | 16 ++--
.../material-ui/src/Popper/Popper.test.js | 2 +-
.../material-ui/src/Snackbar/Snackbar.test.js | 2 +-
.../material-ui/src/test-utils/createMount.js | 4 +-
15 files changed, 100 insertions(+), 72 deletions(-)
diff --git a/docs/src/pages/components/modal/ServerModal.js b/docs/src/pages/components/modal/ServerModal.js
index 0a99b62fa43482..f2584c39dde9b0 100644
--- a/docs/src/pages/components/modal/ServerModal.js
+++ b/docs/src/pages/components/modal/ServerModal.js
@@ -4,9 +4,14 @@ import Modal from '@material-ui/core/Modal';
const useStyles = makeStyles(theme => ({
root: {
- transform: 'translateZ(0)',
height: 300,
flexGrow: 1,
+ transform: 'translateZ(0)',
+ // The position fixed scoping doesn't work in IE 11.
+ // Disable this demo to preserve the others.
+ '@media all and (-ms-high-contrast: none)': {
+ display: 'none',
+ },
},
modal: {
display: 'flex',
diff --git a/docs/src/pages/components/modal/ServerModal.tsx b/docs/src/pages/components/modal/ServerModal.tsx
index c5eb2ea4c9e5b5..369b9e68339da7 100644
--- a/docs/src/pages/components/modal/ServerModal.tsx
+++ b/docs/src/pages/components/modal/ServerModal.tsx
@@ -5,9 +5,14 @@ import Modal from '@material-ui/core/Modal';
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
- transform: 'translateZ(0)',
height: 300,
flexGrow: 1,
+ transform: 'translateZ(0)',
+ // The position fixed scoping doesn't work in IE 11.
+ // Disable this demo to preserve the others.
+ '@media all and (-ms-high-contrast: none)': {
+ display: 'none',
+ },
},
modal: {
display: 'flex',
diff --git a/docs/src/pages/components/modal/SpringModal.js b/docs/src/pages/components/modal/SpringModal.js
index 5e38c9f6c9a3be..89b0a4ba3bd360 100644
--- a/docs/src/pages/components/modal/SpringModal.js
+++ b/docs/src/pages/components/modal/SpringModal.js
@@ -3,7 +3,7 @@ import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Modal from '@material-ui/core/Modal';
import Backdrop from '@material-ui/core/Backdrop';
-import { useSpring, animated } from 'react-spring';
+import { useSpring, animated } from 'react-spring/web.cjs'; // web.cjs is required for IE 11 support
const useStyles = makeStyles(theme => ({
modal: {
diff --git a/docs/src/pages/components/modal/SpringModal.tsx b/docs/src/pages/components/modal/SpringModal.tsx
index 368d8f5462046b..c862f3e45aa86e 100644
--- a/docs/src/pages/components/modal/SpringModal.tsx
+++ b/docs/src/pages/components/modal/SpringModal.tsx
@@ -3,7 +3,7 @@ import React from 'react';
import { makeStyles, Theme, createStyles } from '@material-ui/core/styles';
import Modal from '@material-ui/core/Modal';
import Backdrop from '@material-ui/core/Backdrop';
-import { useSpring, animated } from 'react-spring';
+import { useSpring, animated } from 'react-spring/web.cjs'; // web.cjs is required for IE 11 support
const useStyles = makeStyles((theme: Theme) =>
createStyles({
diff --git a/docs/src/pages/components/popper/SpringPopper.js b/docs/src/pages/components/popper/SpringPopper.js
index bcd94c6756fea4..41008e9ddfe958 100644
--- a/docs/src/pages/components/popper/SpringPopper.js
+++ b/docs/src/pages/components/popper/SpringPopper.js
@@ -2,7 +2,7 @@
import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Popper from '@material-ui/core/Popper';
-import { useSpring, animated } from 'react-spring';
+import { useSpring, animated } from 'react-spring/web.cjs'; // web.cjs is required for IE 11 support
const useStyles = makeStyles(theme => ({
paper: {
diff --git a/docs/src/pages/components/popper/SpringPopper.tsx b/docs/src/pages/components/popper/SpringPopper.tsx
index 985de853278e36..e01fc1b8e87220 100644
--- a/docs/src/pages/components/popper/SpringPopper.tsx
+++ b/docs/src/pages/components/popper/SpringPopper.tsx
@@ -2,7 +2,7 @@
import React from 'react';
import { makeStyles, Theme, createStyles } from '@material-ui/core/styles';
import Popper from '@material-ui/core/Popper';
-import { useSpring, animated } from 'react-spring';
+import { useSpring, animated } from 'react-spring/web.cjs'; // web.cjs is required for IE 11 support
const useStyles = makeStyles((theme: Theme) =>
createStyles({
diff --git a/docs/src/pages/components/tree-view/CustomizedTreeView.js b/docs/src/pages/components/tree-view/CustomizedTreeView.js
index ad5330374c2635..cc933bbe824a27 100644
--- a/docs/src/pages/components/tree-view/CustomizedTreeView.js
+++ b/docs/src/pages/components/tree-view/CustomizedTreeView.js
@@ -5,7 +5,7 @@ import { fade, makeStyles, withStyles } from '@material-ui/core/styles';
import TreeView from '@material-ui/lab/TreeView';
import TreeItem from '@material-ui/lab/TreeItem';
import Collapse from '@material-ui/core/Collapse';
-import { useSpring, animated } from 'react-spring';
+import { useSpring, animated } from 'react-spring/web.cjs'; // web.cjs is required for IE 11 support
function MinusSquare(props) {
return (
diff --git a/docs/src/pages/components/tree-view/CustomizedTreeView.tsx b/docs/src/pages/components/tree-view/CustomizedTreeView.tsx
index d4ed966af0ace3..e828c971bcef25 100644
--- a/docs/src/pages/components/tree-view/CustomizedTreeView.tsx
+++ b/docs/src/pages/components/tree-view/CustomizedTreeView.tsx
@@ -4,7 +4,7 @@ import { fade, makeStyles, withStyles, Theme, createStyles } from '@material-ui/
import TreeView from '@material-ui/lab/TreeView';
import TreeItem, { TreeItemProps } from '@material-ui/lab/TreeItem';
import Collapse from '@material-ui/core/Collapse';
-import { useSpring, animated } from 'react-spring';
+import { useSpring, animated } from 'react-spring/web.cjs'; // web.cjs is required for IE 11 support
import { TransitionProps } from '@material-ui/core/transitions';
function MinusSquare(props: SvgIconProps) {
diff --git a/packages/material-ui/src/ClickAwayListener/ClickAwayListener.test.js b/packages/material-ui/src/ClickAwayListener/ClickAwayListener.test.js
index 2dbad01b48891d..b574922d91c44f 100644
--- a/packages/material-ui/src/ClickAwayListener/ClickAwayListener.test.js
+++ b/packages/material-ui/src/ClickAwayListener/ClickAwayListener.test.js
@@ -77,13 +77,13 @@ describe('', () => {
,
);
const preventDefault = event => event.preventDefault();
- window.document.body.addEventListener('click', preventDefault);
+ document.body.addEventListener('click', preventDefault);
const event = new window.Event('click', { view: window, bubbles: true, cancelable: true });
- window.document.body.dispatchEvent(event);
+ document.body.dispatchEvent(event);
assert.strictEqual(handleClickAway.callCount, 0);
- window.document.body.removeEventListener('click', preventDefault);
+ document.body.removeEventListener('click', preventDefault);
});
});
diff --git a/packages/material-ui/src/Modal/Modal.test.js b/packages/material-ui/src/Modal/Modal.test.js
index 4c39193249e403..a0ec1ff7e04808 100644
--- a/packages/material-ui/src/Modal/Modal.test.js
+++ b/packages/material-ui/src/Modal/Modal.test.js
@@ -49,8 +49,18 @@ describe('', () => {
);
describe('props', () => {
+ let container;
+
+ before(() => {
+ container = document.createElement('div');
+ document.body.appendChild(container);
+ });
+
+ after(() => {
+ document.body.removeChild(container);
+ });
+
it('should consume theme default props', () => {
- const container = document.createElement('div');
const theme = createMuiTheme({ props: { MuiModal: { container } } });
mount(
@@ -620,11 +630,11 @@ describe('', () => {
};
const wrapper = mount();
- assert.strictEqual(document.body.style.overflow, '');
+ assert.strictEqual(document.body.parentNode.style.overflow, '');
wrapper.setProps({ open: true });
- assert.strictEqual(document.body.style.overflow, 'hidden');
+ assert.strictEqual(document.body.parentNode.style.overflow, 'hidden');
wrapper.setProps({ open: false });
- assert.strictEqual(document.body.style.overflow, '');
+ assert.strictEqual(document.body.parentNode.style.overflow, '');
});
it('should open and close with Transitions', done => {
@@ -649,17 +659,17 @@ describe('', () => {
let wrapper;
const onEntered = () => {
- assert.strictEqual(document.body.style.overflow, 'hidden');
+ assert.strictEqual(document.body.parentNode.style.overflow, 'hidden');
wrapper.setProps({ open: false });
};
const onExited = () => {
- assert.strictEqual(document.body.style.overflow, '');
+ assert.strictEqual(document.body.parentNode.style.overflow, '');
done();
};
wrapper = mount();
- assert.strictEqual(document.body.style.overflow, '');
+ assert.strictEqual(document.body.parentNode.style.overflow, '');
wrapper.setProps({ open: true });
});
});
@@ -711,23 +721,23 @@ describe('', () => {
let wrapper;
const onEntered = () => {
- assert.strictEqual(document.body.style.overflow, 'hidden');
+ assert.strictEqual(document.body.parentNode.style.overflow, 'hidden');
wrapper.setProps({ open: false });
};
const onExited = () => {
- assert.strictEqual(document.body.style.overflow, '');
+ assert.strictEqual(document.body.parentNode.style.overflow, '');
done();
};
const onExiting = () => {
- assert.strictEqual(document.body.style.overflow, 'hidden');
+ assert.strictEqual(document.body.parentNode.style.overflow, 'hidden');
};
wrapper = mount(
,
);
- assert.strictEqual(document.body.style.overflow, '');
+ assert.strictEqual(document.body.parentNode.style.overflow, '');
wrapper.setProps({ open: true });
});
@@ -754,23 +764,23 @@ describe('', () => {
let wrapper;
const onEntered = () => {
- assert.strictEqual(document.body.style.overflow, 'hidden');
+ assert.strictEqual(document.body.parentNode.style.overflow, 'hidden');
wrapper.setProps({ open: false });
};
const onExited = () => {
- assert.strictEqual(document.body.style.overflow, '');
+ assert.strictEqual(document.body.parentNode.style.overflow, '');
done();
};
const onExiting = () => {
- assert.strictEqual(document.body.style.overflow, '');
+ assert.strictEqual(document.body.parentNode.style.overflow, '');
};
wrapper = mount(
,
);
- assert.strictEqual(document.body.style.overflow, '');
+ assert.strictEqual(document.body.parentNode.style.overflow, '');
wrapper.setProps({ open: true });
});
});
diff --git a/packages/material-ui/src/Modal/ModalManager.js b/packages/material-ui/src/Modal/ModalManager.js
index a0e9dc0a281ea4..2cbf3c8c66058d 100644
--- a/packages/material-ui/src/Modal/ModalManager.js
+++ b/packages/material-ui/src/Modal/ModalManager.js
@@ -2,13 +2,12 @@ import getScrollbarSize from '../utils/getScrollbarSize';
import ownerDocument from '../utils/ownerDocument';
import ownerWindow from '../utils/ownerWindow';
-// Do we have a vertical scrollbar?
+// Is a vertical scrollbar displayed?
function isOverflowing(container) {
const doc = ownerDocument(container);
if (doc.body === container) {
- const win = ownerWindow(doc);
- return win.innerWidth > doc.documentElement.clientWidth;
+ return ownerWindow(doc).innerWidth > doc.documentElement.clientWidth;
}
return container.scrollHeight > container.clientHeight;
@@ -26,26 +25,21 @@ function getPaddingRight(node) {
return parseInt(window.getComputedStyle(node)['padding-right'], 10) || 0;
}
-const BLACKLIST = ['template', 'script', 'style'];
-
-function isHideable(node) {
- return node.nodeType === 1 && BLACKLIST.indexOf(node.tagName.toLowerCase()) === -1;
-}
-
-function siblings(container, mount, currentNode, nodesToExclude, callback) {
- const blacklist = [mount, currentNode, ...nodesToExclude];
+function ariaHiddenSiblings(container, mountNode, currentNode, nodesToExclude = [], show) {
+ const blacklist = [mountNode, currentNode, ...nodesToExclude];
+ const blacklistTagNames = ['TEMPLATE', 'SCRIPT', 'STYLE'];
[].forEach.call(container.children, node => {
- if (blacklist.indexOf(node) === -1 && isHideable(node)) {
- callback(node);
+ if (
+ node.nodeType === 1 &&
+ blacklist.indexOf(node) === -1 &&
+ blacklistTagNames.indexOf(node.tagName) === -1
+ ) {
+ ariaHidden(node, show);
}
});
}
-function ariaHiddenSiblings(container, mountNode, currentNode, nodesToExclude = [], show) {
- siblings(container, mountNode, currentNode, nodesToExclude, node => ariaHidden(node, show));
-}
-
function findIndexOf(containerInfo, callback) {
let idx = -1;
containerInfo.some((item, index) => {
@@ -59,24 +53,42 @@ function findIndexOf(containerInfo, callback) {
}
function handleContainer(containerInfo, props) {
- const restoreStyle = {};
- const style = {};
+ const restoreStyle = [];
const restorePaddings = [];
+ const container = containerInfo.container;
let fixedNodes;
if (!props.disableScrollLock) {
- restoreStyle.overflow = containerInfo.container.style.overflow;
- restoreStyle['padding-right'] = containerInfo.container.style.paddingRight;
- style.overflow = 'hidden';
+ const overflowing = isOverflowing(container);
- if (isOverflowing(containerInfo.container)) {
+ // Improve Gatsby support
+ // https://css-tricks.com/snippets/css/force-vertical-scrollbar/
+ const parent = container.parentElement;
+ const scrollContainer = parent.nodeName === 'HTML' ? parent : container;
+
+ restoreStyle.push({
+ value: scrollContainer.style.overflow,
+ key: 'overflow',
+ el: scrollContainer,
+ });
+
+ // Block the scroll even if no scrollbar is visible to account for mobile keyboard
+ // screensize shrink.
+ scrollContainer.style.overflow = 'hidden';
+
+ if (overflowing) {
const scrollbarSize = getScrollbarSize();
+ restoreStyle.push({
+ value: container.style.paddingRight,
+ key: 'padding-right',
+ el: container,
+ });
// Use computed style, here to get the real padding to add our scrollbar width.
- style['padding-right'] = `${getPaddingRight(containerInfo.container) + scrollbarSize}px`;
+ container.style['padding-right'] = `${getPaddingRight(container) + scrollbarSize}px`;
// .mui-fixed is a global helper.
- fixedNodes = ownerDocument(containerInfo.container).querySelectorAll('.mui-fixed');
+ fixedNodes = ownerDocument(container).querySelectorAll('.mui-fixed');
[].forEach.call(fixedNodes, node => {
restorePaddings.push(node.style.paddingRight);
node.style.paddingRight = `${getPaddingRight(node) + scrollbarSize}px`;
@@ -84,10 +96,6 @@ function handleContainer(containerInfo, props) {
}
}
- Object.keys(style).forEach(key => {
- containerInfo.container.style[key] = style[key];
- });
-
const restore = () => {
if (fixedNodes) {
[].forEach.call(fixedNodes, (node, i) => {
@@ -99,11 +107,11 @@ function handleContainer(containerInfo, props) {
});
}
- Object.keys(restoreStyle).forEach(key => {
- if (restoreStyle[key]) {
- containerInfo.container.style.setProperty(key, restoreStyle[key]);
+ restoreStyle.forEach(({ value, el, key }) => {
+ if (value) {
+ el.style.setProperty(key, value);
} else {
- containerInfo.container.style.removeProperty(key);
+ el.style.removeProperty(key);
}
});
};
@@ -230,6 +238,6 @@ export default class ModalManager {
}
isTopModal(modal) {
- return !!this.modals.length && this.modals[this.modals.length - 1] === modal;
+ return this.modals.length > 0 && this.modals[this.modals.length - 1] === modal;
}
}
diff --git a/packages/material-ui/src/Popover/Popover.test.js b/packages/material-ui/src/Popover/Popover.test.js
index c8ad9224242c61..b43630e04dd673 100644
--- a/packages/material-ui/src/Popover/Popover.test.js
+++ b/packages/material-ui/src/Popover/Popover.test.js
@@ -336,7 +336,7 @@ describe('', () => {
before(() => {
openPopover = anchorOrigin => {
if (!anchorEl) {
- anchorEl = window.document.createElement('div');
+ anchorEl = document.createElement('div');
}
const css = (element, styles) => {
@@ -352,7 +352,7 @@ describe('', () => {
top: '100px',
left: '100px',
});
- window.document.body.appendChild(anchorEl);
+ document.body.appendChild(anchorEl);
return new Promise(resolve => {
const component = (
@@ -362,7 +362,7 @@ describe('', () => {
anchorOrigin={anchorOrigin}
transitionDuration={0}
onEntered={() => {
- popoverEl = window.document.querySelector('[data-mui-test="Popover"]');
+ popoverEl = document.querySelector('[data-mui-test="Popover"]');
resolve();
}}
>
@@ -392,7 +392,7 @@ describe('', () => {
after(() => {
if (anchorEl) {
- window.document.body.removeChild(anchorEl);
+ document.body.removeChild(anchorEl);
}
});
@@ -449,7 +449,7 @@ describe('', () => {
it('should pass through container prop if container and anchorEl props are provided', () => {
const container = document.createElement('div');
- const wrapper2 = mount();
+ const wrapper2 = mount();
assert.strictEqual(wrapper2.find(Modal).props().container, container);
});
@@ -458,7 +458,7 @@ describe('', () => {
await openPopover(undefined);
assert.strictEqual(
wrapper.find(Modal).props().container,
- window.document.body,
+ document.body,
"should use anchorEl's parent body as Modal container",
);
});
@@ -516,7 +516,7 @@ describe('', () => {
anchorOrigin={anchorOrigin}
transitionDuration={0}
onEntered={() => {
- popoverEl = window.document.querySelector('[data-mui-test="Popover"]');
+ popoverEl = document.querySelector('[data-mui-test="Popover"]');
resolve();
}}
>
@@ -568,7 +568,7 @@ describe('', () => {
anchorReference="none"
transitionDuration={0}
onEntered={() => {
- popoverEl = window.document.querySelector('[data-mui-test="Popover"]');
+ popoverEl = document.querySelector('[data-mui-test="Popover"]');
resolve();
}}
PaperProps={{
diff --git a/packages/material-ui/src/Popper/Popper.test.js b/packages/material-ui/src/Popper/Popper.test.js
index f6e351d5ce25b2..39002ee20e1007 100644
--- a/packages/material-ui/src/Popper/Popper.test.js
+++ b/packages/material-ui/src/Popper/Popper.test.js
@@ -14,7 +14,7 @@ describe('', () => {
let mount;
const render = createClientRender({ strict: true });
const defaultProps = {
- anchorEl: () => window.document.createElement('svg'),
+ anchorEl: () => document.createElement('svg'),
children: Hello World,
open: true,
};
diff --git a/packages/material-ui/src/Snackbar/Snackbar.test.js b/packages/material-ui/src/Snackbar/Snackbar.test.js
index 5ad26e05250cc6..1d84fe249b1237 100644
--- a/packages/material-ui/src/Snackbar/Snackbar.test.js
+++ b/packages/material-ui/src/Snackbar/Snackbar.test.js
@@ -38,7 +38,7 @@ describe('', () => {
mount();
const event = new window.Event('click', { view: window, bubbles: true, cancelable: true });
- window.document.body.dispatchEvent(event);
+ document.body.dispatchEvent(event);
assert.strictEqual(handleClose.callCount, 1);
assert.deepEqual(handleClose.args[0], [event, 'clickaway']);
diff --git a/packages/material-ui/src/test-utils/createMount.js b/packages/material-ui/src/test-utils/createMount.js
index 3a4c14c6d5d8df..eaaa7d57f6e031 100644
--- a/packages/material-ui/src/test-utils/createMount.js
+++ b/packages/material-ui/src/test-utils/createMount.js
@@ -35,10 +35,10 @@ class Mode extends React.Component {
export default function createMount(options = {}) {
const { mount = enzymeMount, strict: globalStrict, ...globalEnzymeOptions } = options;
- const attachTo = window.document.createElement('div');
+ const attachTo = document.createElement('div');
attachTo.className = 'app';
attachTo.setAttribute('id', 'app');
- window.document.body.insertBefore(attachTo, window.document.body.firstChild);
+ document.body.insertBefore(attachTo, document.body.firstChild);
const mountWithContext = function mountWithContext(node, localOptions = {}) {
const { disableUnnmount = false, strict = globalStrict, ...localEnzymeOptions } = localOptions;