├── .gitignore ├── .npmignore ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── package.json ├── src └── index.ts ├── test.js └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib 3 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | node_modules 3 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "./node_modules/typescript/lib" 3 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 André Staltz 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # css2obj 2 | 3 | Takes CSS-looking properties as an ES6 tagged template literal and returns an object suitable for `styles.registerStyle()` in [Free-Style](https://github.com/blakeembrey/free-style). 4 | 5 | ``` 6 | npm install css2obj 7 | ``` 8 | 9 | Raw example: 10 | 11 | ```js 12 | const thirty = 30; 13 | const obj = css2obj` 14 | position: absolute; 15 | left: 20px; 16 | bottom: ${thirty}px; 17 | `; 18 | 19 | console.log(obj); 20 | /* 21 | { 22 | 'position': 'absolute', 23 | 'left': '20px', 24 | 'bottom': '30px' 25 | } 26 | */ 27 | ``` 28 | 29 | Example with Free-Style: 30 | 31 | ```js 32 | const thirty = 30; 33 | 34 | styles.registerStyle(css2obj` 35 | position: absolute; 36 | left: 20px; 37 | bottom: ${thirty}px; 38 | `); 39 | ``` 40 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "css2obj", 3 | "version": "1.0.1", 4 | "description": "Tagged template literal that takes CSS and returns a JavaScript object suitable for free-style", 5 | "author": "staltz", 6 | "license": "MIT", 7 | "main": "lib/index.js", 8 | "typings": "lib/index.d.ts", 9 | "scripts": { 10 | "pretest": "npm run lib", 11 | "test": "ava", 12 | "prelib": "mkdir -p lib", 13 | "lib": "tsc", 14 | "prepublish": "npm run lib" 15 | }, 16 | "devDependencies": { 17 | "ava": "^0.16.0", 18 | "typescript": "^2.0.2" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | function wholeArray(strs: Array, vals: Array): Array { 2 | let resultArray: Array = []; 3 | for (let i = 0, N = strs.length, M = vals.length; i < N || i < M; i++) { 4 | if (i < N) { 5 | resultArray = resultArray.concat(strs[i]); 6 | } 7 | if (i < M) { 8 | resultArray = resultArray.concat(vals[i]); 9 | } 10 | } 11 | return resultArray 12 | .join('') 13 | .split(/[\:\;]/g) 14 | .map(s => s.trim()) 15 | .filter(s => s.length > 0); 16 | } 17 | 18 | export default function css2obj(strings, ...values) { 19 | const obj = {}; 20 | let index = 0; 21 | const strsAndVals = wholeArray(strings, values); 22 | let key = ''; 23 | strsAndVals.forEach((part, i) => { 24 | if (i % 2 === 0) { 25 | key = part; 26 | } else { 27 | obj[key] = `${part}`; 28 | } 29 | }); 30 | return obj; 31 | } 32 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import css2obj from './lib/index'; 3 | 4 | test('plain simple CSS properties to object', t => { 5 | const obj = css2obj` 6 | position: absolute; 7 | left: 20; 8 | bottom: 30; 9 | `; 10 | 11 | t.is(JSON.stringify(obj), '{"position":"absolute","left":"20","bottom":"30"}'); 12 | t.pass(); 13 | }); 14 | 15 | test('simple CSS properties with one interpolation to object', t => { 16 | const b = 30; 17 | const obj = css2obj` 18 | position: absolute; 19 | left: 20; 20 | bottom: ${b}; 21 | `; 22 | 23 | t.is(JSON.stringify(obj), JSON.stringify({ 24 | 'position': 'absolute', 25 | 'left': '20', 26 | 'bottom': '30', 27 | })); 28 | t.pass(); 29 | }); 30 | 31 | test('plain complex CSS properties to object', t => { 32 | const obj = css2obj` 33 | background-color: rgba(0, 0, 0, 0); 34 | box-shadow: 0 1px 1px 0 #c5c5c5; 35 | color: #686868; 36 | border: none; 37 | font-size: 20px; 38 | text-align: center; 39 | width: 30px; 40 | height: 30px; 41 | line-height: 30px; 42 | margin: 4px; 43 | cursor: pointer; 44 | `; 45 | 46 | t.is(JSON.stringify(obj), JSON.stringify({ 47 | 'background-color': 'rgba(0, 0, 0, 0)', 48 | 'box-shadow': '0 1px 1px 0 #c5c5c5', 49 | 'color': '#686868', 50 | 'border': 'none', 51 | 'font-size': '20px', 52 | 'text-align': 'center', 53 | 'width': '30px', 54 | 'height': '30px', 55 | 'line-height': '30px', 56 | 'margin': '4px', 57 | 'cursor': 'pointer', 58 | })); 59 | t.pass(); 60 | }); 61 | 62 | test('complex CSS properties with 3 interpolations to object', t => { 63 | const smallSpace = 4; 64 | const largeSpace = 30; 65 | const grey = '#686868'; 66 | const obj = css2obj` 67 | background-color: rgba(0, 0, 0, 0); 68 | box-shadow: 0 1px 1px 0 #c5c5c5; 69 | color: ${grey}; 70 | border: none; 71 | font-size: 20px; 72 | text-align: center; 73 | width: ${largeSpace}px; 74 | height: ${largeSpace}px; 75 | line-height: ${largeSpace}px; 76 | margin: ${smallSpace}px; 77 | cursor: pointer; 78 | `; 79 | 80 | t.is(JSON.stringify(obj), JSON.stringify({ 81 | 'background-color': 'rgba(0, 0, 0, 0)', 82 | 'box-shadow': '0 1px 1px 0 #c5c5c5', 83 | 'color': '#686868', 84 | 'border': 'none', 85 | 'font-size': '20px', 86 | 'text-align': 'center', 87 | 'width': '30px', 88 | 'height': '30px', 89 | 'line-height': '30px', 90 | 'margin': '4px', 91 | 'cursor': 'pointer', 92 | })); 93 | t.pass(); 94 | }); -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es5", 5 | "declaration": true, 6 | "noImplicitAny": false, 7 | "noImplicitReturns": true, 8 | "strictNullChecks": true, 9 | "sourceMap": true, 10 | "outDir": "lib/" 11 | }, 12 | "formatCodeOptions": { 13 | "indentSize": 2, 14 | "tabSize": 2 15 | }, 16 | "files": [ 17 | "src/index.ts" 18 | ] 19 | } 20 | --------------------------------------------------------------------------------