├── example ├── 1 │ ├── README.md │ ├── index.html │ ├── package.json │ ├── webpack.config.js │ ├── .gitignore │ └── src │ │ └── app.jsx └── 2 │ ├── README.md │ ├── result.png │ ├── result-head.png │ ├── index.html │ ├── package.json │ ├── webpack.config.js │ ├── .gitignore │ └── src │ └── app.jsx ├── webpack.config.js ├── .gitignore ├── LICENSE ├── package.json ├── src └── CSSX.jsx ├── README.md └── lib ├── CSSX.js.map └── CSSX.js /example/1/README.md: -------------------------------------------------------------------------------- 1 | ``` 2 | npm install 3 | npm run dev 4 | ``` -------------------------------------------------------------------------------- /example/2/README.md: -------------------------------------------------------------------------------- 1 | ``` 2 | npm install 3 | npm run dev 4 | ``` -------------------------------------------------------------------------------- /example/2/result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasimir/react-cssx/HEAD/example/2/result.png -------------------------------------------------------------------------------- /example/2/result-head.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasimir/react-cssx/HEAD/example/2/result-head.png -------------------------------------------------------------------------------- /example/2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | React and CSSX 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /example/1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | React and CSSX 7 | 8 | 9 |

Another title here

10 |
11 |
12 |

13 | 14 | 15 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | entry: './src/CSSX.jsx', 3 | devtool: 'source-map', 4 | output: { 5 | path: __dirname + '/lib', 6 | filename: 'CSSX.js', 7 | libraryTarget: 'umd' 8 | }, 9 | externals: { 10 | 'react': 'react' 11 | }, 12 | module: { 13 | loaders: [ 14 | { 15 | test: /\.jsx?$/, 16 | exclude: /(node_modules|bower_components)/, 17 | loader: 'babel', 18 | query: { 19 | presets: ['react', 'es2015', 'stage-2'] 20 | } 21 | } 22 | ] 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /example/1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "1", 3 | "version": "1.0.0", 4 | "description": "CSS in React", 5 | "scripts": { 6 | "dev": "webpack --watch --inline" 7 | }, 8 | "author": "Krasimir Tsonev", 9 | "license": "MIT", 10 | "devDependencies": { 11 | "babel": "6.5.2", 12 | "babel-core": "6.6.5", 13 | "babel-loader": "6.2.4", 14 | "babel-preset-es2015": "6.6.0", 15 | "babel-preset-react": "6.5.0", 16 | "cssx-loader": "5.0.0", 17 | "react": "0.14.7", 18 | "react-cssx": "1.2.0", 19 | "react-dom": "0.14.7", 20 | "webpack": "1.12.14" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /example/2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "1", 3 | "version": "1.0.0", 4 | "description": "CSS in React", 5 | "scripts": { 6 | "dev": "webpack --watch --inline" 7 | }, 8 | "author": "Krasimir Tsonev", 9 | "license": "MIT", 10 | "devDependencies": { 11 | "babel": "6.5.2", 12 | "babel-core": "6.6.5", 13 | "babel-loader": "6.2.4", 14 | "babel-preset-es2015": "6.6.0", 15 | "babel-preset-react": "6.5.0", 16 | "cssx-loader": "5.0.0", 17 | "react": "0.14.7", 18 | "react-cssx": "1.2.0", 19 | "react-dom": "0.14.7", 20 | "webpack": "1.12.14" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /example/1/webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | entry: './src/app.jsx', 3 | devtool: 'source-map', 4 | output: { 5 | path: __dirname + '/build', 6 | filename: 'app.js' 7 | }, 8 | module: { 9 | loaders: [ 10 | { 11 | test: /\.jsx?$/, 12 | exclude: /(node_modules|bower_components)/, 13 | loader: 'babel', 14 | query: { 15 | presets: ['react', 'es2015'] 16 | } 17 | }, 18 | { 19 | test: /(\.js|\.jsx)$/, 20 | loader: 'cssx-loader', 21 | exclude: /node_modules/ 22 | } 23 | ] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /example/2/webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | entry: './src/app.jsx', 3 | devtool: 'source-map', 4 | output: { 5 | path: __dirname + '/build', 6 | filename: 'app.js' 7 | }, 8 | module: { 9 | loaders: [ 10 | { 11 | test: /\.jsx?$/, 12 | exclude: /(node_modules|bower_components)/, 13 | loader: 'babel', 14 | query: { 15 | presets: ['react', 'es2015'] 16 | } 17 | }, 18 | { 19 | test: /(\.js|\.jsx)$/, 20 | loader: 'cssx-loader', 21 | exclude: /node_modules/ 22 | } 23 | ] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 18 | .grunt 19 | 20 | # node-waf configuration 21 | .lock-wscript 22 | 23 | # Compiled binary addons (http://nodejs.org/api/addons.html) 24 | build/Release 25 | 26 | # Dependency directory 27 | node_modules 28 | 29 | # Optional npm cache directory 30 | .npm 31 | 32 | # Optional REPL history 33 | .node_repl_history 34 | -------------------------------------------------------------------------------- /example/1/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 18 | .grunt 19 | 20 | # node-waf configuration 21 | .lock-wscript 22 | 23 | # Compiled binary addons (http://nodejs.org/api/addons.html) 24 | build/Release 25 | 26 | # Dependency directory 27 | node_modules 28 | 29 | # Optional npm cache directory 30 | .npm 31 | 32 | # Optional REPL history 33 | .node_repl_history 34 | -------------------------------------------------------------------------------- /example/2/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 18 | .grunt 19 | 20 | # node-waf configuration 21 | .lock-wscript 22 | 23 | # Compiled binary addons (http://nodejs.org/api/addons.html) 24 | build/Release 25 | 26 | # Dependency directory 27 | node_modules 28 | 29 | # Optional npm cache directory 30 | .npm 31 | 32 | # Optional REPL history 33 | .node_repl_history 34 | -------------------------------------------------------------------------------- /example/2/src/app.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import CSSX from 'react-cssx'; 4 | // import CSSX from '../../../lib/CSSX.js'; 5 | 6 | class Component extends React.Component { 7 | render() { 8 | return ( 9 |
10 |

First paragraph

11 | 12 |

Second paragraph

13 |
14 | 15 |

Third paragraph

16 |
17 |
18 | ); 19 | } 20 | styleParagraph(color, text) { 21 | return ( 22 | 30 | ); 31 | } 32 | } 33 | 34 | ReactDOM.render(, document.querySelector('#content')); 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Krasimir Tsonev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-cssx", 3 | "version": "1.2.4", 4 | "description": "Proof of concept about using CSSX in React", 5 | "main": "lib/CSSX.js", 6 | "author": { 7 | "name": "Krasimir Tsonev", 8 | "email": "info@krasimirtsonev.com", 9 | "url": "http://krasimirtsonev.com" 10 | }, 11 | "license": "MIT", 12 | "keywords": [ 13 | "react", 14 | "css", 15 | "cssx" 16 | ], 17 | "repository": { 18 | "type": "git", 19 | "url": "git@github.com:krasimir/react-and-css.git" 20 | }, 21 | "scripts": { 22 | "dev": "webpack --watch --inline", 23 | "build": "webpack", 24 | "update-site": "gco gh-pages && git merge origin/master && ggpush && gco master" 25 | }, 26 | "dependencies": { 27 | "cssx": "5.2.0" 28 | }, 29 | "devDependencies": { 30 | "babel": "6.5.2", 31 | "babel-core": "6.14.0", 32 | "babel-loader": "6.2.5", 33 | "babel-preset-es2015": "6.14.0", 34 | "babel-preset-es2016": "6.11.3", 35 | "babel-preset-react": "6.11.1", 36 | "babel-preset-stage-2": "^6.22.0", 37 | "cssx-loader": "5.2.0", 38 | "react": "15.3.2", 39 | "react-dom": "15.3.2", 40 | "webpack": "1.12.14" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/CSSX.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import 'cssx'; 3 | 4 | var ids = 0; 5 | var getID = function (prefix) { 6 | return prefix + '-' + (++ids); 7 | }; 8 | 9 | export default class CSSX extends React.Component { 10 | constructor(props) { 11 | super(props); 12 | 13 | let sheet = cssx(getID('cssx-styles')); 14 | let cssScopeId = getID('cssx-el'); 15 | 16 | sheet.scope('#' + cssScopeId); 17 | 18 | this.state = { sheet, cssScopeId }; 19 | } 20 | componentWillUnmount() { 21 | this.state.sheet.destroy(); 22 | } 23 | render() { 24 | this.state.sheet.add(this.props.styles); 25 | 26 | var props = { ...this.props }; 27 | if (this.props['data-element'] === CSSX.defaultProps['data-element']) { 28 | delete props.styles; 29 | } 30 | 31 | return React.createElement( 32 | this.props['data-element'], 33 | { 34 | id: this.state.cssScopeId, 35 | ...props, 36 | }, 37 | this.props.children 38 | ); 39 | } 40 | }; 41 | 42 | CSSX.propTypes = { 43 | styles: React.PropTypes.object.isRequired, 44 | 'data-element': React.PropTypes.string 45 | }; 46 | 47 | CSSX.defaultProps = { 48 | 'data-element': 'div' 49 | } 50 | -------------------------------------------------------------------------------- /example/1/src/app.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import CSSX from 'react-cssx'; 4 | // import CSSX from '../../../lib/CSSX.js'; 5 | // import CSSX from '../../../src/CSSX.jsx'; 6 | 7 | class Component extends React.Component { 8 | constructor(props) { 9 | super(props); 10 | this.state = { 11 | color: '#000' 12 | } 13 | } 14 | render() { 15 | return ( 16 | 17 |

Title styled with CSSX

18 | 19 |
20 | ); 21 | } 22 | css() { 23 | return ( 24 | 37 | ); 38 | } 39 | _change(e) { 40 | this.setState({ color: e.target.value }); 41 | } 42 | } 43 | 44 | class Replacement extends React.Component { 45 | render() { 46 | return

Something else

; 47 | } 48 | } 49 | 50 | var content = document.querySelector('#content'); 51 | var button = document.querySelector('button'); 52 | 53 | ReactDOM.render(, content); 54 | button.addEventListener('click', function () { 55 | ReactDOM.render(, content); 56 | }); 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Using vanilla CSS in React application 2 | 3 | Yet another way to apply CSS styles in JavaScript. It's not using an inline styling though. It's injecting a ` 29 | ); 30 | } 31 | } 32 | ``` 33 | 34 | To make the code above works you'll need: 35 | 36 | * CSSX component (`npm install react-cssx`) 37 | * CSSX transpiler (It's available [here](https://github.com/krasimir/cssx/tree/master/packages/cssx-transpiler). Get it as a [webpack loader](https://github.com/krasimir/cssx/blob/master/packages/cssx-loader), [Meteor package](https://github.com/Quadric/meteor-cssx) or [gulp plugin](https://github.com/krasimir/cssx/blob/master/packages/gulp-cssx).) 38 | 39 | Demo [here](http://krasimir.github.io/react-cssx/example/1/) and [here](http://krasimir.github.io/react-cssx/example/2/). 40 | 41 | ### CSSX component 42 | 43 | `` component has only one required attribute - `styles`. It should be an array in the following format: 44 | 45 | ```js 46 | [ 47 | ['h1', { 'font-size': '32px' }], 48 | ['h1 small', { 'font-size': '24px', 'font-weight': 'bold' }] 49 | ] 50 | ``` 51 | 52 | Of course writing CSS that way is not really nice. So let's use CSSX and replace it with: 53 | 54 | ```js 55 | css() { 56 | return ( 57 | 66 | ); 67 | } 68 | ``` 69 | 70 | *Notice that we should use a function that returns a ` 111 | ); 112 | } 113 | } 114 | ``` 115 | 116 | There are three paragraphs rendered on the screen: 117 | 118 | ![CSSX](./example/2/result.png) 119 | 120 | The first one does not have any local styles attached. However, the second and the third one are styled differently. They have their own dedicated CSS. [CSSX library](https://github.com/krasimir/cssx/tree/master/packages/cssx) creates two `