diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..1297a0e --- /dev/null +++ b/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["es2015", "react", "stage-0"], + "plugins": ["add-module-exports"] +} diff --git a/.gitignore b/.gitignore index 947dcde..090ac6f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ .idea/ node_modules/ +build/ dist/ + *.log *.map .DS_Store diff --git a/.npmignore b/.npmignore index c9c2908..620c0a8 100644 --- a/.npmignore +++ b/.npmignore @@ -6,7 +6,6 @@ dist/ .DS_Store static/ -src/example/ -src/example.* +src/ tmp/ webpack.*.js diff --git a/LICENSE.md b/LICENSE similarity index 100% rename from LICENSE.md rename to LICENSE diff --git a/README.md b/README.md index 0a57737..6bac638 100644 --- a/README.md +++ b/README.md @@ -53,19 +53,19 @@ You get namespaced CSS that works on sub-components (comparable to HTML5 ` @@ -79,7 +79,7 @@ For a cascaded effect, see the `index.html` demo. ## Usage -Run `npm run watch` in your terminal and play with `example/` to get a feel of react-inline-css. +Run `npm run devserver` in your terminal and play with `example/` to get a feel of react-inline-css. ### SASS / LESS @@ -127,11 +127,12 @@ UserComponent { ## Community Let's start one together! After you ★Star this project, follow me [@Rygu](https://twitter.com/rygu) -on Twitter. +on Twitter. ### Contributors - [Danilo Moret](https://github.com/moret) +- [Luigi Poole](https://github.com/luigiplr) ## License diff --git a/package.json b/package.json index 7af7f07..1386291 100644 --- a/package.json +++ b/package.json @@ -15,24 +15,31 @@ "react-component", "style" ], - "main": "src/react-inline-css", + "main": "build/react-inline-css.js", "scripts": { - "localhost": "sleep 2; which open && open http://localhost:8080", - "build": "webpack --verbose --colors --display-error-details --config webpack.client.js", - "watch-client": "webpack --verbose --colors --display-error-details --config webpack.client-watch.js && webpack-dev-server --config webpack.client-watch.js", - "watch": "concurrent 'npm run watch-client' 'npm run localhost'" + "babel": "mkdirp build && babel src/react-inline-css.js -o build/react-inline-css.js", + "build": "webpack -p --verbose --colors --display-error-details && npm run babel", + "devserver": "webpack-dev-server --config webpack.config.devServer.babel.js", + "prepublish": "npm run babel" + }, + "dependencies": { + "react": "^15.2.1", + "react-dom": "^15.2.1" }, "devDependencies": { - "babel-core": "6.7.6", + "babel-cli": "^6.10.1", + "babel-core": "^6.10.4", "babel-loader": "6.2.4", - "babel-preset-es2015": "6.6.0", - "babel-preset-react": "6.5.0", - "concurrently": "2.0.0", + "babel-plugin-add-module-exports": "^0.2.1", + "babel-preset-es2015": "^6.9.0", + "babel-preset-react": "^6.11.1", + "babel-preset-stage-0": "^6.5.0", + "html-webpack-plugin": "^2.22.0", + "html-webpack-template": "^5.0.0", "json-loader": "0.5.4", - "react": "15.0.1", - "react-dom": "15.0.1", - "react-hot-loader": "1.3.0", - "webpack": "1.13.0", + "mkdirp": "^0.5.1", + "open-browser-webpack-plugin": "0.0.2", + "webpack": "^1.13.1", "webpack-dev-server": "1.14.1" } } diff --git a/src/react-inline-css.js b/src/react-inline-css.js index 570fbc4..68b5589 100644 --- a/src/react-inline-css.js +++ b/src/react-inline-css.js @@ -1,58 +1,50 @@ /** * @copyright © 2015, Rick Wong. All rights reserved. */ -var React = require("react"); -var assign = Object.assign ? Object.assign : React.__spread; -var refCounter = 0; +import React, { PropTypes, Component } from 'react' /** * @module InlineCss */ -var InlineCss = React.createClass({ - displayName: "InlineCss", - propTypes: { - namespace: React.PropTypes.string, - componentName: React.PropTypes.string, - stylesheet: React.PropTypes.string.isRequired, - className: React.PropTypes.string, - wrapper: React.PropTypes.string - }, - _transformSheet: function (stylesheet, componentName, namespace) { - return stylesheet. - // Prettier output. - replace(/}\s*/ig, '\n}\n'). - // Regular rules are namespaced. - replace( - /(^|{|}|;|,)\s*([&a-z0-9\-_\.:#\(\),>*\s]+)\s*(\{)/ig, - function (matched) { - return matched.replace(new RegExp(componentName, "g"), "#" + namespace); - } - ); - }, - render: function () { - var namespace = this.props.namespace || "InlineCss-" + refCounter++; - var componentName = this.props.componentName || "&"; - var stylesheet = this._transformSheet(this.props.stylesheet, componentName, namespace); - var Wrapper = this.props.wrapper || "div"; - var wrapperProps = assign({}, this.props, { - namespace: undefined, - componentName: undefined, - stylesheet: undefined, - wrapper: undefined, - id: namespace - }); +export default class InlineCss extends Component { + static propTypes = { + namespace: PropTypes.string, + componentName: PropTypes.string, + stylesheet: PropTypes.string.isRequired, + wrapper: PropTypes.string, + children: PropTypes.any + } - return React.createElement( - Wrapper, - wrapperProps, - this.props.children, - React.createElement("style", { - scoped: true, - dangerouslySetInnerHTML: {__html: stylesheet} - }) - ); - } -}); + static defaultProps = { + namespace: 'inlineCss', + componentName: '&', + wrapper: 'div' + } -module.exports = InlineCss; + _transformSheet(stylesheet, componentName, namespace) { + if (this._cachedSheet && this._cachedSheet.formatted && this._cachedSheet.stylesheet === stylesheet) { + return this._cachedSheet.formatted + } + + const formatted = stylesheet.replace(/([^\r\n,{}]+)(,(?=[^}]*{)|\s*{)/ig, matched => matched.replace(new RegExp(componentName, 'g'), '#' + namespace)) + this._cachedSheet = { stylesheet, formatted } + return formatted + } + + render() { + const { namespace, componentName, stylesheet, wrapper, ...wrapperProps } = this.props + const id = namespace !== 'inlineCss' ? namespace : `${namespace}-${(Math.random().toString(36) + '00000000000000000').slice(2, 7 + 2)}` + + return React.createElement( + wrapper, { id, ...wrapperProps }, + this.props.children, + React.createElement('style', { + scoped: true, + dangerouslySetInnerHTML: { + __html: ::this._transformSheet(stylesheet, componentName, id) + } + }) + ) + } +} diff --git a/static/index.html b/static/index.html deleted file mode 100644 index e80f94b..0000000 --- a/static/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - -
- -