From 7f699b2d7812d4b7b25e74a77b64460085031a54 Mon Sep 17 00:00:00 2001 From: kalle Date: Wed, 3 Jun 2015 09:48:04 +0200 Subject: [PATCH 01/22] improved open and close detection beforeClose beforeOpen afterClose afterOpen triggered even if the isVisible state was unchanged while the component received an update. Now the change of isVisible before and after the Update will be compared. --- src/skylight.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/skylight.jsx b/src/skylight.jsx index d55f829..9033991 100644 --- a/src/skylight.jsx +++ b/src/skylight.jsx @@ -35,20 +35,20 @@ var SkyLight = React.createClass({ this.setState({isVisible: false}); }, componentWillUpdate: function (nextProps, nextState) { - if (nextState.isVisible && this.props.beforeOpen) { + if (nextState.isVisible && !this.state.isVisible && this.props.beforeOpen) { this.props.beforeOpen(); } - if (!nextState.isVisible && this.props.beforeClose) { + if (!nextState.isVisible && this.state.isVisible && this.props.beforeClose) { this.props.beforeClose(); } }, componentDidUpdate: function (prevProps, prevState) { - if (!prevState.isVisible && this.props.afterOpen) { + if (!prevState.isVisible && this.state.isVisible && this.props.afterOpen) { this.props.afterOpen(); } - if (prevState.isVisible && this.props.afterClose) { + if (prevState.isVisible && !this.state.isVisible && this.props.afterClose) { this.props.afterClose(); } }, From aaff4a64147e4b8b645c1bb2f77d6d94d2500ae7 Mon Sep 17 00:00:00 2001 From: MIJOTHY Date: Wed, 17 Jun 2015 13:54:11 +0100 Subject: [PATCH 02/22] typo? --- src/skylight.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/skylight.jsx b/src/skylight.jsx index d55f829..cd3a7b0 100644 --- a/src/skylight.jsx +++ b/src/skylight.jsx @@ -58,7 +58,7 @@ var SkyLight = React.createClass({ var dialogStyles = extend(styles.dialogStyles, this.props.dialogStyles); var overlayStyles = extend(styles.overlayStyles, this.props.overlayStyles); - var closeButtonStyle = extend(styles.closeButtonStyle = this.props.closeButtonStyle); + var closeButtonStyle = extend(styles.closeButtonStyle, this.props.closeButtonStyle); if (this.state.isVisible) { overlayStyles.display = 'block'; From 4592c99fcf725885110aef15861bd4e98349de2e Mon Sep 17 00:00:00 2001 From: Marcio Gasparotto Date: Tue, 5 Jan 2016 22:23:40 -0200 Subject: [PATCH 03/22] refactoring to es2015 with babel --- .babelrc | 3 + .eslintrc | 41 ++++++ index.js | 1 - lib/skylight.js | 231 +++++++++++++++++++++++++++++++++ lib/styles.js | 39 ++++++ package.json | 36 +++-- preprocessor.js | 7 - src/__tests__/skylight-test.js | 71 ---------- src/skylight.js | 196 ++++++++++++++++++++++++++++ src/skylight.jsx | 88 ------------- src/styles.js | 64 ++++----- styles-examples/default.css | 31 ----- 12 files changed, 558 insertions(+), 250 deletions(-) create mode 100644 .babelrc create mode 100644 .eslintrc delete mode 100644 index.js create mode 100644 lib/skylight.js create mode 100644 lib/styles.js delete mode 100644 preprocessor.js delete mode 100644 src/__tests__/skylight-test.js create mode 100644 src/skylight.js delete mode 100644 src/skylight.jsx delete mode 100644 styles-examples/default.css diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..4687bc4 --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["es2015", "react", "stage-0"] +} diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..bbcd0d6 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,41 @@ +{ + "parser": "babel-eslint", + "env": { + "browser": true, + "node": true + }, + "plugins": [ + "react" + ], + "ecmaFeatures": { + "jsx": true + }, + "rules": { + "quotes": [2, "single"], + "eol-last": [0], + "no-mixed-requires": [0], + "no-underscore-dangle": [0], + "react/display-name": 1, + "react/jsx-boolean-value": 1, + "react/jsx-curly-spacing": 1, + "react/jsx-max-props-per-line": [1, {maximum: 6}], + "react/jsx-no-duplicate-props": 1, + "react/jsx-no-undef": 1, + "react/jsx-quotes": 1, + "react/jsx-sort-prop-types": 1, + "react/jsx-sort-props": 1, + "react/jsx-uses-react": 1, + "react/jsx-uses-vars": 1, + "react/no-danger": 1, + "react/no-did-mount-set-state": 1, + "react/no-did-update-set-state": 1, + "react/no-multi-comp": 1, + "react/no-unknown-property": 1, + "react/prop-types": [1, { ignore: ["children"] }], + "react/react-in-jsx-scope": 1, + "react/require-extension": 1, + "react/self-closing-comp": 1, + "react/sort-comp": 1, + "react/wrap-multilines": 1 + } +} diff --git a/index.js b/index.js deleted file mode 100644 index 658ca3a..0000000 --- a/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./src/skylight.jsx'); diff --git a/lib/skylight.js b/lib/skylight.js new file mode 100644 index 0000000..987c8e0 --- /dev/null +++ b/lib/skylight.js @@ -0,0 +1,231 @@ +'use strict'; + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _styles = require('./styles'); + +var _styles2 = _interopRequireDefault(_styles); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var SkyLight = (function (_React$Component) { + _inherits(SkyLight, _React$Component); + + function SkyLight(props) { + _classCallCheck(this, SkyLight); + + var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(SkyLight).call(this, props)); + + _this.state = { isVisible: false }; + return _this; + } + + _createClass(SkyLight, [{ + key: 'componentWillUpdate', + value: function componentWillUpdate(nextProps, nextState) { + if (nextState.isVisible && !this.state.isVisible && this.props.beforeOpen) { + this.props.beforeOpen(); + } + + if (!nextState.isVisible && this.state.isVisible && this.props.beforeClose) { + this.props.beforeClose(); + } + } + }, { + key: 'componentDidUpdate', + value: function componentDidUpdate(prevProps, prevState) { + if (!prevState.isVisible && this.state.isVisible && this.props.afterOpen) { + this.props.afterOpen(); + } + + if (prevState.isVisible && !this.state.isVisible && this.props.afterClose) { + this.props.afterClose(); + } + } + }, { + key: 'show', + value: function show() { + this.setState({ isVisible: true }); + } + }, { + key: 'hide', + value: function hide() { + this.setState({ isVisible: false }); + } + }, { + key: 'render', + value: function render() { + var overlay; + + var dialogStyles = Object.assign(_styles2.default.dialogStyles, this.props.dialogStyles); + var overlayStyles = Object.assign(_styles2.default.overlayStyles, this.props.overlayStyles); + var closeButtonStyle = Object.assign(_styles2.default.closeButtonStyle, this.props.closeButtonStyle); + + if (this.state.isVisible) { + overlayStyles.display = 'block'; + dialogStyles.display = 'block'; + } else { + overlayStyles.display = 'none'; + dialogStyles.display = 'none'; + } + + if (this.props.showOverlay) { + overlay = _react2.default.createElement('div', { style: overlayStyles }); + } + + return _react2.default.createElement( + 'section', + { className: 'skylight-wrapper' }, + overlay, + _react2.default.createElement( + 'div', + { style: dialogStyles }, + _react2.default.createElement( + 'a', + { role: 'button', style: closeButtonStyle, onClick: this.hide }, + '×' + ), + _react2.default.createElement( + 'h2', + null, + this.props.title + ), + this.props.children + ) + ); + } + }]); + + return SkyLight; +})(_react2.default.Component); + +SkyLight.displayName = 'SkyLight'; + +SkyLight.propTypes = { + title: _react2.default.PropTypes.string, + showOverlay: _react2.default.PropTypes.bool, + beforeOpen: _react2.default.PropTypes.func, + afterOpen: _react2.default.PropTypes.func, + beforeClose: _react2.default.PropTypes.func, + afterClose: _react2.default.PropTypes.func, + overlayStyles: _react2.default.PropTypes.object, + dialogStyles: _react2.default.PropTypes.object, + closeButtonStyle: _react2.default.PropTypes.object +}; + +SkyLight.defaultProps = { + title: '', + showOverlay: true, + overlayStyles: _styles2.default.overlayStyles, + dialogStyles: _styles2.default.dialogStyles, + closeButtonStyle: _styles2.default.closeButtonStyle +}; + +exports.default = SkyLight; + +// +// +// +// var React = require('react'); +// var styles = require('./styles'); +// var extend = require('util')._extend; +// +// +// var SkyLight = React.createClass({ +// propTypes: { +// title: React.PropTypes.string, +// showOverlay: React.PropTypes.bool, +// beforeOpen: React.PropTypes.func, +// afterOpen: React.PropTypes.func, +// beforeClose: React.PropTypes.func, +// afterClose: React.PropTypes.func, +// overlayStyles: React.PropTypes.object, +// dialogStyles: React.PropTypes.object, +// closeButtonStyle: React.PropTypes.object +// }, +// getDefaultProps: function () { +// return { +// title: '', +// showOverlay: true, +// overlayStyles: styles.overlayStyles, +// dialogStyles: styles.dialogStyles, +// closeButtonStyle: styles.closeButtonStyle +// } +// }, +// getInitialState: function () { +// return { +// isVisible: false +// }; +// }, +// show: function () { +// this.setState({isVisible: true}); +// }, +// hide: function () { +// this.setState({isVisible: false}); +// }, +// componentWillUpdate: function (nextProps, nextState) { +// if (nextState.isVisible && !this.state.isVisible && this.props.beforeOpen) { +// this.props.beforeOpen(); +// } +// +// if (!nextState.isVisible && this.state.isVisible && this.props.beforeClose) { +// this.props.beforeClose(); +// } +// }, +// componentDidUpdate: function (prevProps, prevState) { +// if (!prevState.isVisible && this.state.isVisible && this.props.afterOpen) { +// this.props.afterOpen(); +// } +// +// if (prevState.isVisible && !this.state.isVisible && this.props.afterClose) { +// this.props.afterClose(); +// } +// }, +// render: function () { +// +// var overlay; +// +// var dialogStyles = extend(styles.dialogStyles, this.props.dialogStyles); +// var overlayStyles = extend(styles.overlayStyles, this.props.overlayStyles); +// var closeButtonStyle = extend(styles.closeButtonStyle, this.props.closeButtonStyle); +// +// if (this.state.isVisible) { +// overlayStyles.display = 'block'; +// dialogStyles.display = 'block'; +// } else { +// overlayStyles.display = 'none'; +// dialogStyles.display = 'none'; +// } +// +// if (this.props.showOverlay) { +// overlay = (
); +// } +// +// return ( +//
+// {overlay} +//
+// × +//

{this.props.title}

+// {this.props.children} +//
+//
+// ) +// } +// }); +// +// module.exports = SkyLight; \ No newline at end of file diff --git a/lib/styles.js b/lib/styles.js new file mode 100644 index 0000000..9727d23 --- /dev/null +++ b/lib/styles.js @@ -0,0 +1,39 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var styles = { + overlayStyles: { + position: 'fixed', + top: 0, + left: 0, + width: '100%', + height: '100%', + zIndex: 99, + backgroundColor: 'rgba(0,0,0,0.3)' + }, + dialogStyles: { + width: '50%', + height: '400px', + position: 'fixed', + top: '50%', + left: '50%', + marginTop: '-200px', + marginLeft: '-25%', + backgroundColor: '#fff', + borderRadius: '2px', + zIndex: 100, + padding: '10px', + boxShadow: '0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28)' + }, + closeButtonStyle: { + cursor: 'pointer', + float: 'right', + fontSize: '1.6em', + margin: '-15px 0' + } +}; + +exports.default = styles; \ No newline at end of file diff --git a/package.json b/package.json index ac20aea..4a4a298 100644 --- a/package.json +++ b/package.json @@ -2,9 +2,11 @@ "name": "react-skylight", "version": "0.2.0", "description": "A react component for modals and dialogs.", - "main": "index.js", + "main": "lib/skylight.js", "scripts": { - "test": "jest" + "build": "babel src -d lib", + "watch": "babel src --watch -d lib", + "lint": "eslint src" }, "repository": { "type": "git", @@ -24,29 +26,21 @@ ], "author": "Marcio Gasparotto", "license": "MIT", - "browserify": { - "transform": [ - [ - "reactify" - ] - ] - }, "peerDependencies": { - "react": ">=0.12.0 <1.0.0" + "react": "*" }, "dependencies": { - "react": "*", - "react-tools": "*", - "browserify": "^8.0.3", - "reactify": "^0.17.1" - }, - "jest": { - "scriptPreprocessor": "preprocessor.js", - "unmockedModulePathPatterns": [ - "node_modules/react" - ] }, "devDependencies": { - "jest-cli": "^0.2.1" + "babel-core": "^6.3.26", + "babel-eslint": "^5.0.0-beta6", + "babel-loader": "^6.2.1", + "babel-preset-es2015": "^6.3.13", + "babel-preset-react": "^6.3.13", + "babel-preset-stage-0": "^6.3.13", + "eslint": "^1.10.3", + "eslint-plugin-react": "^3.14.0", + "jest-cli": "^0.2.1", + "react": "^0.14.5" } } diff --git a/preprocessor.js b/preprocessor.js deleted file mode 100644 index 300111c..0000000 --- a/preprocessor.js +++ /dev/null @@ -1,7 +0,0 @@ - -var ReactTools = require('react-tools'); -module.exports = { - process: function(src) { - return ReactTools.transform(src); - } -}; \ No newline at end of file diff --git a/src/__tests__/skylight-test.js b/src/__tests__/skylight-test.js deleted file mode 100644 index fbc38a8..0000000 --- a/src/__tests__/skylight-test.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Created by Gasparotto on 06/01/15. - */ -jest.dontMock('../skylight.jsx'); - -describe('SkyLight', function() { - - var React; - var SkyLight; - var TestUtils; - - beforeEach(function(){ - React = require('react/addons'); - SkyLight = require('../skylight.jsx'); - TestUtils = React.addons.TestUtils; - }); - - it('Show a title in h2 tag', function() { - - var titleTest = "My title test"; - var skylight = TestUtils.renderIntoDocument( - - ); - - var h2Title = TestUtils.findRenderedDOMComponentWithTag(skylight, 'h2'); - expect(h2Title.getDOMNode().textContent).toEqual(titleTest); - }); - - it('Show a content', function() { - - var text = 'Hi Modal :D'; - var className = 'test'; - var root = React.createElement('div', { className: className }, text); - - var skylight = TestUtils.renderIntoDocument( - {root} - ); - - var content = TestUtils.findRenderedDOMComponentWithClass(skylight, className); - expect(content.getDOMNode().textContent).toEqual(text); - - }); - - - it('Overlay cant be rendered if showOverlay is false', function() { - var skylight = TestUtils.renderIntoDocument( - - ); - var className = 'skylight-dialog__overlay'; - var overlay = TestUtils.scryRenderedDOMComponentsWithClass(skylight, className); - expect(overlay.length).toEqual(0); - }); - - - it('Should be set display:block when isVisible it was changed to true', function() { - - var skylight = TestUtils.renderIntoDocument( - - ); - - var instance = TestUtils.findRenderedComponentWithType(skylight, ); - var modalStyle = TestUtils.findRenderedDOMComponentWithClass(skylight, 'skylight-dialog'); - expect(modalStyle.getDOMNode().style.display).toEqual('none'); - instance.setState({isVisible: true}); - expect(modalStyle.getDOMNode().style.display).toEqual('block'); - instance.setState({isVisible: false}); - expect(modalStyle.getDOMNode().style.display).toEqual('none'); - }); - - -}); \ No newline at end of file diff --git a/src/skylight.js b/src/skylight.js new file mode 100644 index 0000000..ec2f165 --- /dev/null +++ b/src/skylight.js @@ -0,0 +1,196 @@ +import React from 'react'; +import styles from './styles'; + + +class SkyLight extends React.Component { + + constructor(props){ + super(props); + this.state = { isVisible: false }; + } + + componentWillUpdate(nextProps, nextState) { + if (nextState.isVisible && !this.state.isVisible && this.props.beforeOpen) { + this.props.beforeOpen(); + } + + if (!nextState.isVisible && this.state.isVisible && this.props.beforeClose) { + this.props.beforeClose(); + } + } + + componentDidUpdate(prevProps, prevState) { + if (!prevState.isVisible && this.state.isVisible && this.props.afterOpen) { + this.props.afterOpen(); + } + + if (prevState.isVisible && !this.state.isVisible && this.props.afterClose) { + this.props.afterClose(); + } + } + + show() { + this.setState({isVisible: true}); + } + + hide() { + this.setState({isVisible: false}); + } + + render() { + var overlay; + + var dialogStyles = Object.assign(styles.dialogStyles, this.props.dialogStyles); + var overlayStyles = Object.assign(styles.overlayStyles, this.props.overlayStyles); + var closeButtonStyle = Object.assign(styles.closeButtonStyle, this.props.closeButtonStyle); + + if (this.state.isVisible) { + overlayStyles.display = 'block'; + dialogStyles.display = 'block'; + } else { + overlayStyles.display = 'none'; + dialogStyles.display = 'none'; + } + + if (this.props.showOverlay) { + overlay = (
); + } + + return ( +
+ {overlay} +
+ × +

{this.props.title}

+ {this.props.children} +
+
+ ) + } +} + +SkyLight.displayName = 'SkyLight'; + +SkyLight.propTypes = { + title: React.PropTypes.string, + showOverlay: React.PropTypes.bool, + beforeOpen: React.PropTypes.func, + afterOpen: React.PropTypes.func, + beforeClose: React.PropTypes.func, + afterClose: React.PropTypes.func, + overlayStyles: React.PropTypes.object, + dialogStyles: React.PropTypes.object, + closeButtonStyle: React.PropTypes.object +}; + +SkyLight.defaultProps = { + title: '', + showOverlay: true, + overlayStyles: styles.overlayStyles, + dialogStyles: styles.dialogStyles, + closeButtonStyle: styles.closeButtonStyle +}; + +export default SkyLight; + + + + + + + + + + +// +// +// +// var React = require('react'); +// var styles = require('./styles'); +// var extend = require('util')._extend; +// +// +// var SkyLight = React.createClass({ +// propTypes: { +// title: React.PropTypes.string, +// showOverlay: React.PropTypes.bool, +// beforeOpen: React.PropTypes.func, +// afterOpen: React.PropTypes.func, +// beforeClose: React.PropTypes.func, +// afterClose: React.PropTypes.func, +// overlayStyles: React.PropTypes.object, +// dialogStyles: React.PropTypes.object, +// closeButtonStyle: React.PropTypes.object +// }, +// getDefaultProps: function () { +// return { +// title: '', +// showOverlay: true, +// overlayStyles: styles.overlayStyles, +// dialogStyles: styles.dialogStyles, +// closeButtonStyle: styles.closeButtonStyle +// } +// }, +// getInitialState: function () { +// return { +// isVisible: false +// }; +// }, +// show: function () { +// this.setState({isVisible: true}); +// }, +// hide: function () { +// this.setState({isVisible: false}); +// }, +// componentWillUpdate: function (nextProps, nextState) { +// if (nextState.isVisible && !this.state.isVisible && this.props.beforeOpen) { +// this.props.beforeOpen(); +// } +// +// if (!nextState.isVisible && this.state.isVisible && this.props.beforeClose) { +// this.props.beforeClose(); +// } +// }, +// componentDidUpdate: function (prevProps, prevState) { +// if (!prevState.isVisible && this.state.isVisible && this.props.afterOpen) { +// this.props.afterOpen(); +// } +// +// if (prevState.isVisible && !this.state.isVisible && this.props.afterClose) { +// this.props.afterClose(); +// } +// }, +// render: function () { +// +// var overlay; +// +// var dialogStyles = extend(styles.dialogStyles, this.props.dialogStyles); +// var overlayStyles = extend(styles.overlayStyles, this.props.overlayStyles); +// var closeButtonStyle = extend(styles.closeButtonStyle, this.props.closeButtonStyle); +// +// if (this.state.isVisible) { +// overlayStyles.display = 'block'; +// dialogStyles.display = 'block'; +// } else { +// overlayStyles.display = 'none'; +// dialogStyles.display = 'none'; +// } +// +// if (this.props.showOverlay) { +// overlay = (
); +// } +// +// return ( +//
+// {overlay} +//
+// × +//

{this.props.title}

+// {this.props.children} +//
+//
+// ) +// } +// }); +// +// module.exports = SkyLight; diff --git a/src/skylight.jsx b/src/skylight.jsx deleted file mode 100644 index 39139a1..0000000 --- a/src/skylight.jsx +++ /dev/null @@ -1,88 +0,0 @@ -var React = require('react'); -var styles = require('./styles'); -var extend = require('util')._extend; - -var SkyLight = React.createClass({ - propTypes: { - title: React.PropTypes.string, - showOverlay: React.PropTypes.bool, - beforeOpen: React.PropTypes.func, - afterOpen: React.PropTypes.func, - beforeClose: React.PropTypes.func, - afterClose: React.PropTypes.func, - overlayStyles: React.PropTypes.object, - dialogStyles: React.PropTypes.object, - closeButtonStyle: React.PropTypes.object - }, - getDefaultProps: function () { - return { - title: '', - showOverlay: true, - overlayStyles: styles.overlayStyles, - dialogStyles: styles.dialogStyles, - closeButtonStyle: styles.closeButtonStyle - } - }, - getInitialState: function () { - return { - isVisible: false - }; - }, - show: function () { - this.setState({isVisible: true}); - }, - hide: function () { - this.setState({isVisible: false}); - }, - componentWillUpdate: function (nextProps, nextState) { - if (nextState.isVisible && !this.state.isVisible && this.props.beforeOpen) { - this.props.beforeOpen(); - } - - if (!nextState.isVisible && this.state.isVisible && this.props.beforeClose) { - this.props.beforeClose(); - } - }, - componentDidUpdate: function (prevProps, prevState) { - if (!prevState.isVisible && this.state.isVisible && this.props.afterOpen) { - this.props.afterOpen(); - } - - if (prevState.isVisible && !this.state.isVisible && this.props.afterClose) { - this.props.afterClose(); - } - }, - render: function () { - - var overlay; - - var dialogStyles = extend(styles.dialogStyles, this.props.dialogStyles); - var overlayStyles = extend(styles.overlayStyles, this.props.overlayStyles); - var closeButtonStyle = extend(styles.closeButtonStyle, this.props.closeButtonStyle); - - if (this.state.isVisible) { - overlayStyles.display = 'block'; - dialogStyles.display = 'block'; - } else { - overlayStyles.display = 'none'; - dialogStyles.display = 'none'; - } - - if (this.props.showOverlay) { - overlay = (
); - } - - return ( -
- {overlay} -
- × -

{this.props.title}

- {this.props.children} -
-
- ) - } -}); - -module.exports = SkyLight; diff --git a/src/styles.js b/src/styles.js index 593e98e..ff5cb12 100644 --- a/src/styles.js +++ b/src/styles.js @@ -1,32 +1,34 @@ -module.exports = { - overlayStyles: { - position: 'fixed', - top: 0, - left: 0, - width: '100%', - height: '100%', - zIndex: 99, - backgroundColor: 'rgba(0,0,0,0.3)' - }, - dialogStyles: { - width: '50%', - height: '400px', - position: 'fixed', - top: '50%', - left: '50%', - marginTop: '-200px', - marginLeft: '-25%', - backgroundColor: '#fff', - borderRadius: '2px', - zIndex: 100, - padding: '10px', - boxShadow: '0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28)' - }, - closeButtonStyle: { - cursor: 'pointer', - float: 'right', - fontSize: '1.6em', - margin: '-15px 0' - } -}; \ No newline at end of file +const styles = { + overlayStyles: { + position: 'fixed', + top: 0, + left: 0, + width: '100%', + height: '100%', + zIndex: 99, + backgroundColor: 'rgba(0,0,0,0.3)' + }, + dialogStyles: { + width: '50%', + height: '400px', + position: 'fixed', + top: '50%', + left: '50%', + marginTop: '-200px', + marginLeft: '-25%', + backgroundColor: '#fff', + borderRadius: '2px', + zIndex: 100, + padding: '10px', + boxShadow: '0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28)' + }, + closeButtonStyle: { + cursor: 'pointer', + float: 'right', + fontSize: '1.6em', + margin: '-15px 0' + } +}; + +export default styles; diff --git a/styles-examples/default.css b/styles-examples/default.css deleted file mode 100644 index d3ad37c..0000000 --- a/styles-examples/default.css +++ /dev/null @@ -1,31 +0,0 @@ -.skylight-dialog { - width: 50%; - height: 400px; - position: fixed; - top: 50%; - left: 50%; - margin-top: -200px; - margin-left: -25%; - background-color: #fff; - border-radius: 2px; - z-index: 100; - padding: 10px; - box-shadow: 0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28); - overflow: auto; -} - -.skylight-dialog--close { - cursor: pointer; - float: right; - font-size: 1.6em; -} - -.skylight-dialog__overlay { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 99; - background-color: rgba(0,0,0,0.3); -} From 4ed1c429b84ceb426694e35134996e930f1ca2a9 Mon Sep 17 00:00:00 2001 From: Marcio Gasparotto Date: Tue, 5 Jan 2016 22:59:01 -0200 Subject: [PATCH 04/22] fix eslint errors --- README.md | 2 +- lib/skylight.js | 131 +++++++++++----------------------------------- src/skylight.js | 134 ++++++++---------------------------------------- 3 files changed, 52 insertions(+), 215 deletions(-) diff --git a/README.md b/README.md index 8722a6d..695203b 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ var App = React.createClass({ } }); -React.render(, document.getElementById("content")); +ReactDOM.render(, document.getElementById("content")); ``` diff --git a/lib/skylight.js b/lib/skylight.js index 987c8e0..8348cc1 100644 --- a/lib/skylight.js +++ b/lib/skylight.js @@ -66,9 +66,22 @@ var SkyLight = (function (_React$Component) { value: function hide() { this.setState({ isVisible: false }); } + }, { + key: 'onOverlayClicked', + value: function onOverlayClicked() { + if (this.props.hideOnOverlayClicked) { + this.hide(); + } + + if (this.props.onOverlayClicked) { + this.props.onOverlayClicked(); + } + } }, { key: 'render', value: function render() { + var _this2 = this; + var overlay; var dialogStyles = Object.assign(_styles2.default.dialogStyles, this.props.dialogStyles); @@ -84,7 +97,9 @@ var SkyLight = (function (_React$Component) { } if (this.props.showOverlay) { - overlay = _react2.default.createElement('div', { style: overlayStyles }); + overlay = _react2.default.createElement('div', { onClick: function onClick() { + return _this2.onOverlayClicked(); + }, style: overlayStyles }); } return _react2.default.createElement( @@ -96,7 +111,9 @@ var SkyLight = (function (_React$Component) { { style: dialogStyles }, _react2.default.createElement( 'a', - { role: 'button', style: closeButtonStyle, onClick: this.hide }, + { onClick: function onClick() { + return _this2.hide(); + }, role: 'button', style: closeButtonStyle }, '×' ), _react2.default.createElement( @@ -116,15 +133,17 @@ var SkyLight = (function (_React$Component) { SkyLight.displayName = 'SkyLight'; SkyLight.propTypes = { - title: _react2.default.PropTypes.string, - showOverlay: _react2.default.PropTypes.bool, - beforeOpen: _react2.default.PropTypes.func, + afterClose: _react2.default.PropTypes.func, afterOpen: _react2.default.PropTypes.func, beforeClose: _react2.default.PropTypes.func, - afterClose: _react2.default.PropTypes.func, - overlayStyles: _react2.default.PropTypes.object, + beforeOpen: _react2.default.PropTypes.func, + closeButtonStyle: _react2.default.PropTypes.object, dialogStyles: _react2.default.PropTypes.object, - closeButtonStyle: _react2.default.PropTypes.object + hideOnOverlayClicked: _react2.default.PropTypes.bool, + onOverlayClicked: _react2.default.PropTypes.func, + overlayStyles: _react2.default.PropTypes.object, + showOverlay: _react2.default.PropTypes.bool, + title: _react2.default.PropTypes.string }; SkyLight.defaultProps = { @@ -132,100 +151,8 @@ SkyLight.defaultProps = { showOverlay: true, overlayStyles: _styles2.default.overlayStyles, dialogStyles: _styles2.default.dialogStyles, - closeButtonStyle: _styles2.default.closeButtonStyle + closeButtonStyle: _styles2.default.closeButtonStyle, + hideOnOverlayClicked: false }; exports.default = SkyLight; - -// -// -// -// var React = require('react'); -// var styles = require('./styles'); -// var extend = require('util')._extend; -// -// -// var SkyLight = React.createClass({ -// propTypes: { -// title: React.PropTypes.string, -// showOverlay: React.PropTypes.bool, -// beforeOpen: React.PropTypes.func, -// afterOpen: React.PropTypes.func, -// beforeClose: React.PropTypes.func, -// afterClose: React.PropTypes.func, -// overlayStyles: React.PropTypes.object, -// dialogStyles: React.PropTypes.object, -// closeButtonStyle: React.PropTypes.object -// }, -// getDefaultProps: function () { -// return { -// title: '', -// showOverlay: true, -// overlayStyles: styles.overlayStyles, -// dialogStyles: styles.dialogStyles, -// closeButtonStyle: styles.closeButtonStyle -// } -// }, -// getInitialState: function () { -// return { -// isVisible: false -// }; -// }, -// show: function () { -// this.setState({isVisible: true}); -// }, -// hide: function () { -// this.setState({isVisible: false}); -// }, -// componentWillUpdate: function (nextProps, nextState) { -// if (nextState.isVisible && !this.state.isVisible && this.props.beforeOpen) { -// this.props.beforeOpen(); -// } -// -// if (!nextState.isVisible && this.state.isVisible && this.props.beforeClose) { -// this.props.beforeClose(); -// } -// }, -// componentDidUpdate: function (prevProps, prevState) { -// if (!prevState.isVisible && this.state.isVisible && this.props.afterOpen) { -// this.props.afterOpen(); -// } -// -// if (prevState.isVisible && !this.state.isVisible && this.props.afterClose) { -// this.props.afterClose(); -// } -// }, -// render: function () { -// -// var overlay; -// -// var dialogStyles = extend(styles.dialogStyles, this.props.dialogStyles); -// var overlayStyles = extend(styles.overlayStyles, this.props.overlayStyles); -// var closeButtonStyle = extend(styles.closeButtonStyle, this.props.closeButtonStyle); -// -// if (this.state.isVisible) { -// overlayStyles.display = 'block'; -// dialogStyles.display = 'block'; -// } else { -// overlayStyles.display = 'none'; -// dialogStyles.display = 'none'; -// } -// -// if (this.props.showOverlay) { -// overlay = (
); -// } -// -// return ( -//
-// {overlay} -//
-// × -//

{this.props.title}

-// {this.props.children} -//
-//
-// ) -// } -// }); -// -// module.exports = SkyLight; \ No newline at end of file diff --git a/src/skylight.js b/src/skylight.js index ec2f165..532d9e2 100644 --- a/src/skylight.js +++ b/src/skylight.js @@ -1,7 +1,6 @@ import React from 'react'; import styles from './styles'; - class SkyLight extends React.Component { constructor(props){ @@ -37,6 +36,16 @@ class SkyLight extends React.Component { this.setState({isVisible: false}); } + onOverlayClicked() { + if(this.props.hideOnOverlayClicked) { + this.hide(); + } + + if(this.props.onOverlayClicked) { + this.props.onOverlayClicked(); + } + } + render() { var overlay; @@ -53,14 +62,14 @@ class SkyLight extends React.Component { } if (this.props.showOverlay) { - overlay = (
); + overlay = (
this.onOverlayClicked()} style={overlayStyles}>
); } return (
{overlay}
- × + this.hide()} role="button" style={closeButtonStyle} >×

{this.props.title}

{this.props.children}
@@ -72,15 +81,17 @@ class SkyLight extends React.Component { SkyLight.displayName = 'SkyLight'; SkyLight.propTypes = { - title: React.PropTypes.string, - showOverlay: React.PropTypes.bool, - beforeOpen: React.PropTypes.func, + afterClose: React.PropTypes.func, afterOpen: React.PropTypes.func, beforeClose: React.PropTypes.func, - afterClose: React.PropTypes.func, - overlayStyles: React.PropTypes.object, + beforeOpen: React.PropTypes.func, + closeButtonStyle: React.PropTypes.object, dialogStyles: React.PropTypes.object, - closeButtonStyle: React.PropTypes.object + hideOnOverlayClicked: React.PropTypes.bool, + onOverlayClicked: React.PropTypes.func, + overlayStyles: React.PropTypes.object, + showOverlay: React.PropTypes.bool, + title: React.PropTypes.string }; SkyLight.defaultProps = { @@ -88,109 +99,8 @@ SkyLight.defaultProps = { showOverlay: true, overlayStyles: styles.overlayStyles, dialogStyles: styles.dialogStyles, - closeButtonStyle: styles.closeButtonStyle + closeButtonStyle: styles.closeButtonStyle, + hideOnOverlayClicked: false }; export default SkyLight; - - - - - - - - - - -// -// -// -// var React = require('react'); -// var styles = require('./styles'); -// var extend = require('util')._extend; -// -// -// var SkyLight = React.createClass({ -// propTypes: { -// title: React.PropTypes.string, -// showOverlay: React.PropTypes.bool, -// beforeOpen: React.PropTypes.func, -// afterOpen: React.PropTypes.func, -// beforeClose: React.PropTypes.func, -// afterClose: React.PropTypes.func, -// overlayStyles: React.PropTypes.object, -// dialogStyles: React.PropTypes.object, -// closeButtonStyle: React.PropTypes.object -// }, -// getDefaultProps: function () { -// return { -// title: '', -// showOverlay: true, -// overlayStyles: styles.overlayStyles, -// dialogStyles: styles.dialogStyles, -// closeButtonStyle: styles.closeButtonStyle -// } -// }, -// getInitialState: function () { -// return { -// isVisible: false -// }; -// }, -// show: function () { -// this.setState({isVisible: true}); -// }, -// hide: function () { -// this.setState({isVisible: false}); -// }, -// componentWillUpdate: function (nextProps, nextState) { -// if (nextState.isVisible && !this.state.isVisible && this.props.beforeOpen) { -// this.props.beforeOpen(); -// } -// -// if (!nextState.isVisible && this.state.isVisible && this.props.beforeClose) { -// this.props.beforeClose(); -// } -// }, -// componentDidUpdate: function (prevProps, prevState) { -// if (!prevState.isVisible && this.state.isVisible && this.props.afterOpen) { -// this.props.afterOpen(); -// } -// -// if (prevState.isVisible && !this.state.isVisible && this.props.afterClose) { -// this.props.afterClose(); -// } -// }, -// render: function () { -// -// var overlay; -// -// var dialogStyles = extend(styles.dialogStyles, this.props.dialogStyles); -// var overlayStyles = extend(styles.overlayStyles, this.props.overlayStyles); -// var closeButtonStyle = extend(styles.closeButtonStyle, this.props.closeButtonStyle); -// -// if (this.state.isVisible) { -// overlayStyles.display = 'block'; -// dialogStyles.display = 'block'; -// } else { -// overlayStyles.display = 'none'; -// dialogStyles.display = 'none'; -// } -// -// if (this.props.showOverlay) { -// overlay = (
); -// } -// -// return ( -//
-// {overlay} -//
-// × -//

{this.props.title}

-// {this.props.children} -//
-//
-// ) -// } -// }); -// -// module.exports = SkyLight; From a757ba92417fc23741bc5ae1da12753b8132acbe Mon Sep 17 00:00:00 2001 From: Marcio Gasparotto Date: Sat, 9 Jan 2016 20:43:29 -0200 Subject: [PATCH 05/22] Prepare to up to version 0.3.0 --- lib/skylight.js | 17 +++++++++++------ lib/styles.js | 12 ++++++++---- package.json | 2 +- src/skylight.js | 19 ++++++++++++------- src/styles.js | 12 ++++++++---- 5 files changed, 40 insertions(+), 22 deletions(-) diff --git a/lib/skylight.js b/lib/skylight.js index 8348cc1..c5c52f8 100644 --- a/lib/skylight.js +++ b/lib/skylight.js @@ -71,6 +71,9 @@ var SkyLight = (function (_React$Component) { value: function onOverlayClicked() { if (this.props.hideOnOverlayClicked) { this.hide(); + if (this.props.onOverlayClicked) { + this.props.onOverlayClicked(); + } } if (this.props.onOverlayClicked) { @@ -84,9 +87,10 @@ var SkyLight = (function (_React$Component) { var overlay; - var dialogStyles = Object.assign(_styles2.default.dialogStyles, this.props.dialogStyles); - var overlayStyles = Object.assign(_styles2.default.overlayStyles, this.props.overlayStyles); - var closeButtonStyle = Object.assign(_styles2.default.closeButtonStyle, this.props.closeButtonStyle); + var dialogStyles = Object.assign({}, _styles2.default.dialogStyles, this.props.dialogStyles); + var overlayStyles = Object.assign({}, _styles2.default.overlayStyles, this.props.overlayStyles); + var closeButtonStyle = Object.assign({}, _styles2.default.closeButtonStyle, this.props.closeButtonStyle); + var titleStyle = Object.assign({}, _styles2.default.title, this.props.titleStyle); if (this.state.isVisible) { overlayStyles.display = 'block'; @@ -118,7 +122,7 @@ var SkyLight = (function (_React$Component) { ), _react2.default.createElement( 'h2', - null, + { style: titleStyle }, this.props.title ), this.props.children @@ -143,7 +147,8 @@ SkyLight.propTypes = { onOverlayClicked: _react2.default.PropTypes.func, overlayStyles: _react2.default.PropTypes.object, showOverlay: _react2.default.PropTypes.bool, - title: _react2.default.PropTypes.string + title: _react2.default.PropTypes.string, + titleStyle: _react2.default.PropTypes.object }; SkyLight.defaultProps = { @@ -155,4 +160,4 @@ SkyLight.defaultProps = { hideOnOverlayClicked: false }; -exports.default = SkyLight; +exports.default = SkyLight; \ No newline at end of file diff --git a/lib/styles.js b/lib/styles.js index 9727d23..e8327bc 100644 --- a/lib/styles.js +++ b/lib/styles.js @@ -25,14 +25,18 @@ var styles = { backgroundColor: '#fff', borderRadius: '2px', zIndex: 100, - padding: '10px', + padding: '15px', boxShadow: '0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28)' }, + title: { + marginTop: '0' + }, closeButtonStyle: { cursor: 'pointer', - float: 'right', - fontSize: '1.6em', - margin: '-15px 0' + position: 'absolute', + fontSize: '1.8em', + right: '10px', + top: '0' } }; diff --git a/package.json b/package.json index 4a4a298..62ec6fa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-skylight", - "version": "0.2.0", + "version": "0.3.0", "description": "A react component for modals and dialogs.", "main": "lib/skylight.js", "scripts": { diff --git a/src/skylight.js b/src/skylight.js index 532d9e2..f35b417 100644 --- a/src/skylight.js +++ b/src/skylight.js @@ -39,6 +39,9 @@ class SkyLight extends React.Component { onOverlayClicked() { if(this.props.hideOnOverlayClicked) { this.hide(); + if(this.props.onOverlayClicked) { + this.props.onOverlayClicked(); + } } if(this.props.onOverlayClicked) { @@ -49,9 +52,10 @@ class SkyLight extends React.Component { render() { var overlay; - var dialogStyles = Object.assign(styles.dialogStyles, this.props.dialogStyles); - var overlayStyles = Object.assign(styles.overlayStyles, this.props.overlayStyles); - var closeButtonStyle = Object.assign(styles.closeButtonStyle, this.props.closeButtonStyle); + var dialogStyles = Object.assign({}, styles.dialogStyles, this.props.dialogStyles); + var overlayStyles = Object.assign({}, styles.overlayStyles, this.props.overlayStyles); + var closeButtonStyle = Object.assign({}, styles.closeButtonStyle, this.props.closeButtonStyle); + var titleStyle = Object.assign({}, styles.title, this.props.titleStyle); if (this.state.isVisible) { overlayStyles.display = 'block'; @@ -69,9 +73,9 @@ class SkyLight extends React.Component {
{overlay}
- this.hide()} role="button" style={closeButtonStyle} >× -

{this.props.title}

- {this.props.children} + this.hide()} role="button" style={closeButtonStyle} >× +

{this.props.title}

+ {this.props.children}
) @@ -91,7 +95,8 @@ SkyLight.propTypes = { onOverlayClicked: React.PropTypes.func, overlayStyles: React.PropTypes.object, showOverlay: React.PropTypes.bool, - title: React.PropTypes.string + title: React.PropTypes.string, + titleStyle: React.PropTypes.object }; SkyLight.defaultProps = { diff --git a/src/styles.js b/src/styles.js index ff5cb12..74f70a2 100644 --- a/src/styles.js +++ b/src/styles.js @@ -20,14 +20,18 @@ const styles = { backgroundColor: '#fff', borderRadius: '2px', zIndex: 100, - padding: '10px', + padding: '15px', boxShadow: '0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28)' }, + title: { + marginTop: '0' + }, closeButtonStyle: { cursor: 'pointer', - float: 'right', - fontSize: '1.6em', - margin: '-15px 0' + position: 'absolute', + fontSize: '1.8em', + right: '10px', + top: '0' } }; From 2d186457d6d88a5de78dad09d2451f620b5a4144 Mon Sep 17 00:00:00 2001 From: Marcio Gasparotto Date: Sat, 9 Jan 2016 20:58:07 -0200 Subject: [PATCH 06/22] New Readme --- README.md | 156 +++--------------------------------------------------- 1 file changed, 7 insertions(+), 149 deletions(-) diff --git a/README.md b/README.md index 695203b..90c6dd9 100644 --- a/README.md +++ b/README.md @@ -1,182 +1,40 @@ react-skylight ============== -React-SkyLight is a simple react component for modals and dialogs, Powerful, lightweight, and unopinionated in design. +React SkyLight is a simple react component for modals and dialogs. Powerful, lightweight and customizable design. Installation ------------ ```sh -npm install react-skylight +npm install react-skylight --save ``` Features -------- - Very simple modal/dialog -- Unopinionated in or design, (CSS is not included, only a template is suggested (see more below). - Callback before open - Callback after open - Callback before close - Callback after close +- Callback on overlay click +- All styles can be overridden How to use -------------------- -```js +[React skylight demos and docs.](http://marcio.github.io/react-skylight) -//Require react-skylight -var SkyLight = require('react-skylight'); -var App = React.createClass({ - showDialogWithCallBacks: function(){ - this.refs.dialogWithCallBacks.show(); - }, - showSimpleDialog: function(){ - this.refs.simpleDialog.show(); - }, - render:function(){ - return ( -
-

- - -

- I have callbacks! - - Hello, I dont have any callback. - -
- ) - }, - _executeBeforeFirstModalOpen: function(){ - alert('Executed before open'); - }, - _executeAfterFirstModalOpen: function(){ - alert('Executed after open'); - }, - _executeBeforeFirstModalClose: function(){ - alert('Executed before close'); - }, - _executeAfterFirstModalClose: function(){ - alert('Executed after close'); - } -}); - -ReactDOM.render(, document.getElementById("content")); - -``` - - - -Options -------------------- - -####title: (String) -A title for your modal. -``` html -Modal Content -``` -####showOverlay: (Boolean) -Show modal with an overlay (true) or without an overlay (false). - -``` html -Modal With Overlay - -Modal Without Overlay -``` - -####beforeOpen, afterOpen, beforeClose and afterClose: (Function) -A callback functions to execute before and after open and before and after close a modal. You can use just the one you want. -``` html -Modal Content -``` - -##New in 0.2.0 version - -Overlay, dialog and closeButton styles now accept an object that represent your styles. - -If you not declare any style, skyLight will apply the default styles, but if you send an object with one or more properties, your object will override the default property. - -####overlayStyles: (Object) -An object that represent the styles of overlay: -```js -//Default overlay SkyLight styles: -overlayStyles: { - position: 'fixed', - top: 0, - left: 0, - width: '100%', - height: '100%', - zIndex: 99, - backgroundColor: 'rgba(0,0,0,0.3)' -} -``` - -####dialogStyles: (Object) -An object that represent the styles of dialog. -```js -//Default dialog SkyLight styles: -dialogStyles: { - width: '50%', - height: '400px', - position: 'fixed', - top: '50%', - left: '50%', - marginTop: '-200px', - marginLeft: '-25%', - backgroundColor: '#fff', - borderRadius: '2px', - zIndex: 100, - padding: '10px', - boxShadow: '0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28)' -} -``` - -####closeButtonStyle: (Object) -An object that represent the styles of close button -```js -//Default close button SkyLight styles: -closeButtonStyle: { - cursor: 'pointer', - float: 'right', - fontSize: '1.6em', - margin: '-15px 0' -} -``` - -### An Example with new styles, overriding dialog background color to red - - -```js - -var dialogStyles = { - backgroundColor: '#f03' -}; - -Modal Content -``` - - -CSS --------------------- - -External css is no more needed! ##Enjoy! ## Release History - + * 2016-01-09   v0.3.0   Rewrite to ES2015, overlay callback and new site. + * 2015-04-08   v0.2.0   Improvements * 2015-02-03   v0.1.4   Changed skylight.js to skylight.jsx and adjust of namespace From 49e3d3e086c1c258388e354c17a636325b463157 Mon Sep 17 00:00:00 2001 From: darthtrevino Date: Thu, 7 Apr 2016 11:08:32 -0700 Subject: [PATCH 07/22] #32 - Use isVisible prop instead of show/hide --- .eslintrc | 2 +- lib/skylight.js | 73 ++++++++++++++------------------- package.json | 9 ++-- src/skylight.js | 107 +++++++++++++++++++++--------------------------- 4 files changed, 84 insertions(+), 107 deletions(-) diff --git a/.eslintrc b/.eslintrc index bbcd0d6..59dfd49 100644 --- a/.eslintrc +++ b/.eslintrc @@ -21,7 +21,7 @@ "react/jsx-max-props-per-line": [1, {maximum: 6}], "react/jsx-no-duplicate-props": 1, "react/jsx-no-undef": 1, - "react/jsx-quotes": 1, + "jsx-quotes": 1, "react/jsx-sort-prop-types": 1, "react/jsx-sort-props": 1, "react/jsx-uses-react": 1, diff --git a/lib/skylight.js b/lib/skylight.js index c5c52f8..732ad41 100644 --- a/lib/skylight.js +++ b/lib/skylight.js @@ -1,11 +1,11 @@ 'use strict'; -var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); - Object.defineProperty(exports, "__esModule", { value: true }); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + var _react = require('react'); var _react2 = _interopRequireDefault(_react); @@ -22,86 +22,74 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var SkyLight = (function (_React$Component) { +var isOpening = function isOpening(p1, p2) { + return !p1.isVisible && p2.isVisible; +}; +var isClosing = function isClosing(p1, p2) { + return p1.isVisible && !p2.isVisible; +}; + +var SkyLight = function (_React$Component) { _inherits(SkyLight, _React$Component); function SkyLight(props) { _classCallCheck(this, SkyLight); - var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(SkyLight).call(this, props)); - - _this.state = { isVisible: false }; - return _this; + return _possibleConstructorReturn(this, Object.getPrototypeOf(SkyLight).call(this, props)); } _createClass(SkyLight, [{ key: 'componentWillUpdate', value: function componentWillUpdate(nextProps, nextState) { - if (nextState.isVisible && !this.state.isVisible && this.props.beforeOpen) { + if (isOpening(this.props, nextProps) && this.props.beforeOpen) { this.props.beforeOpen(); } - if (!nextState.isVisible && this.state.isVisible && this.props.beforeClose) { + if (isClosing(this.props, nextProps) && this.props.beforeClose) { this.props.beforeClose(); } } }, { key: 'componentDidUpdate', value: function componentDidUpdate(prevProps, prevState) { - if (!prevState.isVisible && this.state.isVisible && this.props.afterOpen) { + if (isOpening(prevProps, this.props) && this.props.afterOpen) { this.props.afterOpen(); } - if (prevState.isVisible && !this.state.isVisible && this.props.afterClose) { + if (isClosing(prevProps, this.props) && this.props.afterClose) { this.props.afterClose(); } } - }, { - key: 'show', - value: function show() { - this.setState({ isVisible: true }); - } - }, { - key: 'hide', - value: function hide() { - this.setState({ isVisible: false }); - } }, { key: 'onOverlayClicked', value: function onOverlayClicked() { - if (this.props.hideOnOverlayClicked) { - this.hide(); - if (this.props.onOverlayClicked) { - this.props.onOverlayClicked(); - } - } - if (this.props.onOverlayClicked) { this.props.onOverlayClicked(); } } + }, { + key: 'onCloseClicked', + value: function onCloseClicked() { + if (this.props.onCloseClicked) { + this.props.onCloseClicked(); + } + } }, { key: 'render', value: function render() { var _this2 = this; - var overlay; - var dialogStyles = Object.assign({}, _styles2.default.dialogStyles, this.props.dialogStyles); var overlayStyles = Object.assign({}, _styles2.default.overlayStyles, this.props.overlayStyles); var closeButtonStyle = Object.assign({}, _styles2.default.closeButtonStyle, this.props.closeButtonStyle); var titleStyle = Object.assign({}, _styles2.default.title, this.props.titleStyle); - if (this.state.isVisible) { - overlayStyles.display = 'block'; - dialogStyles.display = 'block'; - } else { - overlayStyles.display = 'none'; - dialogStyles.display = 'none'; - } + var displayStyle = this.props.isVisible ? 'block' : 'none'; + overlayStyles.display = dialogStyles.display = displayStyle; + var overlay = undefined; if (this.props.showOverlay) { - overlay = _react2.default.createElement('div', { onClick: function onClick() { + overlay = _react2.default.createElement('div', { className: 'skylight-overlay', onClick: function onClick() { return _this2.onOverlayClicked(); }, style: overlayStyles }); } @@ -112,11 +100,11 @@ var SkyLight = (function (_React$Component) { overlay, _react2.default.createElement( 'div', - { style: dialogStyles }, + { className: 'skylight-dialog', style: dialogStyles }, _react2.default.createElement( 'a', { onClick: function onClick() { - return _this2.hide(); + return _this2.onCloseClicked(); }, role: 'button', style: closeButtonStyle }, '×' ), @@ -132,10 +120,9 @@ var SkyLight = (function (_React$Component) { }]); return SkyLight; -})(_react2.default.Component); +}(_react2.default.Component); SkyLight.displayName = 'SkyLight'; - SkyLight.propTypes = { afterClose: _react2.default.PropTypes.func, afterOpen: _react2.default.PropTypes.func, @@ -144,6 +131,8 @@ SkyLight.propTypes = { closeButtonStyle: _react2.default.PropTypes.object, dialogStyles: _react2.default.PropTypes.object, hideOnOverlayClicked: _react2.default.PropTypes.bool, + isVisible: _react2.default.PropTypes.bool, + onCloseClicked: _react2.default.PropTypes.func, onOverlayClicked: _react2.default.PropTypes.func, overlayStyles: _react2.default.PropTypes.object, showOverlay: _react2.default.PropTypes.bool, diff --git a/package.json b/package.json index 62ec6fa..2f741a8 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "scripts": { "build": "babel src -d lib", "watch": "babel src --watch -d lib", - "lint": "eslint src" + "lint": "eslint src", + "test": "npm run lint && npm run build" }, "repository": { "type": "git", @@ -29,8 +30,7 @@ "peerDependencies": { "react": "*" }, - "dependencies": { - }, + "dependencies": {}, "devDependencies": { "babel-core": "^6.3.26", "babel-eslint": "^5.0.0-beta6", @@ -41,6 +41,7 @@ "eslint": "^1.10.3", "eslint-plugin-react": "^3.14.0", "jest-cli": "^0.2.1", - "react": "^0.14.5" + "react": "^0.14.5", + "webpack": "^1.12.14" } } diff --git a/src/skylight.js b/src/skylight.js index f35b417..7f38b1d 100644 --- a/src/skylight.js +++ b/src/skylight.js @@ -1,111 +1,98 @@ import React from 'react'; import styles from './styles'; -class SkyLight extends React.Component { +const isOpening = (p1, p2) => !p1.isVisible && p2.isVisible; +const isClosing = (p1, p2) => p1.isVisible && !p2.isVisible; +class SkyLight extends React.Component { constructor(props){ - super(props); - this.state = { isVisible: false }; + super(props); } componentWillUpdate(nextProps, nextState) { - if (nextState.isVisible && !this.state.isVisible && this.props.beforeOpen) { + if (isOpening(this.props, nextProps) && this.props.beforeOpen) { this.props.beforeOpen(); } - if (!nextState.isVisible && this.state.isVisible && this.props.beforeClose) { + if (isClosing(this.props, nextProps) && this.props.beforeClose) { this.props.beforeClose(); } } componentDidUpdate(prevProps, prevState) { - if (!prevState.isVisible && this.state.isVisible && this.props.afterOpen) { + if (isOpening(prevProps, this.props) && this.props.afterOpen) { this.props.afterOpen(); } - if (prevState.isVisible && !this.state.isVisible && this.props.afterClose) { + if (isClosing(prevProps, this.props) && this.props.afterClose) { this.props.afterClose(); } } - show() { - this.setState({isVisible: true}); - } - - hide() { - this.setState({isVisible: false}); - } - onOverlayClicked() { - if(this.props.hideOnOverlayClicked) { - this.hide(); - if(this.props.onOverlayClicked) { - this.props.onOverlayClicked(); + if (this.props.onOverlayClicked) { + this.props.onOverlayClicked(); } - } + } - if(this.props.onOverlayClicked) { - this.props.onOverlayClicked(); - } - } + onCloseClicked() { + if (this.props.onCloseClicked) { + this.props.onCloseClicked(); + } + } render() { - var overlay; + const dialogStyles = Object.assign({}, styles.dialogStyles, this.props.dialogStyles); + const overlayStyles = Object.assign({}, styles.overlayStyles, this.props.overlayStyles); + const closeButtonStyle = Object.assign({}, styles.closeButtonStyle, this.props.closeButtonStyle); + const titleStyle = Object.assign({}, styles.title, this.props.titleStyle); - var dialogStyles = Object.assign({}, styles.dialogStyles, this.props.dialogStyles); - var overlayStyles = Object.assign({}, styles.overlayStyles, this.props.overlayStyles); - var closeButtonStyle = Object.assign({}, styles.closeButtonStyle, this.props.closeButtonStyle); - var titleStyle = Object.assign({}, styles.title, this.props.titleStyle); - - if (this.state.isVisible) { - overlayStyles.display = 'block'; - dialogStyles.display = 'block'; - } else { - overlayStyles.display = 'none'; - dialogStyles.display = 'none'; - } + const displayStyle = this.props.isVisible ? 'block' : 'none'; + overlayStyles.display = dialogStyles.display = displayStyle; + let overlay; if (this.props.showOverlay) { - overlay = (
this.onOverlayClicked()} style={overlayStyles}>
); + overlay = (
this.onOverlayClicked()} style={overlayStyles}>
); } return (
{overlay} -
- ) + ); } } SkyLight.displayName = 'SkyLight'; - SkyLight.propTypes = { - afterClose: React.PropTypes.func, - afterOpen: React.PropTypes.func, - beforeClose: React.PropTypes.func, - beforeOpen: React.PropTypes.func, - closeButtonStyle: React.PropTypes.object, - dialogStyles: React.PropTypes.object, - hideOnOverlayClicked: React.PropTypes.bool, - onOverlayClicked: React.PropTypes.func, - overlayStyles: React.PropTypes.object, - showOverlay: React.PropTypes.bool, - title: React.PropTypes.string, - titleStyle: React.PropTypes.object + afterClose: React.PropTypes.func, + afterOpen: React.PropTypes.func, + beforeClose: React.PropTypes.func, + beforeOpen: React.PropTypes.func, + closeButtonStyle: React.PropTypes.object, + dialogStyles: React.PropTypes.object, + hideOnOverlayClicked: React.PropTypes.bool, + isVisible: React.PropTypes.bool, + onCloseClicked: React.PropTypes.func, + onOverlayClicked: React.PropTypes.func, + overlayStyles: React.PropTypes.object, + showOverlay: React.PropTypes.bool, + title: React.PropTypes.string, + titleStyle: React.PropTypes.object }; SkyLight.defaultProps = { - title: '', - showOverlay: true, - overlayStyles: styles.overlayStyles, - dialogStyles: styles.dialogStyles, - closeButtonStyle: styles.closeButtonStyle, - hideOnOverlayClicked: false + title: '', + showOverlay: true, + overlayStyles: styles.overlayStyles, + dialogStyles: styles.dialogStyles, + closeButtonStyle: styles.closeButtonStyle, + hideOnOverlayClicked: false }; export default SkyLight; From 213715d673806112afbcf1fb4f3c3a7e0927995b Mon Sep 17 00:00:00 2001 From: darthtrevino Date: Thu, 7 Apr 2016 13:39:01 -0700 Subject: [PATCH 08/22] #32 - Break out new SkylightStateless Component * Move .babelrc and .eslintrc to package.json to clean up top-level dir. * Break core functionality into 'SkyLightStateless' component, which can be used in Flux contexts. Update SkyLight component to thunk its internal state to the SkylightStateless props. * Add Module entrypoint file (index.js) so that clients can optionally pick up SkyLight stateles. SkyLight is still the default export. * Use AirBnb's eslint configuration to eliminate some boilerplate. --- .babelrc | 3 - .eslintrc | 41 -------- lib/index.js | 25 +++++ lib/skylight-stateless.js | 117 ++++++++++++++++++++++ lib/skylight.js | 201 ++++++++++++++++---------------------- lib/skylightstateless.js | 131 +++++++++++++++++++++++++ lib/styles.js | 1 - package.json | 31 ++++-- src/index.js | 2 + src/skylight.js | 98 ------------------- src/skylight.jsx | 78 +++++++++++++++ src/skylightstateless.jsx | 81 +++++++++++++++ src/styles.js | 11 +-- 13 files changed, 549 insertions(+), 271 deletions(-) delete mode 100644 .babelrc delete mode 100644 .eslintrc create mode 100644 lib/index.js create mode 100644 lib/skylight-stateless.js create mode 100644 lib/skylightstateless.js create mode 100644 src/index.js delete mode 100644 src/skylight.js create mode 100644 src/skylight.jsx create mode 100644 src/skylightstateless.jsx diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 4687bc4..0000000 --- a/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["es2015", "react", "stage-0"] -} diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 59dfd49..0000000 --- a/.eslintrc +++ /dev/null @@ -1,41 +0,0 @@ -{ - "parser": "babel-eslint", - "env": { - "browser": true, - "node": true - }, - "plugins": [ - "react" - ], - "ecmaFeatures": { - "jsx": true - }, - "rules": { - "quotes": [2, "single"], - "eol-last": [0], - "no-mixed-requires": [0], - "no-underscore-dangle": [0], - "react/display-name": 1, - "react/jsx-boolean-value": 1, - "react/jsx-curly-spacing": 1, - "react/jsx-max-props-per-line": [1, {maximum: 6}], - "react/jsx-no-duplicate-props": 1, - "react/jsx-no-undef": 1, - "jsx-quotes": 1, - "react/jsx-sort-prop-types": 1, - "react/jsx-sort-props": 1, - "react/jsx-uses-react": 1, - "react/jsx-uses-vars": 1, - "react/no-danger": 1, - "react/no-did-mount-set-state": 1, - "react/no-did-update-set-state": 1, - "react/no-multi-comp": 1, - "react/no-unknown-property": 1, - "react/prop-types": [1, { ignore: ["children"] }], - "react/react-in-jsx-scope": 1, - "react/require-extension": 1, - "react/self-closing-comp": 1, - "react/sort-comp": 1, - "react/wrap-multilines": 1 - } -} diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 0000000..fb9b478 --- /dev/null +++ b/lib/index.js @@ -0,0 +1,25 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _skylight = require('./skylight'); + +Object.defineProperty(exports, 'default', { + enumerable: true, + get: function get() { + return _interopRequireDefault(_skylight).default; + } +}); + +var _skylightstateless = require('./skylightstateless'); + +Object.defineProperty(exports, 'SkyLightStateless', { + enumerable: true, + get: function get() { + return _interopRequireDefault(_skylightstateless).default; + } +}); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } \ No newline at end of file diff --git a/lib/skylight-stateless.js b/lib/skylight-stateless.js new file mode 100644 index 0000000..ff41ab1 --- /dev/null +++ b/lib/skylight-stateless.js @@ -0,0 +1,117 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _styles = require('./styles'); + +var _styles2 = _interopRequireDefault(_styles); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var SkylightStateless = function (_React$Component) { + _inherits(SkylightStateless, _React$Component); + + function SkylightStateless() { + _classCallCheck(this, SkylightStateless); + + return _possibleConstructorReturn(this, Object.getPrototypeOf(SkylightStateless).apply(this, arguments)); + } + + _createClass(SkylightStateless, [{ + key: 'onOverlayClicked', + value: function onOverlayClicked() { + if (this.props.onOverlayClicked) { + this.props.onOverlayClicked(); + } + } + }, { + key: 'onCloseClicked', + value: function onCloseClicked() { + if (this.props.onCloseClicked) { + this.props.onCloseClicked(); + } + } + }, { + key: 'render', + value: function render() { + var dialogStyles = Object.assign({}, _styles2.default.dialogStyles, this.props.dialogStyles); + var overlayStyles = Object.assign({}, _styles2.default.overlayStyles, this.props.overlayStyles); + var closeButtonStyle = Object.assign({}, _styles2.default.closeButtonStyle, this.props.closeButtonStyle); + var titleStyle = Object.assign({}, _styles2.default.title, this.props.titleStyle); + + var displayStyle = this.props.isVisible ? 'block' : 'none'; + overlayStyles.display = dialogStyles.display = displayStyle; + + var overlay = undefined; + if (this.props.showOverlay) { + overlay = _react2.default.createElement('div', { className: 'skylight-overlay', onClick: this.onOverlayClicked.bind(this), style: overlayStyles }); + } + + return _react2.default.createElement( + 'section', + { className: 'skylight-wrapper' }, + overlay, + _react2.default.createElement( + 'div', + { className: 'skylight-dialog', style: dialogStyles }, + _react2.default.createElement( + 'a', + { onClick: this.onCloseClicked.bind(this), role: 'button', style: closeButtonStyle }, + '×' + ), + _react2.default.createElement( + 'h2', + { style: titleStyle }, + this.props.title + ), + this.props.children + ) + ); + } + }]); + + return SkylightStateless; +}(_react2.default.Component); + +SkylightStateless.displayName = 'SkyLightStateless'; + +SkylightStateless.sharedPropTypes = { + closeButtonStyle: _react2.default.PropTypes.object, + dialogStyles: _react2.default.PropTypes.object, + onCloseClicked: _react2.default.PropTypes.func, + onOverlayClicked: _react2.default.PropTypes.func, + overlayStyles: _react2.default.PropTypes.object, + showOverlay: _react2.default.PropTypes.bool, + title: _react2.default.PropTypes.string, + titleStyle: _react2.default.PropTypes.object +}; + +SkylightStateless.propTypes = _extends({}, SkyLightStateless.sharedPropTypes, { + isVisible: _react2.default.PropTypes.bool +}); + +SkylightStateless.defaultProps = { + title: '', + showOverlay: true, + overlayStyles: _styles2.default.overlayStyles, + dialogStyles: _styles2.default.dialogStyles, + closeButtonStyle: _styles2.default.closeButtonStyle +}; + +exports.default = SkyLight; \ No newline at end of file diff --git a/lib/skylight.js b/lib/skylight.js index 732ad41..33af981 100644 --- a/lib/skylight.js +++ b/lib/skylight.js @@ -1,18 +1,20 @@ 'use strict'; Object.defineProperty(exports, "__esModule", { - value: true + value: true }); +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _react = require('react'); var _react2 = _interopRequireDefault(_react); -var _styles = require('./styles'); +var _skylightstateless = require('./skylightstateless'); -var _styles2 = _interopRequireDefault(_styles); +var _skylightstateless2 = _interopRequireDefault(_skylightstateless); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } @@ -22,131 +24,100 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var isOpening = function isOpening(p1, p2) { - return !p1.isVisible && p2.isVisible; +var isOpening = function isOpening(s1, s2) { + return !s1.isVisible && s2.isVisible; }; -var isClosing = function isClosing(p1, p2) { - return p1.isVisible && !p2.isVisible; +var isClosing = function isClosing(s1, s2) { + return s1.isVisible && !s2.isVisible; }; var SkyLight = function (_React$Component) { - _inherits(SkyLight, _React$Component); + _inherits(SkyLight, _React$Component); - function SkyLight(props) { - _classCallCheck(this, SkyLight); + function SkyLight(props) { + _classCallCheck(this, SkyLight); - return _possibleConstructorReturn(this, Object.getPrototypeOf(SkyLight).call(this, props)); - } + var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(SkyLight).call(this, props)); - _createClass(SkyLight, [{ - key: 'componentWillUpdate', - value: function componentWillUpdate(nextProps, nextState) { - if (isOpening(this.props, nextProps) && this.props.beforeOpen) { - this.props.beforeOpen(); - } + _this.state = { isVisible: false }; + return _this; + } - if (isClosing(this.props, nextProps) && this.props.beforeClose) { - this.props.beforeClose(); - } - } - }, { - key: 'componentDidUpdate', - value: function componentDidUpdate(prevProps, prevState) { - if (isOpening(prevProps, this.props) && this.props.afterOpen) { - this.props.afterOpen(); - } - - if (isClosing(prevProps, this.props) && this.props.afterClose) { - this.props.afterClose(); - } - } - }, { - key: 'onOverlayClicked', - value: function onOverlayClicked() { - if (this.props.onOverlayClicked) { - this.props.onOverlayClicked(); - } - } - }, { - key: 'onCloseClicked', - value: function onCloseClicked() { - if (this.props.onCloseClicked) { - this.props.onCloseClicked(); - } - } - }, { - key: 'render', - value: function render() { - var _this2 = this; - - var dialogStyles = Object.assign({}, _styles2.default.dialogStyles, this.props.dialogStyles); - var overlayStyles = Object.assign({}, _styles2.default.overlayStyles, this.props.overlayStyles); - var closeButtonStyle = Object.assign({}, _styles2.default.closeButtonStyle, this.props.closeButtonStyle); - var titleStyle = Object.assign({}, _styles2.default.title, this.props.titleStyle); - - var displayStyle = this.props.isVisible ? 'block' : 'none'; - overlayStyles.display = dialogStyles.display = displayStyle; - - var overlay = undefined; - if (this.props.showOverlay) { - overlay = _react2.default.createElement('div', { className: 'skylight-overlay', onClick: function onClick() { - return _this2.onOverlayClicked(); - }, style: overlayStyles }); - } - - return _react2.default.createElement( - 'section', - { className: 'skylight-wrapper' }, - overlay, - _react2.default.createElement( - 'div', - { className: 'skylight-dialog', style: dialogStyles }, - _react2.default.createElement( - 'a', - { onClick: function onClick() { - return _this2.onCloseClicked(); - }, role: 'button', style: closeButtonStyle }, - '×' - ), - _react2.default.createElement( - 'h2', - { style: titleStyle }, - this.props.title - ), - this.props.children - ) - ); + _createClass(SkyLight, [{ + key: 'componentWillUpdate', + value: function componentWillUpdate(nextProps, nextState) { + if (isOpening(this.state, nextState) && this.props.beforeOpen) { + this.props.beforeOpen(); + } + + if (isClosing(this.state, nextState) && this.props.beforeClose) { + this.props.beforeClose(); + } + } + }, { + key: 'componentDidUpdate', + value: function componentDidUpdate(prevProps, prevState) { + if (isOpening(prevState, this.state) && this.props.afterOpen) { + this.props.afterOpen(); + } + + if (isClosing(prevState, this.state) && this.props.afterClose) { + this.props.afterClose(); + } + } + }, { + key: 'show', + value: function show() { + this.setState({ isVisible: true }); + } + }, { + key: 'hide', + value: function hide() { + this.setState({ isVisible: false }); + } + }, { + key: '_onOverlayClicked', + value: function _onOverlayClicked() { + if (this.props.hideOnOverlayClicked) { + this.hide(); + } + + if (this.props.onOverlayClicked) { + this.props.onOverlayClicked(); + } + } + }, { + key: 'render', + value: function render() { + var _this2 = this; + + return _react2.default.createElement(_skylightstateless2.default, _extends({}, this.props, { + isVisible: this.state.isVisible, + onOverlayClicked: function onOverlayClicked() { + return _this2._onOverlayClicked(); + }, + onCloseClicked: function onCloseClicked() { + return _this2.hide(); } - }]); + })); + } + }]); - return SkyLight; + return SkyLight; }(_react2.default.Component); SkyLight.displayName = 'SkyLight'; -SkyLight.propTypes = { - afterClose: _react2.default.PropTypes.func, - afterOpen: _react2.default.PropTypes.func, - beforeClose: _react2.default.PropTypes.func, - beforeOpen: _react2.default.PropTypes.func, - closeButtonStyle: _react2.default.PropTypes.object, - dialogStyles: _react2.default.PropTypes.object, - hideOnOverlayClicked: _react2.default.PropTypes.bool, - isVisible: _react2.default.PropTypes.bool, - onCloseClicked: _react2.default.PropTypes.func, - onOverlayClicked: _react2.default.PropTypes.func, - overlayStyles: _react2.default.PropTypes.object, - showOverlay: _react2.default.PropTypes.bool, - title: _react2.default.PropTypes.string, - titleStyle: _react2.default.PropTypes.object -}; -SkyLight.defaultProps = { - title: '', - showOverlay: true, - overlayStyles: _styles2.default.overlayStyles, - dialogStyles: _styles2.default.dialogStyles, - closeButtonStyle: _styles2.default.closeButtonStyle, - hideOnOverlayClicked: false -}; +SkyLight.propTypes = _extends({}, _skylightstateless2.default.sharedPropTypes, { + afterClose: _react2.default.PropTypes.func, + afterOpen: _react2.default.PropTypes.func, + beforeClose: _react2.default.PropTypes.func, + beforeOpen: _react2.default.PropTypes.func, + hideOnOverlayClicked: _react2.default.PropTypes.bool +}); + +SkyLight.defaultProps = _extends({}, _skylightstateless2.default.defaultProps, { + hideOnOverlayClicked: false +}); exports.default = SkyLight; \ No newline at end of file diff --git a/lib/skylightstateless.js b/lib/skylightstateless.js new file mode 100644 index 0000000..550e3fa --- /dev/null +++ b/lib/skylightstateless.js @@ -0,0 +1,131 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _styles = require('./styles'); + +var _styles2 = _interopRequireDefault(_styles); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var SkyLightStateless = function (_React$Component) { + _inherits(SkyLightStateless, _React$Component); + + function SkyLightStateless() { + _classCallCheck(this, SkyLightStateless); + + return _possibleConstructorReturn(this, Object.getPrototypeOf(SkyLightStateless).apply(this, arguments)); + } + + _createClass(SkyLightStateless, [{ + key: 'onOverlayClicked', + value: function onOverlayClicked() { + if (this.props.onOverlayClicked) { + this.props.onOverlayClicked(); + } + } + }, { + key: 'onCloseClicked', + value: function onCloseClicked() { + if (this.props.onCloseClicked) { + this.props.onCloseClicked(); + } + } + }, { + key: 'render', + value: function render() { + var _this2 = this; + + var mergeStyles = function mergeStyles(key) { + return Object.assign({}, _styles2.default[key], _this2.props[key]); + }; + var dialogStyles = mergeStyles('dialogStyles'); + var overlayStyles = mergeStyles('overlayStyles'); + var closeButtonStyle = mergeStyles('closeButtonStyle'); + var titleStyle = mergeStyles('titleStyle'); + var displayStyle = this.props.isVisible ? 'block' : 'none'; + overlayStyles.display = dialogStyles.display = displayStyle; + + var overlay = undefined; + if (this.props.showOverlay) { + overlay = _react2.default.createElement('div', { className: 'skylight-overlay', + onClick: function onClick() { + return _this2.onOverlayClicked(); + }, + style: overlayStyles + }); + } + + return _react2.default.createElement( + 'section', + { className: 'skylight-wrapper' }, + overlay, + _react2.default.createElement( + 'div', + { className: 'skylight-dialog', style: dialogStyles }, + _react2.default.createElement( + 'a', + { role: 'button', + onClick: function onClick() { + return _this2.onCloseClicked(); + }, + style: closeButtonStyle + }, + '×' + ), + _react2.default.createElement( + 'h2', + { style: titleStyle }, + this.props.title + ), + this.props.children + ) + ); + } + }]); + + return SkyLightStateless; +}(_react2.default.Component); + +SkyLightStateless.displayName = 'SkyLightStateless'; + +SkyLightStateless.sharedPropTypes = { + closeButtonStyle: _react2.default.PropTypes.object, + dialogStyles: _react2.default.PropTypes.object, + onCloseClicked: _react2.default.PropTypes.func, + onOverlayClicked: _react2.default.PropTypes.func, + overlayStyles: _react2.default.PropTypes.object, + showOverlay: _react2.default.PropTypes.bool, + title: _react2.default.PropTypes.string, + titleStyle: _react2.default.PropTypes.object +}; + +SkyLightStateless.propTypes = _extends({}, SkyLightStateless.sharedPropTypes, { + isVisible: _react2.default.PropTypes.bool +}); + +SkyLightStateless.defaultProps = { + title: '', + showOverlay: true, + overlayStyles: _styles2.default.overlayStyles, + dialogStyles: _styles2.default.dialogStyles, + closeButtonStyle: _styles2.default.closeButtonStyle +}; + +exports.default = SkyLightStateless; \ No newline at end of file diff --git a/lib/styles.js b/lib/styles.js index e8327bc..f92218c 100644 --- a/lib/styles.js +++ b/lib/styles.js @@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true }); - var styles = { overlayStyles: { position: 'fixed', diff --git a/package.json b/package.json index 2f741a8..0623a16 100644 --- a/package.json +++ b/package.json @@ -2,11 +2,11 @@ "name": "react-skylight", "version": "0.3.0", "description": "A react component for modals and dialogs.", - "main": "lib/skylight.js", + "main": "lib/index.js", "scripts": { "build": "babel src -d lib", "watch": "babel src --watch -d lib", - "lint": "eslint src", + "lint": "eslint 'src/*.{js,jsx}'", "test": "npm run lint && npm run build" }, "repository": { @@ -33,15 +33,32 @@ "dependencies": {}, "devDependencies": { "babel-core": "^6.3.26", - "babel-eslint": "^5.0.0-beta6", + "babel-eslint": "^6.0.2", "babel-loader": "^6.2.1", "babel-preset-es2015": "^6.3.13", - "babel-preset-react": "^6.3.13", + "babel-preset-react": "^6.5.0", "babel-preset-stage-0": "^6.3.13", - "eslint": "^1.10.3", - "eslint-plugin-react": "^3.14.0", - "jest-cli": "^0.2.1", + "eslint": "^2.7.0", + "eslint-config-airbnb": "^6.2.0", + "eslint-plugin-react": "^4.3.0", + "jest-cli": "^0.10.0", "react": "^0.14.5", "webpack": "^1.12.14" + }, + "babel": { + "presets": [ + "es2015", + "react", + "stage-0" + ], + "plugins": [] + }, + "eslintConfig": { + "extends": "airbnb", + "parserOptions": { + "ecmaFeatures": { + "experimentalObjectRestSpread": true + } + } } } diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..aae586f --- /dev/null +++ b/src/index.js @@ -0,0 +1,2 @@ +export { default as default } from './skylight'; +export { default as SkyLightStateless } from './skylightstateless'; diff --git a/src/skylight.js b/src/skylight.js deleted file mode 100644 index 7f38b1d..0000000 --- a/src/skylight.js +++ /dev/null @@ -1,98 +0,0 @@ -import React from 'react'; -import styles from './styles'; - -const isOpening = (p1, p2) => !p1.isVisible && p2.isVisible; -const isClosing = (p1, p2) => p1.isVisible && !p2.isVisible; - -class SkyLight extends React.Component { - constructor(props){ - super(props); - } - - componentWillUpdate(nextProps, nextState) { - if (isOpening(this.props, nextProps) && this.props.beforeOpen) { - this.props.beforeOpen(); - } - - if (isClosing(this.props, nextProps) && this.props.beforeClose) { - this.props.beforeClose(); - } - } - - componentDidUpdate(prevProps, prevState) { - if (isOpening(prevProps, this.props) && this.props.afterOpen) { - this.props.afterOpen(); - } - - if (isClosing(prevProps, this.props) && this.props.afterClose) { - this.props.afterClose(); - } - } - - onOverlayClicked() { - if (this.props.onOverlayClicked) { - this.props.onOverlayClicked(); - } - } - - onCloseClicked() { - if (this.props.onCloseClicked) { - this.props.onCloseClicked(); - } - } - - render() { - const dialogStyles = Object.assign({}, styles.dialogStyles, this.props.dialogStyles); - const overlayStyles = Object.assign({}, styles.overlayStyles, this.props.overlayStyles); - const closeButtonStyle = Object.assign({}, styles.closeButtonStyle, this.props.closeButtonStyle); - const titleStyle = Object.assign({}, styles.title, this.props.titleStyle); - - const displayStyle = this.props.isVisible ? 'block' : 'none'; - overlayStyles.display = dialogStyles.display = displayStyle; - - let overlay; - if (this.props.showOverlay) { - overlay = (
this.onOverlayClicked()} style={overlayStyles}>
); - } - - return ( -
- {overlay} -
- this.onCloseClicked()} role="button" style={closeButtonStyle} >× -

{this.props.title}

- {this.props.children} -
-
- ); - } -} - -SkyLight.displayName = 'SkyLight'; -SkyLight.propTypes = { - afterClose: React.PropTypes.func, - afterOpen: React.PropTypes.func, - beforeClose: React.PropTypes.func, - beforeOpen: React.PropTypes.func, - closeButtonStyle: React.PropTypes.object, - dialogStyles: React.PropTypes.object, - hideOnOverlayClicked: React.PropTypes.bool, - isVisible: React.PropTypes.bool, - onCloseClicked: React.PropTypes.func, - onOverlayClicked: React.PropTypes.func, - overlayStyles: React.PropTypes.object, - showOverlay: React.PropTypes.bool, - title: React.PropTypes.string, - titleStyle: React.PropTypes.object -}; - -SkyLight.defaultProps = { - title: '', - showOverlay: true, - overlayStyles: styles.overlayStyles, - dialogStyles: styles.dialogStyles, - closeButtonStyle: styles.closeButtonStyle, - hideOnOverlayClicked: false -}; - -export default SkyLight; diff --git a/src/skylight.jsx b/src/skylight.jsx new file mode 100644 index 0000000..132fe28 --- /dev/null +++ b/src/skylight.jsx @@ -0,0 +1,78 @@ +import React from 'react'; +import SkylightStateless from './skylightstateless'; + +const isOpening = (s1, s2) => !s1.isVisible && s2.isVisible; +const isClosing = (s1, s2) => s1.isVisible && !s2.isVisible; + +class SkyLight extends React.Component { + + constructor(props) { + super(props); + this.state = { isVisible: false }; + } + + componentWillUpdate(nextProps, nextState) { + if (isOpening(this.state, nextState) && this.props.beforeOpen) { + this.props.beforeOpen(); + } + + if (isClosing(this.state, nextState) && this.props.beforeClose) { + this.props.beforeClose(); + } + } + + componentDidUpdate(prevProps, prevState) { + if (isOpening(prevState, this.state) && this.props.afterOpen) { + this.props.afterOpen(); + } + + if (isClosing(prevState, this.state) && this.props.afterClose) { + this.props.afterClose(); + } + } + + show() { + this.setState({ isVisible: true }); + } + + hide() { + this.setState({ isVisible: false }); + } + + _onOverlayClicked() { + if (this.props.hideOnOverlayClicked) { + this.hide(); + } + + if (this.props.onOverlayClicked) { + this.props.onOverlayClicked(); + } + } + + render() { + return ( this._onOverlayClicked()} + onCloseClicked={() => this.hide()} + />); + } +} + +SkyLight.displayName = 'SkyLight'; + +SkyLight.propTypes = { + ...SkylightStateless.sharedPropTypes, + afterClose: React.PropTypes.func, + afterOpen: React.PropTypes.func, + beforeClose: React.PropTypes.func, + beforeOpen: React.PropTypes.func, + hideOnOverlayClicked: React.PropTypes.bool, +}; + +SkyLight.defaultProps = { + ...SkylightStateless.defaultProps, + hideOnOverlayClicked: false, +}; + +export default SkyLight; diff --git a/src/skylightstateless.jsx b/src/skylightstateless.jsx new file mode 100644 index 0000000..6d9a117 --- /dev/null +++ b/src/skylightstateless.jsx @@ -0,0 +1,81 @@ +import React from 'react'; +import styles from './styles'; + +class SkyLightStateless extends React.Component { + + onOverlayClicked() { + if (this.props.onOverlayClicked) { + this.props.onOverlayClicked(); + } + } + + onCloseClicked() { + if (this.props.onCloseClicked) { + this.props.onCloseClicked(); + } + } + + render() { + const mergeStyles = key => Object.assign({}, styles[key], this.props[key]); + const dialogStyles = mergeStyles('dialogStyles'); + const overlayStyles = mergeStyles('overlayStyles'); + const closeButtonStyle = mergeStyles('closeButtonStyle'); + const titleStyle = mergeStyles('titleStyle'); + const displayStyle = this.props.isVisible ? 'block' : 'none'; + overlayStyles.display = dialogStyles.display = displayStyle; + + let overlay; + if (this.props.showOverlay) { + overlay = ( +
this.onOverlayClicked()} + style={overlayStyles} + /> + ); + } + + return ( +
+ {overlay} +
+ this.onCloseClicked()} + style={closeButtonStyle} + > + × + +

{this.props.title}

+ {this.props.children} +
+
+ ); + } +} + +SkyLightStateless.displayName = 'SkyLightStateless'; + +SkyLightStateless.sharedPropTypes = { + closeButtonStyle: React.PropTypes.object, + dialogStyles: React.PropTypes.object, + onCloseClicked: React.PropTypes.func, + onOverlayClicked: React.PropTypes.func, + overlayStyles: React.PropTypes.object, + showOverlay: React.PropTypes.bool, + title: React.PropTypes.string, + titleStyle: React.PropTypes.object, +}; + +SkyLightStateless.propTypes = { + ...SkyLightStateless.sharedPropTypes, + isVisible: React.PropTypes.bool, +}; + +SkyLightStateless.defaultProps = { + title: '', + showOverlay: true, + overlayStyles: styles.overlayStyles, + dialogStyles: styles.dialogStyles, + closeButtonStyle: styles.closeButtonStyle, +}; + +export default SkyLightStateless; diff --git a/src/styles.js b/src/styles.js index 74f70a2..a4e5346 100644 --- a/src/styles.js +++ b/src/styles.js @@ -1,4 +1,3 @@ - const styles = { overlayStyles: { position: 'fixed', @@ -7,7 +6,7 @@ const styles = { width: '100%', height: '100%', zIndex: 99, - backgroundColor: 'rgba(0,0,0,0.3)' + backgroundColor: 'rgba(0,0,0,0.3)', }, dialogStyles: { width: '50%', @@ -21,18 +20,18 @@ const styles = { borderRadius: '2px', zIndex: 100, padding: '15px', - boxShadow: '0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28)' + boxShadow: '0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28)', }, title: { - marginTop: '0' + marginTop: '0', }, closeButtonStyle: { cursor: 'pointer', position: 'absolute', fontSize: '1.8em', right: '10px', - top: '0' - } + top: '0', + }, }; export default styles; From 9c860ea4b5c9aabdfddaa29a3b0f669567d1a4bd Mon Sep 17 00:00:00 2001 From: darthtrevino Date: Mon, 18 Apr 2016 14:04:04 -0700 Subject: [PATCH 09/22] Eliminate string-based zero CSS properties to eliminate React 15 warning --- lib/styles.js | 4 ++-- src/styles.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/styles.js b/lib/styles.js index f92218c..5b1b581 100644 --- a/lib/styles.js +++ b/lib/styles.js @@ -28,14 +28,14 @@ var styles = { boxShadow: '0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28)' }, title: { - marginTop: '0' + marginTop: 0 }, closeButtonStyle: { cursor: 'pointer', position: 'absolute', fontSize: '1.8em', right: '10px', - top: '0' + top: 0 } }; diff --git a/src/styles.js b/src/styles.js index a4e5346..516b847 100644 --- a/src/styles.js +++ b/src/styles.js @@ -23,14 +23,14 @@ const styles = { boxShadow: '0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28)', }, title: { - marginTop: '0', + marginTop: 0, }, closeButtonStyle: { cursor: 'pointer', position: 'absolute', fontSize: '1.8em', right: '10px', - top: '0', + top: 0, }, }; From 823c157b521599ef58c0ff8a8a7e22cd02c95c39 Mon Sep 17 00:00:00 2001 From: darthtrevino Date: Mon, 18 Apr 2016 14:33:01 -0700 Subject: [PATCH 10/22] Add Basic Unit Tests --- karma.conf.js | 41 +++++++++++++++++++++++++++++++++ lib/skylightstateless.js | 15 ++++++------ package.json | 15 ++++++++++-- src/skylightstateless.jsx | 12 ++++------ test/skylight.spec.jsx | 22 ++++++++++++++++++ test/skylightstateless.spec.jsx | 21 +++++++++++++++++ 6 files changed, 110 insertions(+), 16 deletions(-) create mode 100644 karma.conf.js create mode 100644 test/skylight.spec.jsx create mode 100644 test/skylightstateless.spec.jsx diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 0000000..775732c --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,41 @@ +"use strict"; + +const isTddMode = process.argv.indexOf("--tdd") > -1; + +module.exports = config => { + config.set({ + basePath: '', + frameworks: ['mocha', 'chai'], + files: [ + { pattern: 'src/*.(jsx|js)', included: false }, + { pattern: 'src/*.js', included: false }, + 'test/**/*.spec.jsx' + ], + exclude: [], + preprocessors: { + 'test/**/*.spec.{js,jsx}': ['webpack', 'sourcemap'] + }, + webpack: { + resolve: { + extensions: ['', '.js', '.jsx'], + }, + module: { + loaders: [ + { + test: /\.(js|jsx)?$/, + loader: 'babel', + exclude: /node_modules/, + }, + ] + } + }, + reporters: ['progress'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: isTddMode, + browsers: isTddMode ? ['Chrome'] : [ 'PhantomJS' ], + singleRun: !isTddMode, + concurrency: Infinity + }); +}; diff --git a/lib/skylightstateless.js b/lib/skylightstateless.js index 550e3fa..9dadf98 100644 --- a/lib/skylightstateless.js +++ b/lib/skylightstateless.js @@ -55,12 +55,13 @@ var SkyLightStateless = function (_React$Component) { var mergeStyles = function mergeStyles(key) { return Object.assign({}, _styles2.default[key], _this2.props[key]); }; + var isVisible = this.props.isVisible; + var dialogStyles = mergeStyles('dialogStyles'); var overlayStyles = mergeStyles('overlayStyles'); var closeButtonStyle = mergeStyles('closeButtonStyle'); var titleStyle = mergeStyles('titleStyle'); - var displayStyle = this.props.isVisible ? 'block' : 'none'; - overlayStyles.display = dialogStyles.display = displayStyle; + overlayStyles.display = dialogStyles.display = 'block'; var overlay = undefined; if (this.props.showOverlay) { @@ -72,7 +73,7 @@ var SkyLightStateless = function (_React$Component) { }); } - return _react2.default.createElement( + return isVisible ? _react2.default.createElement( 'section', { className: 'skylight-wrapper' }, overlay, @@ -96,13 +97,15 @@ var SkyLightStateless = function (_React$Component) { ), this.props.children ) - ); + ) : _react2.default.createElement('div', null); } }]); return SkyLightStateless; }(_react2.default.Component); +exports.default = SkyLightStateless; + SkyLightStateless.displayName = 'SkyLightStateless'; SkyLightStateless.sharedPropTypes = { @@ -126,6 +129,4 @@ SkyLightStateless.defaultProps = { overlayStyles: _styles2.default.overlayStyles, dialogStyles: _styles2.default.dialogStyles, closeButtonStyle: _styles2.default.closeButtonStyle -}; - -exports.default = SkyLightStateless; \ No newline at end of file +}; \ No newline at end of file diff --git a/package.json b/package.json index 0623a16..e706035 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "build": "babel src -d lib", "watch": "babel src --watch -d lib", "lint": "eslint 'src/*.{js,jsx}'", + "develop": "karma start --tdd", "test": "npm run lint && npm run build" }, "repository": { @@ -38,12 +39,22 @@ "babel-preset-es2015": "^6.3.13", "babel-preset-react": "^6.5.0", "babel-preset-stage-0": "^6.3.13", + "chai": "^3.5.0", "eslint": "^2.7.0", "eslint-config-airbnb": "^6.2.0", "eslint-plugin-react": "^4.3.0", "jest-cli": "^0.10.0", - "react": "^0.14.5", - "webpack": "^1.12.14" + "karma": "^0.13.22", + "karma-chai": "^0.1.0", + "karma-chrome-launcher": "^0.2.3", + "karma-mocha": "^0.2.2", + "karma-phantomjs-launcher": "^1.0.0", + "karma-webpack": "^1.7.0", + "mocha": "^2.4.5", + "phantomjs-prebuilt": "^2.1.7", + "react": "^15.0.1", + "react-addons-test-utils": "^15.0.1", + "webpack": "^1.13.0" }, "babel": { "presets": [ diff --git a/src/skylightstateless.jsx b/src/skylightstateless.jsx index 6d9a117..43e871c 100644 --- a/src/skylightstateless.jsx +++ b/src/skylightstateless.jsx @@ -1,7 +1,7 @@ import React from 'react'; import styles from './styles'; -class SkyLightStateless extends React.Component { +export default class SkyLightStateless extends React.Component { onOverlayClicked() { if (this.props.onOverlayClicked) { @@ -17,12 +17,12 @@ class SkyLightStateless extends React.Component { render() { const mergeStyles = key => Object.assign({}, styles[key], this.props[key]); + const { isVisible } = this.props; const dialogStyles = mergeStyles('dialogStyles'); const overlayStyles = mergeStyles('overlayStyles'); const closeButtonStyle = mergeStyles('closeButtonStyle'); const titleStyle = mergeStyles('titleStyle'); - const displayStyle = this.props.isVisible ? 'block' : 'none'; - overlayStyles.display = dialogStyles.display = displayStyle; + overlayStyles.display = dialogStyles.display = 'block'; let overlay; if (this.props.showOverlay) { @@ -34,7 +34,7 @@ class SkyLightStateless extends React.Component { ); } - return ( + return isVisible ? (
{overlay}
@@ -48,7 +48,7 @@ class SkyLightStateless extends React.Component { {this.props.children}
- ); + ) :
; } } @@ -77,5 +77,3 @@ SkyLightStateless.defaultProps = { dialogStyles: styles.dialogStyles, closeButtonStyle: styles.closeButtonStyle, }; - -export default SkyLightStateless; diff --git a/test/skylight.spec.jsx b/test/skylight.spec.jsx new file mode 100644 index 0000000..cb99489 --- /dev/null +++ b/test/skylight.spec.jsx @@ -0,0 +1,22 @@ +import React from "react"; +import { expect } from "chai"; +import { + renderIntoDocument, + scryRenderedDOMComponentsWithClass +} from "react-addons-test-utils"; +import Skylight from "../src/skylight"; + +describe("The Skylight component", () => { + it("will not render initially", () => { + const rendered = renderIntoDocument(); + const found = scryRenderedDOMComponentsWithClass(rendered, "skylight-wrapper"); + expect(found.length).to.equal(0); + }); + + it("will render it is shown", () => { + const rendered = renderIntoDocument(); + rendered.show(); + const found = scryRenderedDOMComponentsWithClass(rendered, "skylight-wrapper"); + expect(found.length).to.equal(1); + }); +}); diff --git a/test/skylightstateless.spec.jsx b/test/skylightstateless.spec.jsx new file mode 100644 index 0000000..58cf470 --- /dev/null +++ b/test/skylightstateless.spec.jsx @@ -0,0 +1,21 @@ +import React from "react"; +import { expect } from "chai"; +import { + renderIntoDocument, + scryRenderedDOMComponentsWithClass +} from "react-addons-test-utils"; +import SkylightStateless from "../src/skylightstateless"; + +describe("The SkylightStateless component", () => { + it("will not render when it is not visible", () => { + const rendered = renderIntoDocument(); + const found = scryRenderedDOMComponentsWithClass(rendered, "skylight-wrapper"); + expect(found.length).to.equal(0); + }); + + it("will render when it is visible", () => { + const rendered = renderIntoDocument(); + const found = scryRenderedDOMComponentsWithClass(rendered, "skylight-wrapper"); + expect(found.length).to.equal(1); + }); +}); From 7787d66d0b61fb1a16db3ef05d3d1905bd4d9b8e Mon Sep 17 00:00:00 2001 From: darthtrevino Date: Mon, 18 Apr 2016 14:37:20 -0700 Subject: [PATCH 11/22] Add Object.assign Polyfill for PhantomJS-based Test Runs --- karma.conf.js | 1 + lib/skylight.js | 6 +++--- package.json | 3 ++- src/skylight.jsx | 4 +--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/karma.conf.js b/karma.conf.js index 775732c..1d392f6 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -7,6 +7,7 @@ module.exports = config => { basePath: '', frameworks: ['mocha', 'chai'], files: [ + './node_modules/phantomjs-polyfill-object-assign/object-assign-polyfill.js', { pattern: 'src/*.(jsx|js)', included: false }, { pattern: 'src/*.js', included: false }, 'test/**/*.spec.jsx' diff --git a/lib/skylight.js b/lib/skylight.js index 33af981..9be814c 100644 --- a/lib/skylight.js +++ b/lib/skylight.js @@ -106,6 +106,8 @@ var SkyLight = function (_React$Component) { return SkyLight; }(_react2.default.Component); +exports.default = SkyLight; + SkyLight.displayName = 'SkyLight'; SkyLight.propTypes = _extends({}, _skylightstateless2.default.sharedPropTypes, { @@ -118,6 +120,4 @@ SkyLight.propTypes = _extends({}, _skylightstateless2.default.sharedPropTypes, { SkyLight.defaultProps = _extends({}, _skylightstateless2.default.defaultProps, { hideOnOverlayClicked: false -}); - -exports.default = SkyLight; \ No newline at end of file +}); \ No newline at end of file diff --git a/package.json b/package.json index e706035..39f081f 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "watch": "babel src --watch -d lib", "lint": "eslint 'src/*.{js,jsx}'", "develop": "karma start --tdd", - "test": "npm run lint && npm run build" + "test": "npm run lint && karma start && npm run build" }, "repository": { "type": "git", @@ -51,6 +51,7 @@ "karma-phantomjs-launcher": "^1.0.0", "karma-webpack": "^1.7.0", "mocha": "^2.4.5", + "phantomjs-polyfill-object-assign": "0.0.2", "phantomjs-prebuilt": "^2.1.7", "react": "^15.0.1", "react-addons-test-utils": "^15.0.1", diff --git a/src/skylight.jsx b/src/skylight.jsx index 132fe28..7ee800a 100644 --- a/src/skylight.jsx +++ b/src/skylight.jsx @@ -4,7 +4,7 @@ import SkylightStateless from './skylightstateless'; const isOpening = (s1, s2) => !s1.isVisible && s2.isVisible; const isClosing = (s1, s2) => s1.isVisible && !s2.isVisible; -class SkyLight extends React.Component { +export default class SkyLight extends React.Component { constructor(props) { super(props); @@ -74,5 +74,3 @@ SkyLight.defaultProps = { ...SkylightStateless.defaultProps, hideOnOverlayClicked: false, }; - -export default SkyLight; From 4d2e889a9ee601369c8d4f96f0aaedab28108087 Mon Sep 17 00:00:00 2001 From: darthtrevino Date: Mon, 18 Apr 2016 14:39:45 -0700 Subject: [PATCH 12/22] Add npm-run-all to sequence npm scripts --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 39f081f..3599d7d 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "watch": "babel src --watch -d lib", "lint": "eslint 'src/*.{js,jsx}'", "develop": "karma start --tdd", - "test": "npm run lint && karma start && npm run build" + "karma": "karma start", + "test": "npm-run-all lint karma build" }, "repository": { "type": "git", @@ -51,6 +52,7 @@ "karma-phantomjs-launcher": "^1.0.0", "karma-webpack": "^1.7.0", "mocha": "^2.4.5", + "npm-run-all": "^1.7.0", "phantomjs-polyfill-object-assign": "0.0.2", "phantomjs-prebuilt": "^2.1.7", "react": "^15.0.1", From 187dba4cf805de6bcfb275ecec521d70510b2d60 Mon Sep 17 00:00:00 2001 From: darthtrevino Date: Mon, 18 Apr 2016 14:52:39 -0700 Subject: [PATCH 13/22] Add Test Coverage Reporter to Karma --- .gitignore | 6 ++++-- karma.conf.js | 22 ++++++++++++++-------- package.json | 3 +++ 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index f3e8af3..14b0bf2 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ # Thumbnails ._* - + # Files that might appear on external disk .Spotlight-V100 .Trashes @@ -21,4 +21,6 @@ # Node node_modules npm-debug.log -build \ No newline at end of file +build + +coverage/ diff --git a/karma.conf.js b/karma.conf.js index 1d392f6..1ea5523 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -1,5 +1,5 @@ "use strict"; - +const path = require("path"); const isTddMode = process.argv.indexOf("--tdd") > -1; module.exports = config => { @@ -8,29 +8,35 @@ module.exports = config => { frameworks: ['mocha', 'chai'], files: [ './node_modules/phantomjs-polyfill-object-assign/object-assign-polyfill.js', - { pattern: 'src/*.(jsx|js)', included: false }, - { pattern: 'src/*.js', included: false }, - 'test/**/*.spec.jsx' + { pattern: 'lib/**/*', included: false }, + 'test/**/*.spec.jsx', ], exclude: [], preprocessors: { - 'test/**/*.spec.{js,jsx}': ['webpack', 'sourcemap'] + 'test/**/*.spec.{js,jsx}': ['webpack', 'sourcemap'], }, webpack: { resolve: { extensions: ['', '.js', '.jsx'], }, module: { + postLoaders: [ + { + test: /\.(js|jsx)$/, + include: path.resolve('src/'), + loader: 'istanbul-instrumenter' + } + ], loaders: [ { test: /\.(js|jsx)?$/, loader: 'babel', exclude: /node_modules/, }, - ] - } + ], + }, }, - reporters: ['progress'], + reporters: ['progress', 'coverage'], port: 9876, colors: true, logLevel: config.LOG_INFO, diff --git a/package.json b/package.json index 3599d7d..1f6f84f 100644 --- a/package.json +++ b/package.json @@ -44,12 +44,15 @@ "eslint": "^2.7.0", "eslint-config-airbnb": "^6.2.0", "eslint-plugin-react": "^4.3.0", + "istanbul-instrumenter-loader": "^0.2.0", "jest-cli": "^0.10.0", "karma": "^0.13.22", "karma-chai": "^0.1.0", "karma-chrome-launcher": "^0.2.3", + "karma-coverage": "^0.5.5", "karma-mocha": "^0.2.2", "karma-phantomjs-launcher": "^1.0.0", + "karma-sourcemap-loader": "^0.3.7", "karma-webpack": "^1.7.0", "mocha": "^2.4.5", "npm-run-all": "^1.7.0", From ba0bdc46d7a62b8bdbb264ef74ac2ca2d6237fea Mon Sep 17 00:00:00 2001 From: darthtrevino Date: Mon, 18 Apr 2016 15:05:42 -0700 Subject: [PATCH 14/22] Move Linting into the Karma Run. Use isparta-loader instead of Istanbul for better Coverage Report --- .eslintrc | 11 +++++++++++ karma.conf.js | 17 +++++++++++------ package.json | 18 +++++++----------- test/skylight.spec.jsx | 20 ++++++++++---------- test/skylightstateless.spec.jsx | 20 ++++++++++---------- 5 files changed, 49 insertions(+), 37 deletions(-) create mode 100644 .eslintrc diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..031efb5 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,11 @@ +{ + "extends": "airbnb", + "parserOptions": { + "ecmaFeatures": { + "experimentalObjectRestSpread": true + } + }, + "env": { + "mocha": true + } +} diff --git a/karma.conf.js b/karma.conf.js index 1ea5523..0534540 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -20,12 +20,17 @@ module.exports = config => { extensions: ['', '.js', '.jsx'], }, module: { - postLoaders: [ - { - test: /\.(js|jsx)$/, - include: path.resolve('src/'), - loader: 'istanbul-instrumenter' - } + preLoaders: [ + { + test: /\.(js|jsx)$/, + include: path.resolve('src/'), + loader: 'isparta' + }, + { + test: /\.(js|jsx)?$/, + loader: 'eslint', + exclude: /node_modules/, + }, ], loaders: [ { diff --git a/package.json b/package.json index 1f6f84f..2d87692 100644 --- a/package.json +++ b/package.json @@ -6,10 +6,9 @@ "scripts": { "build": "babel src -d lib", "watch": "babel src --watch -d lib", - "lint": "eslint 'src/*.{js,jsx}'", "develop": "karma start --tdd", "karma": "karma start", - "test": "npm-run-all lint karma build" + "test": "npm-run-all karma build" }, "repository": { "type": "git", @@ -28,6 +27,10 @@ "dialog" ], "author": "Marcio Gasparotto", + "contributors": [{ + "name": "Chris Trevino", + "email": "darthtrevino@gmail.com" + }], "license": "MIT", "peerDependencies": { "react": "*" @@ -43,8 +46,9 @@ "chai": "^3.5.0", "eslint": "^2.7.0", "eslint-config-airbnb": "^6.2.0", + "eslint-loader": "^1.3.0", "eslint-plugin-react": "^4.3.0", - "istanbul-instrumenter-loader": "^0.2.0", + "isparta-loader": "^2.0.0", "jest-cli": "^0.10.0", "karma": "^0.13.22", "karma-chai": "^0.1.0", @@ -69,13 +73,5 @@ "stage-0" ], "plugins": [] - }, - "eslintConfig": { - "extends": "airbnb", - "parserOptions": { - "ecmaFeatures": { - "experimentalObjectRestSpread": true - } - } } } diff --git a/test/skylight.spec.jsx b/test/skylight.spec.jsx index cb99489..a6e296a 100644 --- a/test/skylight.spec.jsx +++ b/test/skylight.spec.jsx @@ -1,22 +1,22 @@ -import React from "react"; -import { expect } from "chai"; +import React from 'react'; +import { expect } from 'chai'; import { renderIntoDocument, - scryRenderedDOMComponentsWithClass -} from "react-addons-test-utils"; -import Skylight from "../src/skylight"; + scryRenderedDOMComponentsWithClass, +} from 'react-addons-test-utils'; +import Skylight from '../src/skylight'; -describe("The Skylight component", () => { - it("will not render initially", () => { +describe('The Skylight component', () => { + it('will not render initially', () => { const rendered = renderIntoDocument(); - const found = scryRenderedDOMComponentsWithClass(rendered, "skylight-wrapper"); + const found = scryRenderedDOMComponentsWithClass(rendered, 'skylight-wrapper'); expect(found.length).to.equal(0); }); - it("will render it is shown", () => { + it('will render it is shown', () => { const rendered = renderIntoDocument(); rendered.show(); - const found = scryRenderedDOMComponentsWithClass(rendered, "skylight-wrapper"); + const found = scryRenderedDOMComponentsWithClass(rendered, 'skylight-wrapper'); expect(found.length).to.equal(1); }); }); diff --git a/test/skylightstateless.spec.jsx b/test/skylightstateless.spec.jsx index 58cf470..5b6976a 100644 --- a/test/skylightstateless.spec.jsx +++ b/test/skylightstateless.spec.jsx @@ -1,21 +1,21 @@ -import React from "react"; -import { expect } from "chai"; +import React from 'react'; +import { expect } from 'chai'; import { renderIntoDocument, - scryRenderedDOMComponentsWithClass -} from "react-addons-test-utils"; -import SkylightStateless from "../src/skylightstateless"; + scryRenderedDOMComponentsWithClass, +} from 'react-addons-test-utils'; +import SkylightStateless from '../src/skylightstateless'; -describe("The SkylightStateless component", () => { - it("will not render when it is not visible", () => { +describe('The SkylightStateless component', () => { + it('will not render when it is not visible', () => { const rendered = renderIntoDocument(); - const found = scryRenderedDOMComponentsWithClass(rendered, "skylight-wrapper"); + const found = scryRenderedDOMComponentsWithClass(rendered, 'skylight-wrapper'); expect(found.length).to.equal(0); }); - it("will render when it is visible", () => { + it('will render when it is visible', () => { const rendered = renderIntoDocument(); - const found = scryRenderedDOMComponentsWithClass(rendered, "skylight-wrapper"); + const found = scryRenderedDOMComponentsWithClass(rendered, 'skylight-wrapper'); expect(found.length).to.equal(1); }); }); From ffa8ed22a60562aba123851f3917d7821a78e0f2 Mon Sep 17 00:00:00 2001 From: darthtrevino Date: Mon, 18 Apr 2016 15:32:02 -0700 Subject: [PATCH 15/22] =?UTF-8?q?Boost=20Test=20Coverage=20to=20?= =?UTF-8?q?=F0=9F=92=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/skylightstateless.js | 2 +- src/skylightstateless.jsx | 2 +- test/skylight.spec.jsx | 94 ++++++++++++++++++++++++++++++++- test/skylightstateless.spec.jsx | 44 +++++++++++++++ 4 files changed, 138 insertions(+), 4 deletions(-) diff --git a/lib/skylightstateless.js b/lib/skylightstateless.js index 9dadf98..b13ea43 100644 --- a/lib/skylightstateless.js +++ b/lib/skylightstateless.js @@ -82,7 +82,7 @@ var SkyLightStateless = function (_React$Component) { { className: 'skylight-dialog', style: dialogStyles }, _react2.default.createElement( 'a', - { role: 'button', + { role: 'button', className: 'skylight-close-button', onClick: function onClick() { return _this2.onCloseClicked(); }, diff --git a/src/skylightstateless.jsx b/src/skylightstateless.jsx index 43e871c..357e613 100644 --- a/src/skylightstateless.jsx +++ b/src/skylightstateless.jsx @@ -38,7 +38,7 @@ export default class SkyLightStateless extends React.Component {
{overlay}
- this.onCloseClicked()} style={closeButtonStyle} > diff --git a/test/skylight.spec.jsx b/test/skylight.spec.jsx index a6e296a..19357f3 100644 --- a/test/skylight.spec.jsx +++ b/test/skylight.spec.jsx @@ -1,8 +1,12 @@ +/* eslint-disable no-unused-expressions */ +/* eslint-disable no-return-assign */ import React from 'react'; import { expect } from 'chai'; import { renderIntoDocument, scryRenderedDOMComponentsWithClass, + findRenderedDOMComponentWithClass, + Simulate, } from 'react-addons-test-utils'; import Skylight from '../src/skylight'; @@ -13,10 +17,96 @@ describe('The Skylight component', () => { expect(found.length).to.equal(0); }); - it('will render it is shown', () => { - const rendered = renderIntoDocument(); + it('will render on show()', () => { + const rendered = renderIntoDocument(); rendered.show(); const found = scryRenderedDOMComponentsWithClass(rendered, 'skylight-wrapper'); expect(found.length).to.equal(1); }); + + it('will hide on hide()', () => { + const rendered = renderIntoDocument(); + rendered.show(); + rendered.hide(); + const found = scryRenderedDOMComponentsWithClass(rendered, 'skylight-wrapper'); + expect(found.length).to.equal(0); + }); + + it('will emit beforeOpen and afterOpen events when opening', () => { + let beforeTriggered = false; + let afterTriggered = false; + const onBefore = () => beforeTriggered = true; + const onAfter = () => { + expect(beforeTriggered).to.be.true; + afterTriggered = true; + }; + const rendered = renderIntoDocument( + + ); + expect(beforeTriggered).to.be.false; + expect(afterTriggered).to.be.false; + rendered.show(); + expect(beforeTriggered).to.be.true; + expect(afterTriggered).to.be.true; + }); + + it('will emit beforeClose and afterClose events when closing', () => { + let beforeTriggered = false; + let afterTriggered = false; + const onBefore = () => beforeTriggered = true; + const onAfter = () => { + expect(beforeTriggered).to.be.true; + afterTriggered = true; + }; + const rendered = renderIntoDocument( + + ); + rendered.show(); + expect(beforeTriggered).to.be.false; + expect(afterTriggered).to.be.false; + rendered.hide(); + expect(beforeTriggered).to.be.true; + expect(afterTriggered).to.be.true; + }); + + it('will emit an onOverlayClicked event', () => { + let clicked = false; + const rendered = renderIntoDocument( + clicked = true} /> + ); + rendered.show(); + const overlay = findRenderedDOMComponentWithClass(rendered, 'skylight-overlay'); + Simulate.click(overlay); + expect(clicked).to.be.true; + + // Still open + const found = scryRenderedDOMComponentsWithClass(rendered, 'skylight-wrapper'); + expect(found.length).to.equal(1); + }); + + it('will close when the overlay is clicked when hideOnOverlayClicked prop is true', () => { + const rendered = renderIntoDocument( + + ); + rendered.show(); + const overlay = findRenderedDOMComponentWithClass(rendered, 'skylight-overlay'); + Simulate.click(overlay); + + // Component closes + const found = scryRenderedDOMComponentsWithClass(rendered, 'skylight-wrapper'); + expect(found.length).to.equal(0); + }); + + it('will hide when the close button is clicked', () => { + const rendered = renderIntoDocument( + + ); + rendered.show(); + const closeButton = findRenderedDOMComponentWithClass(rendered, 'skylight-close-button'); + Simulate.click(closeButton); + + // Component closes + const found = scryRenderedDOMComponentsWithClass(rendered, 'skylight-wrapper'); + expect(found.length).to.equal(0); + }); }); diff --git a/test/skylightstateless.spec.jsx b/test/skylightstateless.spec.jsx index 5b6976a..7e1270d 100644 --- a/test/skylightstateless.spec.jsx +++ b/test/skylightstateless.spec.jsx @@ -1,8 +1,12 @@ +/* eslint-disable no-unused-expressions */ +/* eslint-disable no-return-assign */ import React from 'react'; import { expect } from 'chai'; import { renderIntoDocument, scryRenderedDOMComponentsWithClass, + findRenderedDOMComponentWithClass, + Simulate, } from 'react-addons-test-utils'; import SkylightStateless from '../src/skylightstateless'; @@ -18,4 +22,44 @@ describe('The SkylightStateless component', () => { const found = scryRenderedDOMComponentsWithClass(rendered, 'skylight-wrapper'); expect(found.length).to.equal(1); }); + + it('will not render the overlay when the showOverlay prop is false', () => { + const rendered = renderIntoDocument(); + const found = scryRenderedDOMComponentsWithClass(rendered, 'skylight-overlay'); + expect(found.length).to.equal(0); + }); + + it('will emit an event when the overlay is clicked', () => { + let clicked = false; + const rendered = renderIntoDocument( + clicked = true} /> + ); + const overlay = findRenderedDOMComponentWithClass(rendered, 'skylight-overlay'); + Simulate.click(overlay); + expect(clicked).to.be.true; + }); + + it('will emit an event when the close button is clicked', () => { + let clicked = false; + const rendered = renderIntoDocument( + clicked = true} /> + ); + const closeButton = findRenderedDOMComponentWithClass(rendered, 'skylight-close-button'); + Simulate.click(closeButton); + expect(clicked).to.be.true; + }); + + it('will not blow up when no onCloseClicked prop is set', () => { + const rendered = renderIntoDocument(); + const closeButton = findRenderedDOMComponentWithClass(rendered, 'skylight-close-button'); + Simulate.click(closeButton); + // no error thrown + }); + + it('will not blow up when no onOverlayClicked prop is set', () => { + const rendered = renderIntoDocument(); + const overlay = findRenderedDOMComponentWithClass(rendered, 'skylight-overlay'); + Simulate.click(overlay); + // no error thrown + }); }); From d9a3f0ad3f861bedd9299c9246c4feec1da15cd2 Mon Sep 17 00:00:00 2001 From: darthtrevino Date: Mon, 18 Apr 2016 16:18:51 -0700 Subject: [PATCH 16/22] Clean up tests using an Interactor class --- karma.conf.js | 1 - test/skylight.spec.jsx | 58 ++++++++++----------------------- test/skylightinteractor.js | 45 +++++++++++++++++++++++++ test/skylightstateless.spec.jsx | 44 ++++++++++--------------- 4 files changed, 80 insertions(+), 68 deletions(-) create mode 100644 test/skylightinteractor.js diff --git a/karma.conf.js b/karma.conf.js index 0534540..8969f9a 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -8,7 +8,6 @@ module.exports = config => { frameworks: ['mocha', 'chai'], files: [ './node_modules/phantomjs-polyfill-object-assign/object-assign-polyfill.js', - { pattern: 'lib/**/*', included: false }, 'test/**/*.spec.jsx', ], exclude: [], diff --git a/test/skylight.spec.jsx b/test/skylight.spec.jsx index 19357f3..c858d34 100644 --- a/test/skylight.spec.jsx +++ b/test/skylight.spec.jsx @@ -2,34 +2,26 @@ /* eslint-disable no-return-assign */ import React from 'react'; import { expect } from 'chai'; -import { - renderIntoDocument, - scryRenderedDOMComponentsWithClass, - findRenderedDOMComponentWithClass, - Simulate, -} from 'react-addons-test-utils'; import Skylight from '../src/skylight'; +import SkylightInteractor from './SkylightInteractor'; describe('The Skylight component', () => { it('will not render initially', () => { - const rendered = renderIntoDocument(); - const found = scryRenderedDOMComponentsWithClass(rendered, 'skylight-wrapper'); - expect(found.length).to.equal(0); + const rendered = new SkylightInteractor(); + expect(rendered.isOpen()).to.be.false; }); it('will render on show()', () => { - const rendered = renderIntoDocument(); + const rendered = new SkylightInteractor(); rendered.show(); - const found = scryRenderedDOMComponentsWithClass(rendered, 'skylight-wrapper'); - expect(found.length).to.equal(1); + expect(rendered.isOpen()).to.be.true; }); it('will hide on hide()', () => { - const rendered = renderIntoDocument(); + const rendered = new SkylightInteractor(); rendered.show(); rendered.hide(); - const found = scryRenderedDOMComponentsWithClass(rendered, 'skylight-wrapper'); - expect(found.length).to.equal(0); + expect(rendered.isOpen()).to.be.false; }); it('will emit beforeOpen and afterOpen events when opening', () => { @@ -40,7 +32,7 @@ describe('The Skylight component', () => { expect(beforeTriggered).to.be.true; afterTriggered = true; }; - const rendered = renderIntoDocument( + const rendered = new SkylightInteractor( ); expect(beforeTriggered).to.be.false; @@ -58,7 +50,7 @@ describe('The Skylight component', () => { expect(beforeTriggered).to.be.true; afterTriggered = true; }; - const rendered = renderIntoDocument( + const rendered = new SkylightInteractor( ); rendered.show(); @@ -71,42 +63,28 @@ describe('The Skylight component', () => { it('will emit an onOverlayClicked event', () => { let clicked = false; - const rendered = renderIntoDocument( + const rendered = new SkylightInteractor( clicked = true} /> ); rendered.show(); - const overlay = findRenderedDOMComponentWithClass(rendered, 'skylight-overlay'); - Simulate.click(overlay); + rendered.clickOnOverlay(); expect(clicked).to.be.true; - - // Still open - const found = scryRenderedDOMComponentsWithClass(rendered, 'skylight-wrapper'); - expect(found.length).to.equal(1); + expect(rendered.isOpen()).to.be.true; }); it('will close when the overlay is clicked when hideOnOverlayClicked prop is true', () => { - const rendered = renderIntoDocument( + const rendered = new SkylightInteractor( ); rendered.show(); - const overlay = findRenderedDOMComponentWithClass(rendered, 'skylight-overlay'); - Simulate.click(overlay); - - // Component closes - const found = scryRenderedDOMComponentsWithClass(rendered, 'skylight-wrapper'); - expect(found.length).to.equal(0); + rendered.clickOnOverlay(); + expect(rendered.isOpen()).to.be.false; }); it('will hide when the close button is clicked', () => { - const rendered = renderIntoDocument( - - ); + const rendered = new SkylightInteractor(); rendered.show(); - const closeButton = findRenderedDOMComponentWithClass(rendered, 'skylight-close-button'); - Simulate.click(closeButton); - - // Component closes - const found = scryRenderedDOMComponentsWithClass(rendered, 'skylight-wrapper'); - expect(found.length).to.equal(0); + rendered.clickOnClose(); + expect(rendered.isOpen()).to.be.false; }); }); diff --git a/test/skylightinteractor.js b/test/skylightinteractor.js new file mode 100644 index 0000000..93dc102 --- /dev/null +++ b/test/skylightinteractor.js @@ -0,0 +1,45 @@ +/* eslint-disable no-unused-expressions */ +/* eslint-disable no-return-assign */ +import { + renderIntoDocument, + scryRenderedDOMComponentsWithClass, + findRenderedDOMComponentWithClass, + Simulate, +} from 'react-addons-test-utils'; + +/** + * A test wrapper for skylight components that performs DOM interaction. + */ +export default class SkylightInteractor { + constructor(jsx) { + this._component = renderIntoDocument(jsx); + } + + show() { + this._component.show(); + } + + hide() { + this._component.hide(); + } + + isOverlayVisible() { + const found = scryRenderedDOMComponentsWithClass(this._component, 'skylight-overlay'); + return found.length === 1; + } + + clickOnOverlay() { + const overlay = findRenderedDOMComponentWithClass(this._component, 'skylight-overlay'); + Simulate.click(overlay); + } + + clickOnClose() { + const closeButton = findRenderedDOMComponentWithClass(this._component, 'skylight-close-button'); + Simulate.click(closeButton); + } + + isOpen() { + const found = scryRenderedDOMComponentsWithClass(this._component, 'skylight-overlay'); + return found.length === 1; + } +} diff --git a/test/skylightstateless.spec.jsx b/test/skylightstateless.spec.jsx index 7e1270d..f526ace 100644 --- a/test/skylightstateless.spec.jsx +++ b/test/skylightstateless.spec.jsx @@ -2,64 +2,54 @@ /* eslint-disable no-return-assign */ import React from 'react'; import { expect } from 'chai'; -import { - renderIntoDocument, - scryRenderedDOMComponentsWithClass, - findRenderedDOMComponentWithClass, - Simulate, -} from 'react-addons-test-utils'; import SkylightStateless from '../src/skylightstateless'; +import SkylightInteractor from './SkylightInteractor'; describe('The SkylightStateless component', () => { it('will not render when it is not visible', () => { - const rendered = renderIntoDocument(); - const found = scryRenderedDOMComponentsWithClass(rendered, 'skylight-wrapper'); - expect(found.length).to.equal(0); + const rendered = new SkylightInteractor(); + expect(rendered.isOpen()).to.be.false; }); it('will render when it is visible', () => { - const rendered = renderIntoDocument(); - const found = scryRenderedDOMComponentsWithClass(rendered, 'skylight-wrapper'); - expect(found.length).to.equal(1); + const rendered = new SkylightInteractor(); + expect(rendered.isOpen()).to.be.true; }); it('will not render the overlay when the showOverlay prop is false', () => { - const rendered = renderIntoDocument(); - const found = scryRenderedDOMComponentsWithClass(rendered, 'skylight-overlay'); - expect(found.length).to.equal(0); + const rendered = new SkylightInteractor( + + ); + expect(rendered.isOverlayVisible()).to.be.false; }); it('will emit an event when the overlay is clicked', () => { let clicked = false; - const rendered = renderIntoDocument( + const rendered = new SkylightInteractor( clicked = true} /> ); - const overlay = findRenderedDOMComponentWithClass(rendered, 'skylight-overlay'); - Simulate.click(overlay); + rendered.clickOnOverlay(); expect(clicked).to.be.true; }); it('will emit an event when the close button is clicked', () => { let clicked = false; - const rendered = renderIntoDocument( + const rendered = new SkylightInteractor( clicked = true} /> ); - const closeButton = findRenderedDOMComponentWithClass(rendered, 'skylight-close-button'); - Simulate.click(closeButton); + rendered.clickOnClose(); expect(clicked).to.be.true; }); it('will not blow up when no onCloseClicked prop is set', () => { - const rendered = renderIntoDocument(); - const closeButton = findRenderedDOMComponentWithClass(rendered, 'skylight-close-button'); - Simulate.click(closeButton); + const rendered = new SkylightInteractor(); + rendered.clickOnClose(); // no error thrown }); it('will not blow up when no onOverlayClicked prop is set', () => { - const rendered = renderIntoDocument(); - const overlay = findRenderedDOMComponentWithClass(rendered, 'skylight-overlay'); - Simulate.click(overlay); + const rendered = new SkylightInteractor(); + rendered.clickOnOverlay(); // no error thrown }); }); From 56ff21c0ea8f92a3c11c9c7810b7a6c5045ea19e Mon Sep 17 00:00:00 2001 From: darthtrevino Date: Tue, 19 Apr 2016 12:35:51 -0700 Subject: [PATCH 17/22] Remove File that was Renamed --- lib/skylight-stateless.js | 117 -------------------------------------- 1 file changed, 117 deletions(-) delete mode 100644 lib/skylight-stateless.js diff --git a/lib/skylight-stateless.js b/lib/skylight-stateless.js deleted file mode 100644 index ff41ab1..0000000 --- a/lib/skylight-stateless.js +++ /dev/null @@ -1,117 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _react = require('react'); - -var _react2 = _interopRequireDefault(_react); - -var _styles = require('./styles'); - -var _styles2 = _interopRequireDefault(_styles); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - -var SkylightStateless = function (_React$Component) { - _inherits(SkylightStateless, _React$Component); - - function SkylightStateless() { - _classCallCheck(this, SkylightStateless); - - return _possibleConstructorReturn(this, Object.getPrototypeOf(SkylightStateless).apply(this, arguments)); - } - - _createClass(SkylightStateless, [{ - key: 'onOverlayClicked', - value: function onOverlayClicked() { - if (this.props.onOverlayClicked) { - this.props.onOverlayClicked(); - } - } - }, { - key: 'onCloseClicked', - value: function onCloseClicked() { - if (this.props.onCloseClicked) { - this.props.onCloseClicked(); - } - } - }, { - key: 'render', - value: function render() { - var dialogStyles = Object.assign({}, _styles2.default.dialogStyles, this.props.dialogStyles); - var overlayStyles = Object.assign({}, _styles2.default.overlayStyles, this.props.overlayStyles); - var closeButtonStyle = Object.assign({}, _styles2.default.closeButtonStyle, this.props.closeButtonStyle); - var titleStyle = Object.assign({}, _styles2.default.title, this.props.titleStyle); - - var displayStyle = this.props.isVisible ? 'block' : 'none'; - overlayStyles.display = dialogStyles.display = displayStyle; - - var overlay = undefined; - if (this.props.showOverlay) { - overlay = _react2.default.createElement('div', { className: 'skylight-overlay', onClick: this.onOverlayClicked.bind(this), style: overlayStyles }); - } - - return _react2.default.createElement( - 'section', - { className: 'skylight-wrapper' }, - overlay, - _react2.default.createElement( - 'div', - { className: 'skylight-dialog', style: dialogStyles }, - _react2.default.createElement( - 'a', - { onClick: this.onCloseClicked.bind(this), role: 'button', style: closeButtonStyle }, - '×' - ), - _react2.default.createElement( - 'h2', - { style: titleStyle }, - this.props.title - ), - this.props.children - ) - ); - } - }]); - - return SkylightStateless; -}(_react2.default.Component); - -SkylightStateless.displayName = 'SkyLightStateless'; - -SkylightStateless.sharedPropTypes = { - closeButtonStyle: _react2.default.PropTypes.object, - dialogStyles: _react2.default.PropTypes.object, - onCloseClicked: _react2.default.PropTypes.func, - onOverlayClicked: _react2.default.PropTypes.func, - overlayStyles: _react2.default.PropTypes.object, - showOverlay: _react2.default.PropTypes.bool, - title: _react2.default.PropTypes.string, - titleStyle: _react2.default.PropTypes.object -}; - -SkylightStateless.propTypes = _extends({}, SkyLightStateless.sharedPropTypes, { - isVisible: _react2.default.PropTypes.bool -}); - -SkylightStateless.defaultProps = { - title: '', - showOverlay: true, - overlayStyles: _styles2.default.overlayStyles, - dialogStyles: _styles2.default.dialogStyles, - closeButtonStyle: _styles2.default.closeButtonStyle -}; - -exports.default = SkyLight; \ No newline at end of file From 50f7fdecd1209ec57152101a931640ef00f2bab9 Mon Sep 17 00:00:00 2001 From: Marcio Gasparotto Date: Wed, 27 Apr 2016 21:22:13 -0300 Subject: [PATCH 18/22] fix #35 --- lib/skylight.js | 4 ++-- lib/styles.js | 14 +++++++------- package.json | 4 ++-- src/styles.js | 14 +++++++------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/lib/skylight.js b/lib/skylight.js index c5c52f8..db595a4 100644 --- a/lib/skylight.js +++ b/lib/skylight.js @@ -1,11 +1,11 @@ 'use strict'; -var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); - Object.defineProperty(exports, "__esModule", { value: true }); +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + var _react = require('react'); var _react2 = _interopRequireDefault(_react); diff --git a/lib/styles.js b/lib/styles.js index e8327bc..54d4f4e 100644 --- a/lib/styles.js +++ b/lib/styles.js @@ -7,11 +7,11 @@ Object.defineProperty(exports, "__esModule", { var styles = { overlayStyles: { position: 'fixed', - top: 0, - left: 0, + top: '0px', + left: '0px', width: '100%', height: '100%', - zIndex: 99, + zIndex: '99', backgroundColor: 'rgba(0,0,0,0.3)' }, dialogStyles: { @@ -24,19 +24,19 @@ var styles = { marginLeft: '-25%', backgroundColor: '#fff', borderRadius: '2px', - zIndex: 100, + zIndex: '100', padding: '15px', - boxShadow: '0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28)' + boxShadow: '0px 0px 4px rgba(0,0,0,.14),0px 4px 8px rgba(0,0,0,.28)' }, title: { - marginTop: '0' + marginTop: '0px' }, closeButtonStyle: { cursor: 'pointer', position: 'absolute', fontSize: '1.8em', right: '10px', - top: '0' + top: '0px' } }; diff --git a/package.json b/package.json index 62ec6fa..ef03a21 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "author": "Marcio Gasparotto", "license": "MIT", "peerDependencies": { - "react": "*" + "react": "^0.14.0 || ^15.0.0" }, "dependencies": { }, @@ -41,6 +41,6 @@ "eslint": "^1.10.3", "eslint-plugin-react": "^3.14.0", "jest-cli": "^0.2.1", - "react": "^0.14.5" + "react": "^0.14.0 || ^15.0.0" } } diff --git a/src/styles.js b/src/styles.js index 74f70a2..e9997b2 100644 --- a/src/styles.js +++ b/src/styles.js @@ -2,11 +2,11 @@ const styles = { overlayStyles: { position: 'fixed', - top: 0, - left: 0, + top: '0px', + left: '0px', width: '100%', height: '100%', - zIndex: 99, + zIndex: '99', backgroundColor: 'rgba(0,0,0,0.3)' }, dialogStyles: { @@ -19,19 +19,19 @@ const styles = { marginLeft: '-25%', backgroundColor: '#fff', borderRadius: '2px', - zIndex: 100, + zIndex: '100', padding: '15px', - boxShadow: '0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28)' + boxShadow: '0px 0px 4px rgba(0,0,0,.14),0px 4px 8px rgba(0,0,0,.28)' }, title: { - marginTop: '0' + marginTop: '0px' }, closeButtonStyle: { cursor: 'pointer', position: 'absolute', fontSize: '1.8em', right: '10px', - top: '0' + top: '0px' } }; From a00003375e06ce2cfa1856ba9fe9ca519ef83711 Mon Sep 17 00:00:00 2001 From: Marcio Gasparotto Date: Wed, 27 Apr 2016 22:20:09 -0300 Subject: [PATCH 19/22] fixes after merge --- karma.conf.js | 15 +++++++-------- lib/skylight.js | 6 +++--- lib/skylightstateless.js | 6 +++--- package.json | 19 ++++++++++--------- src/styles.js | 10 +++++----- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/karma.conf.js b/karma.conf.js index 8969f9a..f682e0c 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -1,6 +1,5 @@ -"use strict"; -const path = require("path"); -const isTddMode = process.argv.indexOf("--tdd") > -1; +const path = require('path'); +const isTddMode = process.argv.indexOf('--tdd') > -1; module.exports = config => { config.set({ @@ -21,9 +20,9 @@ module.exports = config => { module: { preLoaders: [ { - test: /\.(js|jsx)$/, - include: path.resolve('src/'), - loader: 'isparta' + test: /\.(js|jsx)$/, + include: path.resolve('src/'), + loader: 'isparta', }, { test: /\.(js|jsx)?$/, @@ -45,8 +44,8 @@ module.exports = config => { colors: true, logLevel: config.LOG_INFO, autoWatch: isTddMode, - browsers: isTddMode ? ['Chrome'] : [ 'PhantomJS' ], + browsers: isTddMode ? ['Chrome'] : [ 'PhantomJS'], singleRun: !isTddMode, - concurrency: Infinity + concurrency: Infinity, }); }; diff --git a/lib/skylight.js b/lib/skylight.js index 9be814c..81c2878 100644 --- a/lib/skylight.js +++ b/lib/skylight.js @@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); var _react = require('react'); @@ -31,7 +31,7 @@ var isClosing = function isClosing(s1, s2) { return s1.isVisible && !s2.isVisible; }; -var SkyLight = function (_React$Component) { +var SkyLight = (function (_React$Component) { _inherits(SkyLight, _React$Component); function SkyLight(props) { @@ -104,7 +104,7 @@ var SkyLight = function (_React$Component) { }]); return SkyLight; -}(_react2.default.Component); +})(_react2.default.Component); exports.default = SkyLight; diff --git a/lib/skylightstateless.js b/lib/skylightstateless.js index b13ea43..7bfc4e8 100644 --- a/lib/skylightstateless.js +++ b/lib/skylightstateless.js @@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); var _react = require('react'); @@ -24,7 +24,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var SkyLightStateless = function (_React$Component) { +var SkyLightStateless = (function (_React$Component) { _inherits(SkyLightStateless, _React$Component); function SkyLightStateless() { @@ -102,7 +102,7 @@ var SkyLightStateless = function (_React$Component) { }]); return SkyLightStateless; -}(_react2.default.Component); +})(_react2.default.Component); exports.default = SkyLightStateless; diff --git a/package.json b/package.json index 600da78..e715165 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-skylight", - "version": "0.3.0", + "version": "0.4.0", "description": "A react component for modals and dialogs.", "main": "lib/index.js", "scripts": { @@ -27,15 +27,16 @@ "dialog" ], "author": "Marcio Gasparotto", - "contributors": [{ - "name": "Chris Trevino", - "email": "darthtrevino@gmail.com" - }], + "contributors": [ + { + "name": "Chris Trevino", + "email": "darthtrevino@gmail.com" + } + ], "license": "MIT", "peerDependencies": { - "react": "^0.14.0 || ^15.0.0" + "react": "^0.14.0 || ^15.0.1" }, - "dependencies": {}, "devDependencies": { "babel-core": "^6.3.26", "babel-eslint": "^6.0.2", @@ -62,8 +63,8 @@ "npm-run-all": "^1.7.0", "phantomjs-polyfill-object-assign": "0.0.2", "phantomjs-prebuilt": "^2.1.7", - "react": "^0.14.0 || ^15.0.0", - "react-addons-test-utils": "^0.14.0 || ^15.0.0", + "react": "^15.0.1", + "react-addons-test-utils": "^15.0.1 || ^0.14.0", "webpack": "^1.13.0" }, "babel": { diff --git a/src/styles.js b/src/styles.js index e9997b2..beb6440 100644 --- a/src/styles.js +++ b/src/styles.js @@ -7,7 +7,7 @@ const styles = { width: '100%', height: '100%', zIndex: '99', - backgroundColor: 'rgba(0,0,0,0.3)' + backgroundColor: 'rgba(0,0,0,0.3)', }, dialogStyles: { width: '50%', @@ -21,18 +21,18 @@ const styles = { borderRadius: '2px', zIndex: '100', padding: '15px', - boxShadow: '0px 0px 4px rgba(0,0,0,.14),0px 4px 8px rgba(0,0,0,.28)' + boxShadow: '0px 0px 4px rgba(0,0,0,.14),0px 4px 8px rgba(0,0,0,.28)', }, title: { - marginTop: '0px' + marginTop: '0px', }, closeButtonStyle: { cursor: 'pointer', position: 'absolute', fontSize: '1.8em', right: '10px', - top: '0px' - } + top: '0px', + }, }; export default styles; From faf4e86d571396b2643f81b16b12fc79f074c188 Mon Sep 17 00:00:00 2001 From: Khang Hoang Date: Fri, 24 Jun 2016 15:48:14 +0700 Subject: [PATCH 20/22] add poly assign and its tests --- karma.conf.js | 1 + src/utils/assign.js | 18 ++++++++++++++++++ test/assign.spec.js | 29 +++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 src/utils/assign.js create mode 100644 test/assign.spec.js diff --git a/karma.conf.js b/karma.conf.js index f682e0c..0b711a7 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -8,6 +8,7 @@ module.exports = config => { files: [ './node_modules/phantomjs-polyfill-object-assign/object-assign-polyfill.js', 'test/**/*.spec.jsx', + 'test/assign.spec.js', ], exclude: [], preprocessors: { diff --git a/src/utils/assign.js b/src/utils/assign.js new file mode 100644 index 0000000..3d9fbc6 --- /dev/null +++ b/src/utils/assign.js @@ -0,0 +1,18 @@ +export default function (target, ...args) { + if (target === null) { + throw new TypeError('Cannot convert undefined or null to object'); + } + + const newTarget = target; + for (let index = 0; index < args.length; index++) { + const source = args[index]; + if (source !== null) { + for (const key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + newTarget[key] = source[key]; + } + } + } + } + return newTarget; +} diff --git a/test/assign.spec.js b/test/assign.spec.js new file mode 100644 index 0000000..98be966 --- /dev/null +++ b/test/assign.spec.js @@ -0,0 +1,29 @@ +import assign from '../src/utils/assign'; +import { expect } from 'chai'; + +describe('Assign function', () => { + it('should throw error when target is null', () => { + expect(assign.bind(null, null, {})).to.throw(TypeError); + }); + + it('should accept null source', () => { + expect(assign({}, null)).to.deep.equal({}); + }); + + it('should merge ', () => { + const first = { a: 1 }; + const second = { + b: { + c: 2, + }, + }; + const expected = { + a: 1, + b: { + c: 2, + }, + }; + + expect(assign({}, first, second)).to.deep.equal(expected); + }); +}); From 11c3df0f04860eee728c3927e00d4649606d4479 Mon Sep 17 00:00:00 2001 From: Khang Hoang Date: Fri, 24 Jun 2016 15:48:51 +0700 Subject: [PATCH 21/22] use assign instead of object assign --- src/skylightstateless.jsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/skylightstateless.jsx b/src/skylightstateless.jsx index 357e613..7c3a224 100644 --- a/src/skylightstateless.jsx +++ b/src/skylightstateless.jsx @@ -1,5 +1,6 @@ import React from 'react'; import styles from './styles'; +import assign from './utils/assign'; export default class SkyLightStateless extends React.Component { @@ -16,7 +17,7 @@ export default class SkyLightStateless extends React.Component { } render() { - const mergeStyles = key => Object.assign({}, styles[key], this.props[key]); + const mergeStyles = key => assign({}, styles[key], this.props[key]); const { isVisible } = this.props; const dialogStyles = mergeStyles('dialogStyles'); const overlayStyles = mergeStyles('overlayStyles'); From 215c9ed52b73fcc53ed240e400074c5c3cf4dfd7 Mon Sep 17 00:00:00 2001 From: Marcio Gasparotto Date: Wed, 31 Aug 2016 22:17:45 -0300 Subject: [PATCH 22/22] Polyfill Object.Assign --- README.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a349ee7..4fa1015 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ How to use ## Release History + * 2016-08-31   v0.4.1   Polyfill Object.assign() to works in IE * 2016-04-27 v0.4.0 Fix issue #35 (numeric string value for CSS property), up to react 15.0.1 and merged pull request to support Stateless (thanks @darthtrevino) * 2016-01-09   v0.3.0   Rewrite to ES2015, overlay callback and new site. * 2015-04-08   v0.2.0   Improvements diff --git a/package.json b/package.json index e715165..5ebdbf3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-skylight", - "version": "0.4.0", + "version": "0.4.1", "description": "A react component for modals and dialogs.", "main": "lib/index.js", "scripts": {