Skip to content

Commit 596f423

Browse files
Add Linting (#293)
* Add linting * Make specs pass linter * Make lib/helpers pass linter * Make lib/components pass linter This also does some signfiicant refactoring of the code to appease the linter's pro-ES2015+ stance. closes #289 closes #286 * Make travis run the lint task as well as specs closes #284
1 parent 3ada4fb commit 596f423

16 files changed

+1388
-685
lines changed

.babelrc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"presets": ["es2015", "react"]
3-
}
2+
"presets": ["react", "latest", "stage-2"]
3+
}

.eslintrc.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
module.exports = {
2+
"env": {
3+
"es6": true,
4+
"browser": true
5+
},
6+
"extends": "airbnb",
7+
"parserOptions": {
8+
"ecmaVersion": 7,
9+
"ecmaFeatures": {
10+
"experimentalObjectRestSpread": true,
11+
"jsx": true
12+
},
13+
"sourceType": "module"
14+
},
15+
"parser": "babel-eslint",
16+
rules: {
17+
"comma-dangle": [2, "only-multiline"],
18+
"max-len": [1, {"code": 140}],
19+
"no-continue": [0],
20+
"no-plusplus": [0],
21+
"space-before-function-paren": [2, "always"],
22+
"import/no-extraneous-dependencies": [2, {"devDependencies": true}],
23+
"react/jsx-filename-extension": ["error", {"extensions": [".js"]}]
24+
},
25+
};

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ node_js:
77
before_script:
88
- export DISPLAY=:99.0
99
- sh -e /etc/init.d/xvfb start
10+
script: npm run test:full
11+
cache: yarn

eslint.json

Lines changed: 0 additions & 18 deletions
This file was deleted.

lib/components/Modal.js

Lines changed: 82 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,22 @@
1-
var React = require('react');
2-
var ReactDOM = require('react-dom');
3-
var ExecutionEnvironment = require('exenv');
4-
var ModalPortal = React.createFactory(require('./ModalPortal'));
5-
var ariaAppHider = require('../helpers/ariaAppHider');
6-
var elementClass = require('element-class');
7-
var renderSubtreeIntoContainer = require("react-dom").unstable_renderSubtreeIntoContainer;
8-
var Assign = require('lodash.assign');
9-
10-
var SafeHTMLElement = ExecutionEnvironment.canUseDOM ? window.HTMLElement : {};
11-
var AppElement = ExecutionEnvironment.canUseDOM ? document.body : {appendChild: function() {}};
12-
13-
function getParentElement(parentSelector) {
1+
import React, { Component } from 'react';
2+
import ReactDOM from 'react-dom';
3+
import ExecutionEnvironment from 'exenv';
4+
import elementClass from 'element-class';
5+
import ModalPortal from './ModalPortal';
6+
import ariaAppHider from '../helpers/ariaAppHider';
7+
8+
const renderSubtreeIntoContainer = ReactDOM.unstable_renderSubtreeIntoContainer;
9+
10+
const SafeHTMLElement = ExecutionEnvironment.canUseDOM ? window.HTMLElement : {};
11+
12+
function getParentElement (parentSelector) {
1413
return parentSelector();
1514
}
1615

17-
var Modal = React.createClass({
18-
19-
displayName: 'Modal',
20-
statics: {
21-
setAppElement: function(element) {
22-
AppElement = ariaAppHider.setElement(element);
23-
},
24-
injectCSS: function() {
25-
"production" !== process.env.NODE_ENV
26-
&& console.warn('React-Modal: injectCSS has been deprecated ' +
27-
'and no longer has any effect. It will be removed in a later version');
28-
}
29-
},
16+
export default class Modal extends Component {
3017

31-
propTypes: {
18+
/* eslint-disable react/no-unused-prop-types */
19+
static propTypes = {
3220
isOpen: React.PropTypes.bool.isRequired,
3321
style: React.PropTypes.shape({
3422
content: React.PropTypes.object,
@@ -44,52 +32,86 @@ var Modal = React.createClass({
4432
parentSelector: React.PropTypes.func,
4533
role: React.PropTypes.string,
4634
contentLabel: React.PropTypes.string.isRequired
47-
},
48-
49-
getDefaultProps: function () {
50-
return {
51-
isOpen: false,
52-
portalClassName: 'ReactModalPortal',
53-
ariaHideApp: true,
54-
closeTimeoutMS: 0,
55-
shouldCloseOnOverlayClick: true,
56-
parentSelector: function () { return document.body; }
57-
};
58-
},
59-
60-
componentDidMount: function() {
35+
};
36+
/* eslint-enable react/no-unused-prop-types */
37+
38+
static defaultProps = {
39+
isOpen: false,
40+
portalClassName: 'ReactModalPortal',
41+
ariaHideApp: true,
42+
closeTimeoutMS: 0,
43+
shouldCloseOnOverlayClick: true,
44+
parentSelector () { return document.body; }
45+
};
46+
47+
static defaultStyles = {
48+
overlay: {
49+
position: 'fixed',
50+
top: 0,
51+
left: 0,
52+
right: 0,
53+
bottom: 0,
54+
backgroundColor: 'rgba(255, 255, 255, 0.75)'
55+
},
56+
content: {
57+
position: 'absolute',
58+
top: '40px',
59+
left: '40px',
60+
right: '40px',
61+
bottom: '40px',
62+
border: '1px solid #ccc',
63+
background: '#fff',
64+
overflow: 'auto',
65+
WebkitOverflowScrolling: 'touch',
66+
borderRadius: '4px',
67+
outline: 'none',
68+
padding: '20px'
69+
}
70+
};
71+
72+
static setAppElement (element) {
73+
ariaAppHider.setElement(element);
74+
}
75+
76+
static injectCSS () {
77+
return process.env.NODE_ENV !== 'production'
78+
&& console.warn('React-Modal: injectCSS has been deprecated ' +
79+
'and no longer has any effect. It will be removed in a later version');
80+
}
81+
82+
componentDidMount () {
6183
this.node = document.createElement('div');
6284
this.node.className = this.props.portalClassName;
6385

64-
var parent = getParentElement(this.props.parentSelector);
86+
const parent = getParentElement(this.props.parentSelector);
6587
parent.appendChild(this.node);
6688
this.renderPortal(this.props);
67-
},
89+
}
6890

69-
componentWillReceiveProps: function(newProps) {
70-
var currentParent = getParentElement(this.props.parentSelector);
71-
var newParent = getParentElement(newProps.parentSelector);
91+
componentWillReceiveProps (newProps) {
92+
const currentParent = getParentElement(this.props.parentSelector);
93+
const newParent = getParentElement(newProps.parentSelector);
7294

73-
if(newParent !== currentParent) {
95+
if (newParent !== currentParent) {
7496
currentParent.removeChild(this.node);
7597
newParent.appendChild(this.node);
7698
}
7799

78100
this.renderPortal(newProps);
79-
},
101+
}
80102

81-
componentWillUnmount: function() {
103+
componentWillUnmount () {
82104
if (this.props.ariaHideApp) {
83105
ariaAppHider.show(this.props.appElement);
84106
}
85107

86108
ReactDOM.unmountComponentAtNode(this.node);
87-
var parent = getParentElement(this.props.parentSelector);
109+
const parent = getParentElement(this.props.parentSelector);
88110
parent.removeChild(this.node);
89111
elementClass(document.body).remove('ReactModal__Body--open');
90-
},
112+
}
91113

92-
renderPortal: function(props) {
114+
renderPortal (props) {
93115
if (props.isOpen) {
94116
elementClass(document.body).add('ReactModal__Body--open');
95117
} else {
@@ -100,37 +122,14 @@ var Modal = React.createClass({
100122
ariaAppHider.toggle(props.isOpen, props.appElement);
101123
}
102124

103-
this.portal = renderSubtreeIntoContainer(this, ModalPortal(Assign({}, props, {defaultStyles: Modal.defaultStyles})), this.node);
104-
},
105-
106-
render: function () {
107-
return React.DOM.noscript();
125+
this.portal = renderSubtreeIntoContainer(this,
126+
<ModalPortal
127+
{...props}
128+
defaultStyles={Modal.defaultStyles}
129+
/>, this.node);
108130
}
109-
});
110-
111-
Modal.defaultStyles = {
112-
overlay: {
113-
position : 'fixed',
114-
top : 0,
115-
left : 0,
116-
right : 0,
117-
bottom : 0,
118-
backgroundColor : 'rgba(255, 255, 255, 0.75)'
119-
},
120-
content: {
121-
position : 'absolute',
122-
top : '40px',
123-
left : '40px',
124-
right : '40px',
125-
bottom : '40px',
126-
border : '1px solid #ccc',
127-
background : '#fff',
128-
overflow : 'auto',
129-
WebkitOverflowScrolling : 'touch',
130-
borderRadius : '4px',
131-
outline : 'none',
132-
padding : '20px'
131+
132+
render () {
133+
return null;
133134
}
134135
}
135-
136-
module.exports = Modal

0 commit comments

Comments
 (0)