├── .editorconfig ├── .gitignore ├── .npmignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── package.json ├── src ├── plugin.spec.ts └── plugin.ts ├── tsconfig.json └── tslint.json /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = tab 5 | end_of_line = lf 6 | trim_trailing_whitespace = true 7 | insert_final_newline = true 8 | 9 | [{package.json,*.yml}] 10 | indent_style = space 11 | indent_size = 2 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | .nyc_output/ 3 | .vscode/ 4 | coverage/ 5 | dist/ 6 | node_modules/ 7 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .* 2 | *.map 3 | *.spec.* 4 | .nyc_output/ 5 | .vscode/ 6 | coverage/ 7 | src/ 8 | tsconfig.json 9 | tslint.json 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - "node" 5 | - "6" 6 | 7 | after_success: 8 | - npm install codecov 9 | - npm run codecov 10 | 11 | notifications: 12 | email: 13 | on_success: change 14 | on_failure: always 15 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.1.0 2 | - Upgrade to Postcss 6 (still works with PostCSS 5). 3 | 4 | ## 1.0.0 5 | - Supports PostCSS 5.x. 6 | 7 | ## 0.0.8 8 | - Fix package. 9 | - Move babel-core to dev dependency. 10 | 11 | ## 0.0.7 12 | - Fix package (remove index.js). 13 | 14 | ## 0.0.6 15 | - Fix package. 16 | - Reorganize files. 17 | 18 | ## 0.0.5 19 | - Removed `circle-diameter` and `circle-color` properties. 20 | - Only the `circle` property is supported. 21 | 22 | ## 0.0.4 23 | - Uses `circle-diameter` and `circle-color` properties to create a circle. 24 | - Supports `circle` shorthand property. 25 | 26 | ## 0.0.1 27 | - Supports PostCSS 4.x. 28 | - Uses `@circle` at-rule to create a circle. 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Jed Mao 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 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # postcss-circle 2 | 3 | 6 | 7 | [![NPM version](http://img.shields.io/npm/v/postcss-circle.svg?style=flat)](https://www.npmjs.org/package/postcss-circle) 8 | [![npm license](http://img.shields.io/npm/l/postcss-circle.svg?style=flat-square)](https://www.npmjs.org/package/postcss-circle) 9 | [![Travis Build Status](https://img.shields.io/travis/jedmao/postcss-circle.svg)](https://travis-ci.org/jedmao/postcss-circle) 10 | [![codecov](https://codecov.io/gh/jedmao/postcss-circle/branch/master/graph/badge.svg)](https://codecov.io/gh/jedmao/postcss-circle) 11 | [![Dependency Status](https://gemnasium.com/badges/github.com/jedmao/postcss-circle.svg)](https://gemnasium.com/github.com/jedmao/postcss-circle) 12 | 13 | [![npm](https://nodei.co/npm/postcss-circle.svg?downloads=true)](https://nodei.co/npm/postcss-circle/) 14 | 15 | [PostCSS](https://github.com/postcss/postcss) plugin to insert a circle with color. 16 | 17 | ## Introduction 18 | 19 | Creating a circle in CSS [isn't terribly difficult](http://davidwalsh.name/css-circles); however, it could be easier and more expressive: 20 | 21 | ```css 22 | .circle { 23 | circle: [color]; 24 | } 25 | ``` 26 | 27 | The `diameter` is required and the `color` is optional. You don't have to remember the order, because you can swap their positions. 28 | 29 | Let's create a `red` circle with a `100px` diameter: 30 | 31 | ```css 32 | .circle { 33 | circle: 100px red; 34 | } 35 | ``` 36 | 37 | This transpiles into: 38 | 39 | ```css 40 | .circle { 41 | border-radius: 50%; 42 | width: 100px; 43 | height: 100px; 44 | background-color: red; 45 | } 46 | ``` 47 | 48 | That's it, really. 49 | 50 | ## Installation 51 | 52 | ``` 53 | $ npm install postcss-circle 54 | ``` 55 | 56 | ## Usage 57 | 58 | ### JavaScript 59 | 60 | ```js 61 | postcss([ require('postcss-circle') ]); 62 | ``` 63 | 64 | ### TypeScript 65 | 66 | ```ts 67 | import * as postcssCircle from 'postcss-circle'; 68 | 69 | postcss([ postcssCircle ]); 70 | ``` 71 | 72 | ## Options 73 | 74 | None at this time. 75 | 76 | ## Testing 77 | 78 | Run the following command: 79 | 80 | ``` 81 | $ npm test 82 | ``` 83 | 84 | This will build scripts, run tests and generate a code coverage report. Anything less than 100% coverage will throw an error. 85 | 86 | ### Watching 87 | 88 | For much faster development cycles, run the following commands in 2 separate processes: 89 | 90 | ``` 91 | $ npm run build:watch 92 | ``` 93 | 94 | Compiles TypeScript source into the `./dist` folder and watches for changes. 95 | 96 | ``` 97 | $ npm run watch 98 | ``` 99 | 100 | Runs the tests in the `./dist` folder and watches for changes. 101 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "postcss-circle", 3 | "version": "1.1.0", 4 | "description": "PostCSS plugin to insert a circle with color.", 5 | "main": "dist/plugin.js", 6 | "types": "dist/plugin.d.ts", 7 | "scripts": { 8 | "clean": "rimraf coverage dist *.log", 9 | "codecov": "codecov -f coverage/lcov.info", 10 | "build": "tsc", 11 | "build:watch": "tsc --watch", 12 | "prepublish": "npm test", 13 | "pretest": "npm run tslint && npm run clean && npm run build", 14 | "test": "nyc ava", 15 | "test:watch": "ava --watch", 16 | "tslint": "tslint --project tsconfig.json", 17 | "watch": "npm run test:watch" 18 | }, 19 | "ava": { 20 | "files": [ 21 | "dist/**/*.spec.js" 22 | ], 23 | "source": [ 24 | "dist/**/*.js" 25 | ] 26 | }, 27 | "nyc": { 28 | "lines": 100, 29 | "statements": 100, 30 | "functions": 100, 31 | "branches": 100, 32 | "include": [ 33 | "dist/**/*.js" 34 | ], 35 | "exclude": [ 36 | "dist/**/*.spec.js" 37 | ], 38 | "reporter": [ 39 | "lcov", 40 | "text" 41 | ], 42 | "cache": true, 43 | "all": true, 44 | "check-coverage": true 45 | }, 46 | "repository": { 47 | "type": "git", 48 | "url": "git+https://github.com/jedmao/postcss-circle.git" 49 | }, 50 | "keywords": [ 51 | "postcss", 52 | "postcss-plugin", 53 | "circle" 54 | ], 55 | "author": "Jed Mao ", 56 | "license": "MIT", 57 | "bugs": { 58 | "url": "https://github.com/jedmao/postcss-circle/issues" 59 | }, 60 | "homepage": "https://github.com/jedmao/postcss-circle#readme", 61 | "dependencies": { 62 | "postcss": "^6.0.14" 63 | }, 64 | "devDependencies": { 65 | "@types/node": "^8.0.47", 66 | "ava": "^0.23.0", 67 | "nyc": "^11.3.0", 68 | "rimraf": "^2.6.2", 69 | "tslint": "^5.8.0", 70 | "typescript": "^2.6.1" 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/plugin.spec.ts: -------------------------------------------------------------------------------- 1 | import test, { TestContext } from 'ava'; 2 | import * as postcss from 'postcss'; 3 | 4 | import * as plugin from './plugin'; 5 | 6 | test('throws if no diameter is supplied', macro, 7 | `foo { 8 | circle: red; 9 | }`, 10 | /Missing diameter/ 11 | ); 12 | 13 | test('transpiles diameter into expected declarations', macro, 14 | `foo { 15 | circle: 100px; 16 | }`, 17 | `foo { 18 | border-radius: 50%; 19 | width: 100px; 20 | height: 100px; 21 | }` 22 | ); 23 | 24 | test('transpiles diameter and color into expected declarations', t => { 25 | [ 26 | `foo { 27 | circle: 100px red; 28 | }`, 29 | `foo { 30 | circle: red 100px; 31 | }` 32 | ].forEach(input => { 33 | macro(t, 34 | input, 35 | `foo { 36 | border-radius: 50%; 37 | width: 100px; 38 | height: 100px; 39 | background-color: red; 40 | }` 41 | ); 42 | }); 43 | }); 44 | 45 | function macro( 46 | t: TestContext, 47 | input: string, 48 | expected?: string | RegExp 49 | ) { 50 | const processor = postcss([ plugin() ]); 51 | if (expected instanceof RegExp) { 52 | t.throws(() => { 53 | return processor.process(stripTabs(input)).css; 54 | }, expected); 55 | return; 56 | } 57 | t.is( 58 | processor.process(stripTabs(input)).css, 59 | stripTabs(expected) 60 | ); 61 | function stripTabs(input: string) { 62 | return input.replace(/\t/g, ''); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/plugin.ts: -------------------------------------------------------------------------------- 1 | import * as postcss from 'postcss'; 2 | 3 | const errorContext = { 4 | plugin: 'postcss-circle' 5 | }; 6 | 7 | const PostCssCircle = postcss.plugin('postcss-circle', () => { 8 | return root => { 9 | root.walkRules(rule => { 10 | rule.walkDecls('circle', decl => { 11 | let [diameter, color] = postcss.list.space(decl.value); 12 | if (!/^\d/.test(diameter)) { 13 | [diameter, color] = [color, diameter]; 14 | } 15 | if (!diameter) { 16 | throw decl.error('Missing diameter', errorContext); 17 | } 18 | decl.cloneBefore({ 19 | prop: 'border-radius', 20 | value: '50%' 21 | }); 22 | if (color) { 23 | decl.cloneAfter({ 24 | prop: 'background-color', 25 | value: color 26 | }); 27 | } 28 | decl.prop = 'width'; 29 | decl.value = diameter; 30 | decl.cloneAfter({ prop: 'height' }); 31 | }); 32 | }); 33 | }; 34 | }); 35 | 36 | export = PostCssCircle; 37 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "noImplicitAny": true, 5 | "target": "es6", 6 | "declaration": true, 7 | "newLine": "LF", 8 | "outDir": "dist", 9 | "rootDir": "src", 10 | "sourceMap": true, 11 | "lib": [ 12 | "es2015" 13 | ] 14 | }, 15 | "include": [ 16 | "src/**/*.ts" 17 | ], 18 | "exclude": [ 19 | "node_modules" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "class-name": true, 4 | "curly": true, 5 | "eofline": true, 6 | "forin": true, 7 | "label-position": true, 8 | "max-line-length": [true, 120], 9 | "no-arg": true, 10 | "no-bitwise": true, 11 | "no-console": [true, 12 | "debug", 13 | "info", 14 | "time", 15 | "timeEnd", 16 | "trace" 17 | ], 18 | "no-construct": true, 19 | "no-debugger": true, 20 | "no-duplicate-variable": true, 21 | "no-empty": true, 22 | "no-eval": true, 23 | "no-string-literal": true, 24 | "no-trailing-whitespace": true, 25 | "one-line": [true, 26 | "check-open-brace", 27 | "check-catch", 28 | "check-else", 29 | "check-whitespace" 30 | ], 31 | "quotemark": [false], 32 | "radix": true, 33 | "semicolon": [true, 34 | "always" 35 | ], 36 | "triple-equals": [true, "allow-null-check"], 37 | "variable-name": false, 38 | "whitespace": [true, 39 | "check-branch", 40 | "check-decl", 41 | "check-operator", 42 | "check-type" 43 | ] 44 | } 45 | } 46 | --------------------------------------------------------------------------------