Skip to content

Commit dbaa77f

Browse files
committed
Release v3.4.1.
1 parent 2132488 commit dbaa77f

File tree

5 files changed

+225
-58
lines changed

5 files changed

+225
-58
lines changed

CHANGELOG.md

+14
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
v3.4.1 - Tue, 17 Apr 2018 09:49:06 UTC
2+
--------------------------------------
3+
4+
- [2132488](../../commit/2132488) Add eslint rule to disallow importing devDependencies in lib sources
5+
- [4887c69](../../commit/4887c69) Move react-lifecycles-compat to `dependencies` and upgrade it to v3
6+
- [f748406](../../commit/f748406) Remove cWRP usage in ModalPortal
7+
- [e91d59a](../../commit/e91d59a) Fix lifecycle method usages in Modal
8+
- [0dd7805](../../commit/0dd7805) [chore] update the pull request template...
9+
- [fa8e33c](../../commit/fa8e33c) removed un-safe lifecycle methods componentWillMount and componentWillUpdate. Implemented getDerivedStateFromProps and getSnapshotBeforeUpdate lifecycle methods using react-lifecycles-compat polyfill.
10+
- [d8c3dad](../../commit/d8c3dad) [fixed] mouse up event on overlay triggered the closing of the modal
11+
- [d6f3463](../../commit/d6f3463) [chore] Update transitions.md (#635)
12+
- [fa87046](../../commit/fa87046) [Chore] update README.md: added description for setting app element
13+
14+
115
v3.3.2 - Mon, 12 Mar 2018 22:16:32 UTC
216
--------------------------------------
317

bower.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-modal",
3-
"version": "3.3.2",
3+
"version": "3.4.1",
44
"homepage": "https://github.com/reactjs/react-modal",
55
"authors": [
66
"Ryan Florence",

dist/react-modal.js

+205-52
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,8 @@ var _safeHTMLElement = __webpack_require__(8);
524524

525525
var _safeHTMLElement2 = _interopRequireDefault(_safeHTMLElement);
526526

527+
var _reactLifecyclesCompat = __webpack_require__(22);
528+
527529
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
528530

529531
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -586,31 +588,37 @@ var Modal = function (_Component) {
586588
!isReact16 && this.renderPortal(this.props);
587589
}
588590
}, {
589-
key: "componentWillReceiveProps",
590-
value: function componentWillReceiveProps(newProps) {
591+
key: "getSnapshotBeforeUpdate",
592+
value: function getSnapshotBeforeUpdate(prevProps) {
593+
var prevParent = getParentElement(prevProps.parentSelector);
594+
var nextParent = getParentElement(this.props.parentSelector);
595+
return { prevParent: prevParent, nextParent: nextParent };
596+
}
597+
}, {
598+
key: "componentDidUpdate",
599+
value: function componentDidUpdate(prevProps, _, snapshot) {
591600
if (!_safeHTMLElement.canUseDOM) return;
592-
var isOpen = newProps.isOpen;
593-
// Stop unnecessary renders if modal is remaining closed
594-
595-
if (!this.props.isOpen && !isOpen) return;
601+
var _props = this.props,
602+
isOpen = _props.isOpen,
603+
portalClassName = _props.portalClassName;
596604

597-
var currentParent = getParentElement(this.props.parentSelector);
598-
var newParent = getParentElement(newProps.parentSelector);
599605

600-
if (newParent !== currentParent) {
601-
currentParent.removeChild(this.node);
602-
newParent.appendChild(this.node);
606+
if (prevProps.portalClassName !== portalClassName) {
607+
this.node.className = portalClassName;
603608
}
604609

605-
!isReact16 && this.renderPortal(newProps);
606-
}
607-
}, {
608-
key: "componentWillUpdate",
609-
value: function componentWillUpdate(newProps) {
610-
if (!_safeHTMLElement.canUseDOM) return;
611-
if (newProps.portalClassName !== this.props.portalClassName) {
612-
this.node.className = newProps.portalClassName;
610+
// Stop unnecessary renders if modal is remaining closed
611+
if (!prevProps.isOpen && !isOpen) return;
612+
613+
var prevParent = snapshot.prevParent,
614+
nextParent = snapshot.nextParent;
615+
616+
if (nextParent !== prevParent) {
617+
prevParent.removeChild(this.node);
618+
nextParent.appendChild(this.node);
613619
}
620+
621+
!isReact16 && this.renderPortal(this.props);
614622
}
615623
}, {
616624
key: "componentWillUnmount",
@@ -735,6 +743,10 @@ Modal.defaultStyles = {
735743
padding: "20px"
736744
}
737745
};
746+
747+
748+
(0, _reactLifecyclesCompat.polyfill)(Modal);
749+
738750
exports.default = Modal;
739751

740752
/***/ }),
@@ -1594,10 +1606,6 @@ var ModalPortal = function (_Component) {
15941606

15951607
var _this = _possibleConstructorReturn(this, (ModalPortal.__proto__ || Object.getPrototypeOf(ModalPortal)).call(this, props));
15961608

1597-
_this.setFocusAfterRender = function (focus) {
1598-
_this.focusAfterRender = _this.props.shouldFocusAfterRender && focus;
1599-
};
1600-
16011609
_this.setOverlayRef = function (overlay) {
16021610
_this.overlay = overlay;
16031611
_this.props.overlayRef && _this.props.overlayRef(overlay);
@@ -1713,16 +1721,6 @@ var ModalPortal = function (_Component) {
17131721
}
17141722
}
17151723
_this.shouldClose = null;
1716-
_this.moveFromContentToOverlay = null;
1717-
};
1718-
1719-
_this.handleOverlayOnMouseUp = function () {
1720-
if (_this.moveFromContentToOverlay === null) {
1721-
_this.shouldClose = false;
1722-
}
1723-
if (_this.props.shouldCloseOnOverlayClick) {
1724-
_this.shouldClose = true;
1725-
}
17261724
};
17271725

17281726
_this.handleContentOnMouseUp = function () {
@@ -1733,7 +1731,6 @@ var ModalPortal = function (_Component) {
17331731
if (!_this.props.shouldCloseOnOverlayClick && event.target == _this.overlay) {
17341732
event.preventDefault();
17351733
}
1736-
_this.moveFromContentToOverlay = false;
17371734
};
17381735

17391736
_this.handleContentOnClick = function () {
@@ -1742,7 +1739,6 @@ var ModalPortal = function (_Component) {
17421739

17431740
_this.handleContentOnMouseDown = function () {
17441741
_this.shouldClose = false;
1745-
_this.moveFromContentToOverlay = false;
17461742
};
17471743

17481744
_this.requestClose = function (event) {
@@ -1797,39 +1793,33 @@ var ModalPortal = function (_Component) {
17971793
_createClass(ModalPortal, [{
17981794
key: "componentDidMount",
17991795
value: function componentDidMount() {
1800-
// Focus needs to be set when mounting and already open
18011796
if (this.props.isOpen) {
1802-
this.setFocusAfterRender(true);
18031797
this.open();
18041798
}
18051799
}
18061800
}, {
1807-
key: "componentWillReceiveProps",
1808-
value: function componentWillReceiveProps(newProps) {
1801+
key: "componentDidUpdate",
1802+
value: function componentDidUpdate(prevProps, prevState) {
18091803
if (undefined !== "production") {
1810-
if (newProps.bodyOpenClassName !== this.props.bodyOpenClassName) {
1804+
if (prevProps.bodyOpenClassName !== this.props.bodyOpenClassName) {
18111805
// eslint-disable-next-line no-console
18121806
console.warn('React-Modal: "bodyOpenClassName" prop has been modified. ' + "This may cause unexpected behavior when multiple modals are open.");
18131807
}
1814-
if (newProps.htmlOpenClassName !== this.props.htmlOpenClassName) {
1808+
if (prevProps.htmlOpenClassName !== this.props.htmlOpenClassName) {
18151809
// eslint-disable-next-line no-console
18161810
console.warn('React-Modal: "htmlOpenClassName" prop has been modified. ' + "This may cause unexpected behavior when multiple modals are open.");
18171811
}
18181812
}
1819-
// Focus only needs to be set once when the modal is being opened
1820-
if (!this.props.isOpen && newProps.isOpen) {
1821-
this.setFocusAfterRender(true);
1813+
1814+
if (this.props.isOpen && !prevProps.isOpen) {
18221815
this.open();
1823-
} else if (this.props.isOpen && !newProps.isOpen) {
1816+
} else if (!this.props.isOpen && prevProps.isOpen) {
18241817
this.close();
18251818
}
1826-
}
1827-
}, {
1828-
key: "componentDidUpdate",
1829-
value: function componentDidUpdate() {
1830-
if (this.focusAfterRender) {
1819+
1820+
// Focus only needs to be set once when the modal is being opened
1821+
if (this.props.shouldFocusAfterRender && this.state.isOpen && !prevState.isOpen) {
18311822
this.focusContent();
1832-
this.setFocusAfterRender(false);
18331823
}
18341824
}
18351825
}, {
@@ -1880,7 +1870,6 @@ var ModalPortal = function (_Component) {
18801870
style: _extends({}, overlayStyles, this.props.style.overlay),
18811871
onClick: this.handleOverlayOnClick,
18821872
onMouseDown: this.handleOverlayOnMouseDown,
1883-
onMouseUp: this.handleOverlayOnMouseUp,
18841873
"aria-modal": "true"
18851874
},
18861875
_react2.default.createElement(
@@ -2355,6 +2344,170 @@ var __WEBPACK_AMD_DEFINE_RESULT__;/*!
23552344
}());
23562345

23572346

2347+
/***/ }),
2348+
/* 22 */
2349+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
2350+
2351+
"use strict";
2352+
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
2353+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "polyfill", function() { return polyfill; });
2354+
/**
2355+
* Copyright (c) 2013-present, Facebook, Inc.
2356+
*
2357+
* This source code is licensed under the MIT license found in the
2358+
* LICENSE file in the root directory of this source tree.
2359+
*/
2360+
2361+
function componentWillMount() {
2362+
// Call this.constructor.gDSFP to support sub-classes.
2363+
var state = this.constructor.getDerivedStateFromProps(this.props, this.state);
2364+
if (state !== null && state !== undefined) {
2365+
this.setState(state);
2366+
}
2367+
}
2368+
2369+
function componentWillReceiveProps(nextProps) {
2370+
// Call this.constructor.gDSFP to support sub-classes.
2371+
var state = this.constructor.getDerivedStateFromProps(nextProps, this.state);
2372+
if (state !== null && state !== undefined) {
2373+
this.setState(state);
2374+
}
2375+
}
2376+
2377+
function componentWillUpdate(nextProps, nextState) {
2378+
try {
2379+
var prevProps = this.props;
2380+
var prevState = this.state;
2381+
this.props = nextProps;
2382+
this.state = nextState;
2383+
this.__reactInternalSnapshotFlag = true;
2384+
this.__reactInternalSnapshot = this.getSnapshotBeforeUpdate(
2385+
prevProps,
2386+
prevState
2387+
);
2388+
} finally {
2389+
this.props = prevProps;
2390+
this.state = prevState;
2391+
}
2392+
}
2393+
2394+
// React may warn about cWM/cWRP/cWU methods being deprecated.
2395+
// Add a flag to suppress these warnings for this special case.
2396+
componentWillMount.__suppressDeprecationWarning = true;
2397+
componentWillReceiveProps.__suppressDeprecationWarning = true;
2398+
componentWillUpdate.__suppressDeprecationWarning = true;
2399+
2400+
function polyfill(Component) {
2401+
var prototype = Component.prototype;
2402+
2403+
if (!prototype || !prototype.isReactComponent) {
2404+
throw new Error('Can only polyfill class components');
2405+
}
2406+
2407+
if (
2408+
typeof Component.getDerivedStateFromProps !== 'function' &&
2409+
typeof prototype.getSnapshotBeforeUpdate !== 'function'
2410+
) {
2411+
return Component;
2412+
}
2413+
2414+
// If new component APIs are defined, "unsafe" lifecycles won't be called.
2415+
// Error if any of these lifecycles are present,
2416+
// Because they would work differently between older and newer (16.3+) versions of React.
2417+
var foundWillMountName = null;
2418+
var foundWillReceivePropsName = null;
2419+
var foundWillUpdateName = null;
2420+
if (typeof prototype.componentWillMount === 'function') {
2421+
foundWillMountName = 'componentWillMount';
2422+
} else if (typeof prototype.UNSAFE_componentWillMount === 'function') {
2423+
foundWillMountName = 'UNSAFE_componentWillMount';
2424+
}
2425+
if (typeof prototype.componentWillReceiveProps === 'function') {
2426+
foundWillReceivePropsName = 'componentWillReceiveProps';
2427+
} else if (typeof prototype.UNSAFE_componentWillReceiveProps === 'function') {
2428+
foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
2429+
}
2430+
if (typeof prototype.componentWillUpdate === 'function') {
2431+
foundWillUpdateName = 'componentWillUpdate';
2432+
} else if (typeof prototype.UNSAFE_componentWillUpdate === 'function') {
2433+
foundWillUpdateName = 'UNSAFE_componentWillUpdate';
2434+
}
2435+
if (
2436+
foundWillMountName !== null ||
2437+
foundWillReceivePropsName !== null ||
2438+
foundWillUpdateName !== null
2439+
) {
2440+
var componentName = Component.displayName || Component.name;
2441+
var newApiName =
2442+
typeof Component.getDerivedStateFromProps === 'function'
2443+
? 'getDerivedStateFromProps()'
2444+
: 'getSnapshotBeforeUpdate()';
2445+
2446+
throw Error(
2447+
'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
2448+
componentName +
2449+
' uses ' +
2450+
newApiName +
2451+
' but also contains the following legacy lifecycles:' +
2452+
(foundWillMountName !== null ? '\n ' + foundWillMountName : '') +
2453+
(foundWillReceivePropsName !== null
2454+
? '\n ' + foundWillReceivePropsName
2455+
: '') +
2456+
(foundWillUpdateName !== null ? '\n ' + foundWillUpdateName : '') +
2457+
'\n\nThe above lifecycles should be removed. Learn more about this warning here:\n' +
2458+
'https://fb.me/react-async-component-lifecycle-hooks'
2459+
);
2460+
}
2461+
2462+
// React <= 16.2 does not support static getDerivedStateFromProps.
2463+
// As a workaround, use cWM and cWRP to invoke the new static lifecycle.
2464+
// Newer versions of React will ignore these lifecycles if gDSFP exists.
2465+
if (typeof Component.getDerivedStateFromProps === 'function') {
2466+
prototype.componentWillMount = componentWillMount;
2467+
prototype.componentWillReceiveProps = componentWillReceiveProps;
2468+
}
2469+
2470+
// React <= 16.2 does not support getSnapshotBeforeUpdate.
2471+
// As a workaround, use cWU to invoke the new lifecycle.
2472+
// Newer versions of React will ignore that lifecycle if gSBU exists.
2473+
if (typeof prototype.getSnapshotBeforeUpdate === 'function') {
2474+
if (typeof prototype.componentDidUpdate !== 'function') {
2475+
throw new Error(
2476+
'Cannot polyfill getSnapshotBeforeUpdate() for components that do not define componentDidUpdate() on the prototype'
2477+
);
2478+
}
2479+
2480+
prototype.componentWillUpdate = componentWillUpdate;
2481+
2482+
var componentDidUpdate = prototype.componentDidUpdate;
2483+
2484+
prototype.componentDidUpdate = function componentDidUpdatePolyfill(
2485+
prevProps,
2486+
prevState,
2487+
maybeSnapshot
2488+
) {
2489+
// 16.3+ will not execute our will-update method;
2490+
// It will pass a snapshot value to did-update though.
2491+
// Older versions will require our polyfilled will-update value.
2492+
// We need to handle both cases, but can't just check for the presence of "maybeSnapshot",
2493+
// Because for <= 15.x versions this might be a "prevContext" object.
2494+
// We also can't just check "__reactInternalSnapshot",
2495+
// Because get-snapshot might return a falsy value.
2496+
// So check for the explicit __reactInternalSnapshotFlag flag to determine behavior.
2497+
var snapshot = this.__reactInternalSnapshotFlag
2498+
? this.__reactInternalSnapshot
2499+
: maybeSnapshot;
2500+
2501+
componentDidUpdate.call(this, prevProps, prevState, snapshot);
2502+
};
2503+
}
2504+
2505+
return Component;
2506+
}
2507+
2508+
2509+
2510+
23582511
/***/ })
23592512
/******/ ]);
23602513
});

0 commit comments

Comments
 (0)