├── .gitignore ├── .npmignore ├── README.md ├── example ├── README.md ├── app.js └── index.html ├── package.json ├── rollup.config.js ├── src └── index.js └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | yarn.lock 4 | package-lock.json 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | example 2 | rollup.config.js 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Picostyle for React 2 | 3 | [![350 gzip][gzip-badge]][bundlesize] 4 | 5 | [gzip-badge]: https://img.shields.io/badge/minified%20&%20gzipped-350%20B-brightgreen.svg 6 | [bundlesize]: https://github.com/siddharthkp/bundlesize 7 | 8 |
9 | 10 | 11 | 12 |
13 |
14 | 15 | Picostyle React is the package of [Picostyle](https://github.com/picostyle/picostyle) for [React](https://github.com/facebook/react). 16 | 17 | [Try it Online](https://codepen.io/morishitter/pen/qXaPYQ?editors=0010) 18 | 19 | ## Features 20 | 21 | - **🚀 The smallest CSS-in-JS library**: Only 0.3 KB (minified & gzipped). 22 | - **👏 Zero dependencies**: And under 60 LOC. 23 | - **💅 Styled components**: Gives you a styled component like [styled-components](https://www.styled-components.com/) that y'all love. 24 | - **❤️ For React**: The 1 KB frontend library family. 25 | 26 | ## Installation 27 | 28 |
29 | $ npm install picostyle-react
30 | 
31 | 32 | ## Usage 33 | 34 | Picostyle React works well with: 35 | 36 | - Media Queries (`@media`) 37 | - Pseudo-element (`::before`) 38 | - Pseudo-classes (`:hover`) 39 | 40 | ### With React 41 | 42 | [Get the Code](https://github.com/picostyle/picostyle-react/tree/master/example) 43 | 44 | ```js 45 | import React from "react" 46 | import ReactDOM from "react-dom" 47 | import picostyle from "picostyle-react" 48 | 49 | const ps = picostyle(React.createElement) 50 | 51 | const keyColor = "#f07" 52 | 53 | const Text = ps("h1")({ 54 | fontSize: "64px", 55 | cursor: "pointer", 56 | color: "#fff", 57 | padding: "0.4em", 58 | transition: "all .2s ease-in-out", 59 | ":hover": { 60 | transform: "scale(1.3)", 61 | }, 62 | "@media (max-width: 450px)": { 63 | fontSize: "32px", 64 | }, 65 | }) 66 | 67 | const Wrapper = ps("div")({ 68 | display: "flex", 69 | justifyContent: "center", 70 | alignItems: "center", 71 | width: "100vw", 72 | height: "100vh", 73 | backgroundColor: keyColor, 74 | }) 75 | 76 | class Hello extends React.Component { 77 | render() { 78 | 79 | return ( 80 | 81 | Picostyle 82 | 83 | ) 84 | } 85 | } 86 | 87 | ReactDOM.render( 88 | , 89 | document.getElementById("app") 90 | ) 91 | ``` 92 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # How to setup 2 | 3 | ``` 4 | $ yarn install 5 | $ yarn start 6 | ``` 7 | -------------------------------------------------------------------------------- /example/app.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import ReactDOM from 'react-dom' 3 | import picostyle from "../" 4 | 5 | const ps = picostyle(React.createElement) 6 | 7 | class Hello extends React.Component { 8 | render() { 9 | const keyColor = "#f07" 10 | 11 | const Text = ps("h1")({ 12 | fontSize: "64px", 13 | cursor: "pointer", 14 | color: "#fff", 15 | padding: "0.4em", 16 | transition: "all .2s ease-in-out", 17 | ":hover": { 18 | transform: "scale(1.3)", 19 | }, 20 | "@media (max-width: 450px)": { 21 | fontSize: "32px", 22 | }, 23 | }) 24 | 25 | const Wrapper = ps("div")({ 26 | display: "flex", 27 | justifyContent: "center", 28 | alignItems: "center", 29 | width: "100vw", 30 | height: "100vh", 31 | backgroundColor: keyColor, 32 | }) 33 | 34 | return ( 35 | 36 | Picostyle 37 | 38 | ) 39 | } 40 | } 41 | 42 | ReactDOM.render( 43 | , 44 | document.getElementById("app") 45 | ) 46 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Picostyle 8 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "picostyle-react", 3 | "version": "0.0.1", 4 | "description": "Picostyle for React", 5 | "main": "dist/picostyle-react.js", 6 | "scripts": { 7 | "build": "npm run clear && rollup -c", 8 | "clear": "(rm -rf dist || true) && mkdir dist", 9 | "test": "npm run build && size-limit", 10 | "example": "webpack-dev-server" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/picostyle/picostyle-react.git" 15 | }, 16 | "keywords": [ 17 | "css-in-js", 18 | "react", 19 | "picostyle" 20 | ], 21 | "author": "Masaaki Morishita", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/picostyle/picostyle-react/issues" 25 | }, 26 | "homepage": "https://github.com/picostyle/picostyle-react#readme", 27 | "devDependencies": { 28 | "babel-core": "^6.26.0", 29 | "babel-loader": "^7.1.2", 30 | "babel-plugin-transform-react-jsx": "^6.24.1", 31 | "babel-preset-env": "^1.6.0", 32 | "react": "^15.6.1", 33 | "react-dom": "^15.6.1", 34 | "rollup": "^0.47.6", 35 | "rollup-plugin-uglify": "^2.0.1", 36 | "size-limit": "^0.10.0", 37 | "webpack": "^3.5.5", 38 | "webpack-dev-server": "^2.7.1" 39 | }, 40 | "size-limit": [ 41 | { 42 | "path": "dist/picostyle-react.js", 43 | "limit": "399B" 44 | } 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import uglify from "rollup-plugin-uglify" 2 | 3 | export default { 4 | entry: "src/index.js", 5 | dest: "dist/picostyle-react.js", 6 | format: "umd", 7 | moduleName: "picostyleReact", 8 | plugins: [ 9 | uglify() 10 | ], 11 | sourceMap: true, 12 | } 13 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | var _id = 0 2 | var sheet = document.head.appendChild(document.createElement("style")).sheet 3 | 4 | function hyphenate (str) { 5 | return str.replace(/[A-Z]/g, "-$&").toLowerCase() 6 | } 7 | 8 | function insert (rule) { 9 | sheet.insertRule(rule, 0) 10 | } 11 | 12 | function createRule (className, decls, media) { 13 | var newDecls = [] 14 | for (var property in decls) { 15 | newDecls.push(hyphenate(property) + ":" + decls[property] + ";") 16 | } 17 | var rule = "." + className + "{" + newDecls.join("") + "}" 18 | return media ? media + "{" + rule + "}" : rule 19 | } 20 | 21 | function parse (decls, child, media, className) { 22 | child = child || "" 23 | className = className || "p" + (_id++).toString(36) 24 | 25 | for (var property in decls) { 26 | var value = decls[property] 27 | if (typeof value === "object") { 28 | var nextMedia = /^@/.test(property) ? property : null 29 | var nextChild = nextMedia ? child : child + property 30 | parse(value, nextChild, nextMedia, className) 31 | } 32 | } 33 | 34 | insert(createRule(className + child, decls, media)) 35 | return className 36 | } 37 | 38 | function merge(a, b) { 39 | var obj = {} 40 | 41 | for (var i in a) { 42 | obj[i] = a[i] 43 | } 44 | for (var i in b) { 45 | obj[i] = b[i] 46 | } 47 | 48 | return obj 49 | } 50 | 51 | export default function (h) { 52 | return function (type) { 53 | return function (decls) { 54 | return function (props) { 55 | return h(type, merge(props, { className: parse(decls) })) 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const APP_ROOT = __dirname; 4 | 5 | module.exports = { 6 | context: APP_ROOT, 7 | devServer: { 8 | contentBase: 'example', 9 | }, 10 | entry: { 11 | app: './example/app.js', 12 | }, 13 | module: { 14 | rules: [ 15 | { 16 | test: /\.js$/, 17 | exclude: /node_modules/, 18 | use: [ 19 | { 20 | loader: 'babel-loader', 21 | options: { 22 | presets: [ 23 | ["env", { 24 | "targets": { 25 | "browsers": [ 26 | "ie >= 11", 27 | "last 2 Edge versions", 28 | "last 2 Firefox versions", 29 | "last 2 Chrome versions", 30 | "last 2 Safari versions", 31 | "last 2 Opera versions", 32 | "last 2 iOS versions", 33 | "last 2 ChromeAndroid versions" 34 | ], 35 | }, 36 | }] 37 | ], 38 | plugins: [ 39 | 'transform-react-jsx' 40 | ], 41 | }, 42 | }, 43 | ], 44 | } 45 | ], 46 | }, 47 | output: { 48 | filename: '[name].js', 49 | path: path.join(APP_ROOT, 'example/dist'), 50 | publicPath: '/dist/', 51 | }, 52 | }; 53 | --------------------------------------------------------------------------------