Skip to content

Commit 2f1973b

Browse files
committed
Merge branch 'master' of https://github.com/rackt/react-modal
2 parents 28dbc63 + 1038e3b commit 2f1973b

File tree

9 files changed

+203
-30
lines changed

9 files changed

+203
-30
lines changed

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
v0.0.5 - Thu, 13 Nov 2014 18:55:47 GMT
2+
--------------------------------------
3+
4+
- [b15aa82](../../commit/b15aa82) [added] Supporting custom className
5+
- [b7a38de](../../commit/b7a38de) [fixed] Warning caused by trying to focus null element closes #11
6+
7+
18
v0.0.4 - Tue, 11 Nov 2014 16:08:14 GMT
29
--------------------------------------
310

bower.json

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

dist/react-modal.js

+72-21
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ var React = (typeof window !== "undefined" ? window.React : typeof global !== "u
7171
var div = React.DOM.div;
7272
var focusManager = _dereq_('../helpers/focusManager');
7373
var scopeTab = _dereq_('../helpers/scopeTab');
74+
var cx = _dereq_('react/lib/cx');
7475

7576
// so that our CSS is statically analyzable
7677
var CLASS_NAMES = {
@@ -102,21 +103,36 @@ var ModalPortal = module.exports = React.createClass({
102103
},
103104

104105
componentDidMount: function() {
105-
this.handleProps(this.props);
106-
this.maybeFocus();
106+
// Focus needs to be set when mounting and already open
107+
if (this.props.isOpen) {
108+
this.setFocusAfterRender(true);
109+
this.open();
110+
}
107111
},
108112

109113
componentWillReceiveProps: function(newProps) {
110-
this.handleProps(newProps);
111-
},
114+
// Focus only needs to be set once when the modal is being opened
115+
if (!this.props.isOpen && newProps.isOpen) {
116+
this.setFocusAfterRender(true);
117+
}
112118

113-
handleProps: function(props) {
114-
if (props.isOpen === true)
119+
if (newProps.isOpen === true)
115120
this.open();
116-
else if (props.isOpen === false)
121+
else if (newProps.isOpen === false)
117122
this.close();
118123
},
119124

125+
componentDidUpdate: function () {
126+
if (this.focusAfterRender) {
127+
this.focusContent();
128+
this.setFocusAfterRender(false);
129+
}
130+
},
131+
132+
setFocusAfterRender: function (focus) {
133+
this.focusAfterRender = focus;
134+
},
135+
120136
open: function() {
121137
focusManager.setupScopedFocus(this.getDOMNode());
122138
focusManager.markForFocusLater();
@@ -134,17 +150,6 @@ var ModalPortal = module.exports = React.createClass({
134150
this.closeWithoutTimeout();
135151
},
136152

137-
componentDidUpdate: function() {
138-
this.maybeFocus();
139-
},
140-
141-
maybeFocus: function() {
142-
if (this.props.isOpen &&
143-
!this.refs.content.getDOMNode().contains(document.activeElement)) {
144-
this.focusContent();
145-
}
146-
},
147-
148153
focusContent: function() {
149154
this.refs.content.getDOMNode().focus();
150155
},
@@ -212,7 +217,7 @@ var ModalPortal = module.exports = React.createClass({
212217
},
213218
div({
214219
ref: "content",
215-
className: this.buildClassName('content'),
220+
className: cx(this.buildClassName('content'), this.props.className),
216221
tabIndex: "-1",
217222
onClick: stopPropagation,
218223
onKeyDown: this.handleKeyDown
@@ -224,7 +229,7 @@ var ModalPortal = module.exports = React.createClass({
224229
}
225230
});
226231

227-
},{"../helpers/focusManager":4,"../helpers/scopeTab":6}],3:[function(_dereq_,module,exports){
232+
},{"../helpers/focusManager":4,"../helpers/scopeTab":6,"react/lib/cx":9}],3:[function(_dereq_,module,exports){
228233
var _element = null;
229234

230235
function setElement(element) {
@@ -435,6 +440,52 @@ module.exports = findTabbableDescendants;
435440
module.exports = _dereq_('./components/Modal');
436441

437442

438-
},{"./components/Modal":1}]},{},[8])
443+
},{"./components/Modal":1}],9:[function(_dereq_,module,exports){
444+
/**
445+
* Copyright 2013-2014 Facebook, Inc.
446+
*
447+
* Licensed under the Apache License, Version 2.0 (the "License");
448+
* you may not use this file except in compliance with the License.
449+
* You may obtain a copy of the License at
450+
*
451+
* http://www.apache.org/licenses/LICENSE-2.0
452+
*
453+
* Unless required by applicable law or agreed to in writing, software
454+
* distributed under the License is distributed on an "AS IS" BASIS,
455+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
456+
* See the License for the specific language governing permissions and
457+
* limitations under the License.
458+
*
459+
* @providesModule cx
460+
*/
461+
462+
/**
463+
* This function is used to mark string literals representing CSS class names
464+
* so that they can be transformed statically. This allows for modularization
465+
* and minification of CSS class names.
466+
*
467+
* In static_upstream, this function is actually implemented, but it should
468+
* eventually be replaced with something more descriptive, and the transform
469+
* that is used in the main stack should be ported for use elsewhere.
470+
*
471+
* @param string|object className to modularize, or an object of key/values.
472+
* In the object case, the values are conditions that
473+
* determine if the className keys should be included.
474+
* @param [string ...] Variable list of classNames in the string case.
475+
* @return string Renderable space-separated CSS className.
476+
*/
477+
function cx(classNames) {
478+
if (typeof classNames == 'object') {
479+
return Object.keys(classNames).filter(function(className) {
480+
return classNames[className];
481+
}).join(' ');
482+
} else {
483+
return Array.prototype.join.call(arguments, ' ');
484+
}
485+
}
486+
487+
module.exports = cx;
488+
489+
},{}]},{},[8])
439490
(8)
440491
});

dist/react-modal.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/bootstrap/app.css

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
body {
2+
font-family: "Helvetica Neue", Arial;
3+
font-weight: 200;
4+
background: #ccc;
5+
}
6+
7+
.ReactModal__Overlay {
8+
-webkit-perspective: 600;
9+
perspective: 600;
10+
opacity: 0;
11+
overflow-x: hidden;
12+
overflow-y: auto;
13+
background-color: rgba(0, 0, 0, 0.5);
14+
}
15+
16+
.ReactModal__Overlay--after-open {
17+
opacity: 1;
18+
transition: opacity 150ms ease-out;
19+
}
20+
21+
.ReactModal__Content {
22+
-webkit-transform: scale(0.5) rotateX(-30deg);
23+
}
24+
25+
.ReactModal__Content--after-open {
26+
-webkit-transform: scale(1) rotateX(0deg);
27+
transition: all 150ms ease-in;
28+
}
29+
30+
.ReactModal__Overlay--before-close {
31+
opacity: 0;
32+
}
33+
34+
.ReactModal__Content--before-close {
35+
-webkit-transform: scale(0.5) rotateX(30deg);
36+
transition: all 150ms ease-in;
37+
}
38+
39+
.ReactModal__Content.modal-dialog {
40+
border: none;
41+
background-color: transparent;
42+
}

examples/bootstrap/app.js

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/** @jsx React.DOM */
2+
var React = require('react');
3+
var Modal = require('../../lib/index');
4+
5+
var appElement = document.getElementById('example');
6+
7+
Modal.setAppElement(appElement);
8+
Modal.injectCSS();
9+
10+
var App = React.createClass({
11+
12+
getInitialState: function() {
13+
return { modalIsOpen: false };
14+
},
15+
16+
openModal: function() {
17+
this.setState({modalIsOpen: true});
18+
},
19+
20+
closeModal: function() {
21+
this.setState({modalIsOpen: false});
22+
},
23+
24+
handleModalCloseRequest: function() {
25+
// opportunity to validate something and keep the modal open even if it
26+
// requested to be closed
27+
this.setState({modalIsOpen: false});
28+
},
29+
30+
handleSaveClicked: function(e) {
31+
alert('Save button was clicked');
32+
},
33+
34+
render: function() {
35+
return (
36+
<div>
37+
<button onClick={this.openModal}>Open Modal</button>
38+
<Modal
39+
className="Modal__Bootstrap modal-dialog"
40+
closeTimeoutMS={150}
41+
isOpen={this.state.modalIsOpen}
42+
onRequestClose={this.handleModalCloseRequest}
43+
>
44+
<div className="modal-content">
45+
<div className="modal-header">
46+
<button type="button" className="close" onClick={this.handleModalCloseRequest}>
47+
<span aria-hidden="true">&times;</span>
48+
<span className="sr-only">Close</span>
49+
</button>
50+
<h4 className="modal-title">Modal title</h4>
51+
</div>
52+
<div className="modal-body">
53+
<h4>Really long content...</h4>
54+
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
55+
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
56+
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
57+
</div>
58+
<div className="modal-footer">
59+
<button type="button" className="btn btn-default" onClick={this.handleModalCloseRequest}>Close</button>
60+
<button type="button" className="btn btn-primary" onClick={this.handleSaveClicked}>Save changes</button>
61+
</div>
62+
</div>
63+
</Modal>
64+
</div>
65+
);
66+
}
67+
});
68+
69+
React.renderComponent(<App/>, appElement);

examples/bootstrap/index.html

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!doctype html public "embarassment">
2+
<title>Bootstrap-Style Example</title>
3+
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
4+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
5+
<link href="app.css" rel="stylesheet"/>
6+
<body>
7+
<div id="example"></div>
8+
<script src="/__build__/shared.js"></script>
9+
<script src="/__build__/bootstrap.js"></script>
10+

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-modal",
3-
"version": "0.0.4",
3+
"version": "0.0.5",
44
"description": "Accessible modal dialog component for React.JS",
55
"main": "./lib/index",
66
"repository": {

webpack.config.js

-6
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,6 @@ module.exports = {
3939
]
4040
},
4141

42-
resolve: {
43-
alias: {
44-
'react-router': '../../modules/index'
45-
}
46-
},
47-
4842
plugins: [
4943
new webpack.optimize.CommonsChunkPlugin('shared.js')
5044
]

0 commit comments

Comments
 (0)