├── LICENSE ├── README.md ├── index.js ├── lib ├── CSSProperty.js └── hyphenateStyleName.js └── package.json /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Calvin 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 | # Summary 2 | Convert React style defined as an object to pure inline css (string). 3 | 4 | # Installation 5 | ```js 6 | npm install react-style-object-to-css 7 | ``` 8 | 9 | # Example 10 | ```js 11 | const reactToCSS = require('react-style-object-to-css') 12 | const styleObj = { 13 | backgroundColor: 'blue', 14 | fontSize: 14 15 | } 16 | 17 | // result === "background-color: blue; font-size: 14px;" 18 | const result = reactToCSS(styleObj) 19 | ``` 20 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var isUnitlessNumber = require('./lib/CSSProperty').isUnitlessNumber; 4 | var hyphenateStyleName = require('./lib/hyphenateStyleName'); 5 | var isArray = Array.isArray; 6 | var keys = Object.keys; 7 | 8 | var counter = 1; 9 | // Follows syntax at https://developer.mozilla.org/en-US/docs/Web/CSS/content, 10 | // including multiple space separated values. 11 | var unquotedContentValueRegex = /^(normal|none|(\b(url\([^)]*\)|chapter_counter|attr\([^)]*\)|(no-)?(open|close)-quote|inherit)((\b\s*)|$|\s+))+)$/; 12 | 13 | function buildRule(key, value) { 14 | if (!isUnitlessNumber[key] && typeof value === 'number') { 15 | value = '' + value + 'px'; 16 | } 17 | else if (key === 'content' && !unquotedContentValueRegex.test(value)) { 18 | value = "'" + value.replace(/'/g, "\\'") + "'"; 19 | } 20 | 21 | return hyphenateStyleName(key) + ': ' + value + '; '; 22 | } 23 | 24 | function styleToCssString(rules) { 25 | var result = '' 26 | if (!rules || keys(rules).length === 0) { 27 | return result; 28 | } 29 | var styleKeys = keys(rules); 30 | for (var j = 0, l = styleKeys.length; j < l; j++) { 31 | var styleKey = styleKeys[j]; 32 | var value = rules[styleKey]; 33 | 34 | if (isArray(value)) { 35 | for (var i = 0, len = value.length; i < len; i++) { 36 | result += buildRule(styleKey, value[i]); 37 | } 38 | } 39 | else { 40 | result += buildRule(styleKey, value); 41 | } 42 | } 43 | return result; 44 | } 45 | 46 | module.exports = styleToCssString; 47 | -------------------------------------------------------------------------------- /lib/CSSProperty.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * CSS properties which accept numbers but are not in units of "px". 5 | */ 6 | var isUnitlessNumber = { 7 | boxFlex: true, 8 | boxFlexGroup: true, 9 | columnCount: true, 10 | flex: true, 11 | flexGrow: true, 12 | flexPositive: true, 13 | flexShrink: true, 14 | flexNegative: true, 15 | fontWeight: true, 16 | lineClamp: true, 17 | lineHeight: true, 18 | opacity: true, 19 | order: true, 20 | orphans: true, 21 | widows: true, 22 | zIndex: true, 23 | zoom: true, 24 | 25 | // SVG-related properties 26 | fillOpacity: true, 27 | strokeDashoffset: true, 28 | strokeOpacity: true, 29 | strokeWidth: true 30 | }; 31 | 32 | /** 33 | * @param {string} prefix vendor-specific prefix, eg: Webkit 34 | * @param {string} key style name, eg: transitionDuration 35 | * @return {string} style name prefixed with `prefix`, properly camelCased, eg: 36 | * WebkitTransitionDuration 37 | */ 38 | function prefixKey(prefix, key) { 39 | return prefix + key.charAt(0).toUpperCase() + key.substring(1); 40 | } 41 | 42 | /** 43 | * Support style names that may come passed in prefixed by adding permutations 44 | * of vendor prefixes. 45 | */ 46 | var prefixes = ['Webkit', 'ms', 'Moz', 'O']; 47 | 48 | // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an 49 | // infinite loop, because it iterates over the newly added props too. 50 | Object.keys(isUnitlessNumber).forEach(function(prop) { 51 | prefixes.forEach(function(prefix) { 52 | isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; 53 | }); 54 | }); 55 | 56 | /** 57 | * Most style properties can be unset by doing .style[prop] = '' but IE8 58 | * doesn't like doing that with shorthand properties so for the properties that 59 | * IE8 breaks on, which are listed here, we instead unset each of the 60 | * individual properties. See http://bugs.jquery.com/ticket/12385. 61 | * The 4-value 'clock' properties like margin, padding, border-width seem to 62 | * behave without any problems. Curiously, list-style works too without any 63 | * special prodding. 64 | */ 65 | var shorthandPropertyExpansions = { 66 | background: { 67 | backgroundImage: true, 68 | backgroundPosition: true, 69 | backgroundRepeat: true, 70 | backgroundColor: true 71 | }, 72 | border: { 73 | borderWidth: true, 74 | borderStyle: true, 75 | borderColor: true 76 | }, 77 | borderBottom: { 78 | borderBottomWidth: true, 79 | borderBottomStyle: true, 80 | borderBottomColor: true 81 | }, 82 | borderLeft: { 83 | borderLeftWidth: true, 84 | borderLeftStyle: true, 85 | borderLeftColor: true 86 | }, 87 | borderRight: { 88 | borderRightWidth: true, 89 | borderRightStyle: true, 90 | borderRightColor: true 91 | }, 92 | borderTop: { 93 | borderTopWidth: true, 94 | borderTopStyle: true, 95 | borderTopColor: true 96 | }, 97 | font: { 98 | fontStyle: true, 99 | fontVariant: true, 100 | fontWeight: true, 101 | fontSize: true, 102 | lineHeight: true, 103 | fontFamily: true 104 | } 105 | }; 106 | 107 | var CSSProperty = { 108 | isUnitlessNumber: isUnitlessNumber, 109 | shorthandPropertyExpansions: shorthandPropertyExpansions 110 | }; 111 | 112 | module.exports = CSSProperty; 113 | -------------------------------------------------------------------------------- /lib/hyphenateStyleName.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var msPattern = /^ms-/; 4 | 5 | var _uppercasePattern = /([A-Z])/g; 6 | 7 | /** 8 | * Hyphenates a camelcased string, for example: 9 | * 10 | * > hyphenate('backgroundColor') 11 | * < "background-color" 12 | * 13 | * For CSS style names, use `hyphenateStyleName` instead which works properly 14 | * with all vendor prefixes, including `ms`. 15 | * 16 | * @param {string} string 17 | * @return {string} 18 | */ 19 | function hyphenate(string) { 20 | return string.replace(_uppercasePattern, '-$1').toLowerCase(); 21 | } 22 | 23 | /** 24 | * Hyphenates a camelcased CSS property name, for example: 25 | * 26 | * > hyphenateStyleName('backgroundColor') 27 | * < "background-color" 28 | * > hyphenateStyleName('MozTransition') 29 | * < "-moz-transition" 30 | * > hyphenateStyleName('msTransition') 31 | * < "-ms-transition" 32 | * 33 | * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix 34 | * is converted to `-ms-`. 35 | * 36 | * @param {string} string 37 | * @return {string} 38 | */ 39 | function hyphenateStyleName(string) { 40 | return hyphenate(string).replace(msPattern, '-ms-'); 41 | } 42 | 43 | module.exports = hyphenateStyleName; 44 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-style-object-to-css", 3 | "version": "1.1.0", 4 | "description": "Convert react style with object to inline css(string).", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/Calvin92/react-style-object-to-css.git" 12 | }, 13 | "keywords": [ 14 | "React", 15 | "CSS", 16 | "Javascript" 17 | ], 18 | "author": "Calvin92", 19 | "license": "MIT", 20 | "bugs": { 21 | "url": "https://github.com/Calvin92/react-style-object-to-css/issues" 22 | }, 23 | "homepage": "https://github.com/Calvin92/react-style-object-to-css#readme" 24 | } 25 | --------------------------------------------------------------------------------