diff --git a/.eslintrc.yml b/.eslintrc.yml new file mode 100644 index 00000000..b2dc66e7 --- /dev/null +++ b/.eslintrc.yml @@ -0,0 +1,27 @@ +extends: eslint:recommended +env: + node: true + browser: true +rules: + block-scoped-var: 2 + callback-return: 2 + dot-notation: 2 + indent: 2 + linebreak-style: [2, unix] + new-cap: 2 + no-console: [2, allow: [warn, error]] + no-else-return: 2 + no-eq-null: 2 + no-fallthrough: 2 + no-invalid-this: 2 + no-return-assign: 2 + no-shadow: 1 + no-trailing-spaces: 2 + no-use-before-define: [2, nofunc] + quotes: [2, single, avoid-escape] + semi: [2, always] + strict: [2, global] + valid-jsdoc: [2, requireReturn: false] + no-control-regex: 0 + no-useless-escape: 2 + diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..83b98e6f --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +.idea +node_modules +/.idea +.nyc_output +coverage +package-lock.json +yarn.lock +yarn-error.log +dist/ +.DS_Store +lerna-debug.log +/modules/ +/dist/ +.vscode/ +_book/ +/demo/*.js +/demo/*.js.map +/demo/analyzer/ diff --git a/.npmignore b/.npmignore new file mode 100644 index 00000000..69c896a9 --- /dev/null +++ b/.npmignore @@ -0,0 +1,20 @@ +node_modules/ +/test +.idea +.idea/ +__tests__/ +__mocks__/ +__stories__/ +.nyc_output +coverage +package-lock.json +yarn.lock +yarn-error.log +tsconfig.json +.vscode/ +/docs/ +.storybook/ +/build/ +/dist/ +/demo/ +/demo/analyzer/ diff --git a/.storybook/addons.js b/.storybook/addons.js new file mode 100644 index 00000000..6aed412d --- /dev/null +++ b/.storybook/addons.js @@ -0,0 +1,2 @@ +import '@storybook/addon-actions/register'; +import '@storybook/addon-links/register'; diff --git a/.storybook/config.js b/.storybook/config.js new file mode 100644 index 00000000..fa9a817e --- /dev/null +++ b/.storybook/config.js @@ -0,0 +1,9 @@ +import { configure } from '@storybook/react'; + +// automatically import all files ending in *.stories.js +const req = require.context('../.storybook', true, /.stories.tsx?$/); +function loadStories() { + req.keys().forEach((filename) => req(filename)); +} + +configure(loadStories, module); diff --git a/.storybook/webpack.config.js b/.storybook/webpack.config.js new file mode 100644 index 00000000..576cd297 --- /dev/null +++ b/.storybook/webpack.config.js @@ -0,0 +1,15 @@ +module.exports = { + module: { + rules: [ + { + test: /\.tsx?$/, + loader: 'ts-loader' + } + ] + }, + + resolve: { + extensions: ['.ts', '.tsx', '.js', '.jsx'], + enforceExtension: false + } +}; diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..33f1b33c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,22 @@ +language: node_js +os: + - linux +cache: + yarn: true + directories: + - ~/.npm +notifications: + email: false +node_js: + - '8' +script: + - npm run test + - npm run build +matrix: + allow_failures: [] + fast_finish: true +after_success: + - npm run semantic-release +branches: + except: + - /^v\d+\.\d+\.\d+$/ \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..fdddb29a --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/README.md b/README.md new file mode 100644 index 00000000..76b89475 --- /dev/null +++ b/README.md @@ -0,0 +1,114 @@ +# ezcss + +[![][npm-badge]][npm-url] [![][travis-badge]][travis-url] + +Super lite CSS-in-JS solution. + + +## Usage + +Import renderer. + +```js +import {Renderer} from 'ezcss'; + +const renderer = new Renderer; +const {rule, sheet, withStyles, useStyles, styled, css} = renderer; +``` + +Render a single "rule". + +```js +const className = rule({ + border: '1px solid red' +}, 'MyName'); + +
+``` + +Create a "styles sheet" with multiple lazy-evaluating rules. + +```js +const styles = sheet({ + main: { + border: '1px solid red' + }, + element: { + border: '1px solid blue' + } +}, 'MyName'); + +
+``` + +Injects `styles` prop into component. + +```js +const styles = { + main: { + border: '1px solid red' + } +}; + +const MyComp = withStyles(styles, function MyComp ({styles}) { + return
+}); +``` + +Use `styles` object in your component. + +```js +const styles = { + main: { + border: '1px solid red' + } +}; + +const MyComp = useStyles(styles, function MyComp (props, styles) { + return
+}); +``` + +Create "styled" components. + +```js +const Div = styled('div', { + border: '1px solid red' +}, 'RedBorderDiv'); + +
Hello world!
+``` + +Stateful component style decorator. + +```js +@css({ + border: '1px solid red' +}) +class MyComponent extends Component { + render () { + + } +} +``` + + +## Server Side Rendering + +`excss` works in Node.js environment as well. Use `.raw` property to access raw CSS styles +on server and include then in your template. + +```js +const html += ``; +``` + + +## License + +[Unlicense](./LICENSE) — public domain. + + +[npm-url]: https://www.npmjs.com/package/ezcss +[npm-badge]: https://img.shields.io/npm/v/ezcss.svg +[travis-url]: https://travis-ci.org/streamich/ezcss +[travis-badge]: https://travis-ci.org/streamich/ezcss.svg?branch=master diff --git a/build/gulpfile.js b/build/gulpfile.js new file mode 100644 index 00000000..956fc8df --- /dev/null +++ b/build/gulpfile.js @@ -0,0 +1,29 @@ +'use strict'; + +var gulp = require('gulp'); +var ts = require('gulp-typescript'); +var config = require('../tsconfig.json'); + +gulp.task('build-ts', function() { + return gulp + .src(['../src/**/*.ts', '!../src/**/__tests__/**']) + .pipe( + ts(Object.assign({}, config.compilerOptions, { + target: 'es5', + module: 'commonjs', + })) + ) + .pipe(gulp.dest('../lib')); +}); + +gulp.task('build-modules', function() { + return gulp + .src(['../src/**/*.ts', '!../src/**/__tests__/**']) + .pipe( + ts(Object.assign({}, config.compilerOptions, { + target: 'ESNext', + module: 'ESNext', + })) + ) + .pipe(gulp.dest('../modules')); +}); diff --git a/build/webpack.config.cjs.js b/build/webpack.config.cjs.js new file mode 100644 index 00000000..f2adb8c8 --- /dev/null +++ b/build/webpack.config.cjs.js @@ -0,0 +1,27 @@ +'use strict'; + +var pkg = require('../package.json'); +var join = require('path').join; + +module.exports = { + entry: join(__dirname, '..', 'src', 'index.ts'), + + output: { + filename: pkg.name + '.min.js', + path: join(__dirname, '..', 'dist') + }, + + module: { + rules: [ + { + test: /\.tsx?$/, + loader: 'ts-loader' + } + ] + }, + + resolve: { + extensions: ['.ts', '.tsx', '.js', '.jsx'], + enforceExtension: false + } +}; diff --git a/build/webpack.config.umd.js b/build/webpack.config.umd.js new file mode 100644 index 00000000..a8fd2abd --- /dev/null +++ b/build/webpack.config.umd.js @@ -0,0 +1,10 @@ +'use strict'; + +var pkg = require('../package.json'); +var config = require('./webpack.config.cjs.js'); + +config.output.filename = pkg.name + '.umd.min.js'; +config.output.library = pkg.name; +config.output.libraryTarget = 'umd'; + +module.exports = config; diff --git a/demo/demo1.html b/demo/demo1.html new file mode 100644 index 00000000..dc64f490 --- /dev/null +++ b/demo/demo1.html @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/demo/demo1.tsx b/demo/demo1.tsx new file mode 100644 index 00000000..526d6e5f --- /dev/null +++ b/demo/demo1.tsx @@ -0,0 +1,17 @@ +import {createElement as h} from 'react'; +import {render} from 'react-dom'; +import {Renderer} from '../src/lite'; + +const renderer = new Renderer; +const {rule} = renderer; + +const className = rule({ + border: '1px solid red' +}); + +const el = document.createElement('div'); +document.body.appendChild(el); + +render(
+ Hello world! +
, el); diff --git a/package.json b/package.json index 3d931b38..dbcc97a0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pico-style", - "version": "0.1.0", + "version": "0.0.1", "description": "Smallest 4th gen CSS-in-JS library", "main": "lib/index.js", "unpkg": "dist/pico-style.umd.min.js", @@ -11,8 +11,8 @@ "scripts": { "eslint": "eslint src", "start": "npm run storybook", - "clean": "rimraf modules lib dist && npm run test:visual:clean", - "build": "npm run clean && npm run build:lib && npm run build:cjs && npm run build:umd", + "clean": "rimraf dist && npm run test:visual:clean", + "build": "npm run clean && npm run build:cjs && npm run build:umd", "build:modules": "gulp build-modules --gulpfile build/gulpfile.js", "build:lib": "gulp build-ts --gulpfile build/gulpfile.js", "build:cjs": "webpack -p --config build/webpack.config.cjs.js", diff --git a/renovate.json b/renovate.json new file mode 100644 index 00000000..3d1bae41 --- /dev/null +++ b/renovate.json @@ -0,0 +1,14 @@ +{ + "extends": [ + "config:base" + ], + "automerge": true, + "pinVersions": false, + "major": { + "automerge": false + }, + "devDependencies": { + "automerge": true, + "pinVersions": true + } +}