├── .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 |
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 |
--------------------------------------------------------------------------------