css-to-react-native
Advanced tools
Comparing version 1.0.6 to 2.0.0
@@ -10,20 +10,29 @@ 'use strict'; | ||
/* eslint-disable no-param-reassign */ | ||
var nearley = require('nearley'); | ||
var parse = require('postcss-value-parser'); | ||
var camelizeStyleName = require('fbjs/lib/camelizeStyleName'); | ||
var grammar = require('./grammar'); | ||
var transforms = require('./transforms'); | ||
var TokenStream = require('./TokenStream'); | ||
var transforms = ['background', 'border', 'borderColor', 'borderRadius', 'borderWidth', 'flex', 'flexFlow', 'font', 'fontVariant', 'fontWeight', 'margin', 'padding', 'shadowOffset', 'textShadowOffset', 'transform']; | ||
// Note if this is wrong, you'll need to change tokenTypes.js too | ||
var numberOrLengthRe = /^([+-]?(?:\d*\.)?\d+(?:[Ee][+-]?\d+)?)(?:px)?$/; | ||
var transformRawValue = function transformRawValue(input) { | ||
return input !== '' && !isNaN(input) ? Number(input) : input; | ||
// Undocumented export | ||
var transformRawValue = exports.transformRawValue = function transformRawValue(input) { | ||
var value = input.trim().match(numberOrLengthRe); | ||
return value ? Number(value[1]) : input; | ||
}; | ||
var parseProp = exports.parseProp = function parseProp(propName, value) { | ||
return new nearley.Parser(grammar.ParserRules, propName).feed(value).results[0]; | ||
}; | ||
var getStylesForProperty = exports.getStylesForProperty = function getStylesForProperty(propName, inputValue, allowShorthand) { | ||
var value = inputValue.trim(); | ||
// Undocumented: allow ast to be passed in | ||
var propValue = void 0; | ||
var propValue = allowShorthand && transforms.indexOf(propName) !== -1 ? parseProp(propName, value) : transformRawValue(value); | ||
var isRawValue = allowShorthand === false || !(propName in transforms); | ||
if (isRawValue) { | ||
var value = typeof inputValue === 'string' ? inputValue : parse.stringify(inputValue); | ||
propValue = transformRawValue(value); | ||
} else { | ||
var ast = typeof inputValue === 'string' ? parse(inputValue.trim()) : inputValue; | ||
var tokenStream = new TokenStream(ast.nodes); | ||
propValue = transforms[propName](tokenStream); | ||
} | ||
@@ -30,0 +39,0 @@ return propValue && propValue.$merge ? propValue.$merge : _defineProperty({}, propName, propValue); |
{ | ||
"name": "css-to-react-native", | ||
"version": "1.0.6", | ||
"version": "2.0.0", | ||
"description": "Convert CSS text to a React Native stylesheet object", | ||
"main": "dist/index.js", | ||
"scripts": { | ||
"build-grammar": "nearleyc src/grammar.ne -o src/grammar.js", | ||
"build": "npm run build-grammar; babel src --ignore test.js --out-dir dist", | ||
"test": "npm run build-grammar; jest", | ||
"build": "babel src --ignore test.js --out-dir dist", | ||
"test": "jest", | ||
"test:watch": "jest --watch", | ||
"prepublish": "npm run build" | ||
@@ -38,6 +38,6 @@ }, | ||
"dependencies": { | ||
"css-color-list": "0.0.1", | ||
"css-color-keywords": "^1.0.0", | ||
"fbjs": "^0.8.5", | ||
"nearley": "^2.7.7" | ||
"postcss-value-parser": "^3.3.0" | ||
} | ||
} |
@@ -6,4 +6,4 @@ # css-to-react-native | ||
```css | ||
font-size: 18; | ||
line-height: 24; | ||
font-size: 18px; | ||
line-height: 24px; | ||
color: red; | ||
@@ -25,5 +25,5 @@ ``` | ||
```css | ||
text-shadow-offset: 10 5; | ||
text-shadow-offset: 10px 5px; | ||
font-variant: small-caps; | ||
transform: translate(10, 5) scale(5); | ||
transform: translate(10px, 5px) scale(5); | ||
``` | ||
@@ -47,4 +47,4 @@ | ||
```css | ||
font: bold 14/16 "Helvetica"; | ||
margin: 5 7 2; | ||
font: bold 14px/16px "Helvetica"; | ||
margin: 5px 7px 2px; | ||
``` | ||
@@ -73,4 +73,2 @@ | ||
`flex` does not support putting `flexBasis` before `flexGrow`. The supported syntax is `flex: <flex-grow> <flex-shrink> <flex-basis>`. | ||
# API | ||
@@ -85,5 +83,5 @@ | ||
transform([ | ||
['font', 'bold 14/16 "Helvetica"'], | ||
['margin', '5 7 2'], | ||
['border-left-width', '5'], | ||
['font', 'bold 14px/16px "Helvetica"'], | ||
['margin', '5px 7px 2px'], | ||
['border-left-width', '5px'], | ||
]); // => { fontFamily: 'Helvetica', ... } | ||
@@ -98,3 +96,3 @@ ``` | ||
getPropertyName('border-width'); // => 'borderWidth' | ||
getStylesForProperty('borderWidth', '1 0 2 0'); // => { borderTopWidth: 1, ... } | ||
getStylesForProperty('borderWidth', '1px 0px 2px 0px'); // => { borderTopWidth: 1, ... } | ||
``` | ||
@@ -105,6 +103,8 @@ | ||
```js | ||
transform([['border-radius', '50']], ['borderRadius']); | ||
transform([['border-radius', '50px']], ['borderRadius']); | ||
// { borderRadius: 50 } rather than { borderTopLeft: ... } | ||
``` | ||
This can also be done by passing a third argument, `false` to `getStylesForProperty`. | ||
## License | ||
@@ -111,0 +111,0 @@ |
/* eslint-disable no-param-reassign */ | ||
const nearley = require('nearley'); | ||
const parse = require('postcss-value-parser'); | ||
const camelizeStyleName = require('fbjs/lib/camelizeStyleName'); | ||
const grammar = require('./grammar'); | ||
const transforms = require('./transforms'); | ||
const TokenStream = require('./TokenStream'); | ||
const transforms = [ | ||
'background', | ||
'border', | ||
'borderColor', | ||
'borderRadius', | ||
'borderWidth', | ||
'flex', | ||
'flexFlow', | ||
'font', | ||
'fontVariant', | ||
'fontWeight', | ||
'margin', | ||
'padding', | ||
'shadowOffset', | ||
'textShadowOffset', | ||
'transform', | ||
]; | ||
// Note if this is wrong, you'll need to change tokenTypes.js too | ||
const numberOrLengthRe = /^([+-]?(?:\d*\.)?\d+(?:[Ee][+-]?\d+)?)(?:px)?$/; | ||
const transformRawValue = input => ( | ||
(input !== '' && !isNaN(input)) | ||
? Number(input) | ||
: input | ||
); | ||
// Undocumented export | ||
export const transformRawValue = (input) => { | ||
const value = input.trim().match(numberOrLengthRe); | ||
return value ? Number(value[1]) : input; | ||
}; | ||
export const parseProp = (propName, value) => | ||
new nearley.Parser(grammar.ParserRules, propName).feed(value).results[0]; | ||
export const getStylesForProperty = (propName, inputValue, allowShorthand) => { | ||
const value = inputValue.trim(); | ||
// Undocumented: allow ast to be passed in | ||
let propValue; | ||
const propValue = (allowShorthand && transforms.indexOf(propName) !== -1) | ||
? parseProp(propName, value) | ||
: transformRawValue(value); | ||
const isRawValue = (allowShorthand === false) || !(propName in transforms); | ||
if (isRawValue) { | ||
const value = typeof inputValue === 'string' ? inputValue : parse.stringify(inputValue); | ||
propValue = transformRawValue(value); | ||
} else { | ||
const ast = typeof inputValue === 'string' ? parse(inputValue.trim()) : inputValue; | ||
const tokenStream = new TokenStream(ast.nodes); | ||
propValue = transforms[propName](tokenStream); | ||
} | ||
@@ -40,0 +30,0 @@ return (propValue && propValue.$merge) |
/* global jest it, expect */ | ||
import transformCss, { parseProp } from '.'; | ||
import transformCss, { getStylesForProperty } from '.'; | ||
@@ -16,17 +16,25 @@ const runTest = (inputCss, expectedStyles) => { | ||
it('allows pixels in unspecialized transform', () => runTest([ | ||
['top', '0px'], | ||
], { top: 0 })); | ||
it('allows percent in unspecialized transform', () => runTest([ | ||
['top', '0%'], | ||
], { top: '0%' })); | ||
it('allows decimal values', () => { | ||
expect(parseProp('number', '0.5')).toBe(0.5); | ||
expect(parseProp('number', '1.5')).toBe(1.5); | ||
expect(parseProp('number', '10.5')).toBe(10.5); | ||
expect(parseProp('number', '100.5')).toBe(100.5); | ||
expect(parseProp('number', '-0.5')).toBe(-0.5); | ||
expect(parseProp('number', '-1.5')).toBe(-1.5); | ||
expect(parseProp('number', '-10.5')).toBe(-10.5); | ||
expect(parseProp('number', '-100.5')).toBe(-100.5); | ||
expect(parseProp('number', '.5')).toBe(0.5); | ||
expect(parseProp('number', '-.5')).toBe(-0.5); | ||
expect(getStylesForProperty('margin', '0.5px').marginTop).toBe(0.5); | ||
expect(getStylesForProperty('margin', '1.5px').marginTop).toBe(1.5); | ||
expect(getStylesForProperty('margin', '10.5px').marginTop).toBe(10.5); | ||
expect(getStylesForProperty('margin', '100.5px').marginTop).toBe(100.5); | ||
expect(getStylesForProperty('margin', '-0.5px').marginTop).toBe(-0.5); | ||
expect(getStylesForProperty('margin', '-1.5px').marginTop).toBe(-1.5); | ||
expect(getStylesForProperty('margin', '-10.5px').marginTop).toBe(-10.5); | ||
expect(getStylesForProperty('margin', '-100.5px').marginTop).toBe(-100.5); | ||
expect(getStylesForProperty('margin', '.5px').marginTop).toBe(0.5); | ||
expect(getStylesForProperty('margin', '-.5px').marginTop).toBe(-0.5); | ||
}); | ||
it('allows decimal values in transformed values', () => runTest([ | ||
['border-radius', '1.5'], | ||
['border-radius', '1.5px'], | ||
], { | ||
@@ -40,3 +48,3 @@ borderTopLeftRadius: 1.5, | ||
it('allows negative values in transformed values', () => runTest([ | ||
['border-radius', '-1.5'], | ||
['border-radius', '-1.5px'], | ||
], { | ||
@@ -49,2 +57,11 @@ borderTopLeftRadius: -1.5, | ||
it('allows percent values in transformed values', () => runTest([ | ||
['margin', '10%'], | ||
], { | ||
marginTop: '10%', | ||
marginRight: '10%', | ||
marginBottom: '10%', | ||
marginLeft: '10%', | ||
})); | ||
it('transforms strings', () => runTest([ | ||
@@ -87,7 +104,7 @@ ['color', 'red'], | ||
it('transforms shadow offsets', () => runTest([ | ||
['shadow-offset', ' 10 5'], | ||
['shadow-offset', '10px 5px'], | ||
], { shadowOffset: { width: 10, height: 5 } })); | ||
it('transforms text shadow offsets', () => runTest([ | ||
['text-shadow-offset', '10 5'], | ||
['text-shadow-offset', '10px 5px'], | ||
], { textShadowOffset: { width: 10, height: 5 } })); | ||
@@ -115,8 +132,8 @@ | ||
it('transforms translate(number, number) to translateX and translateY', () => runTest([ | ||
['transform', 'translate(2, 3)'], | ||
it('transforms translate(length, length) to translateX and translateY', () => runTest([ | ||
['transform', 'translate(2px, 3px)'], | ||
], { transform: [{ translateY: 3 }, { translateX: 2 }] })); | ||
it('transforms translate(number) to translateX and translateY', () => runTest([ | ||
['transform', 'translate(5)'], | ||
it('transforms translate(length) to translateX and translateY', () => runTest([ | ||
['transform', 'translate(5px)'], | ||
], { transform: [{ translateY: 0 }, { translateX: 5 }] })); | ||
@@ -133,15 +150,15 @@ | ||
it('transforms border shorthand', () => runTest([ | ||
['border', '2 dashed #f00'], | ||
['border', '2px dashed #f00'], | ||
], { borderWidth: 2, borderColor: '#f00', borderStyle: 'dashed' })); | ||
it('transforms border shorthand in other order', () => runTest([ | ||
['border', '#f00 2 dashed'], | ||
['border', '#f00 2px dashed'], | ||
], { borderWidth: 2, borderColor: '#f00', borderStyle: 'dashed' })); | ||
it('transforms border shorthand missing color', () => runTest([ | ||
['border', '2 dashed'], | ||
['border', '2px dashed'], | ||
], { borderWidth: 2, borderColor: 'black', borderStyle: 'dashed' })); | ||
it('transforms border shorthand missing style', () => runTest([ | ||
['border', '2 #f00'], | ||
['border', '2px #f00'], | ||
], { borderWidth: 2, borderColor: '#f00', borderStyle: 'solid' })); | ||
@@ -162,30 +179,34 @@ | ||
it('transforms border shorthand missing color & style', () => runTest([ | ||
['border', '2'], | ||
['border', '2px'], | ||
], { borderWidth: 2, borderColor: 'black', borderStyle: 'solid' })); | ||
it('transforms margin shorthands using 4 values', () => runTest([ | ||
['margin', '10 20 30 40'], | ||
['margin', '10px 20px 30px 40px'], | ||
], { marginTop: 10, marginRight: 20, marginBottom: 30, marginLeft: 40 })); | ||
it('transforms margin shorthands using 3 values', () => runTest([ | ||
['margin', '10 20 30'], | ||
['margin', '10px 20px 30px'], | ||
], { marginTop: 10, marginRight: 20, marginBottom: 30, marginLeft: 20 })); | ||
it('transforms margin shorthands using 2 values', () => runTest([ | ||
['margin', '10 20'], | ||
['margin', '10px 20px'], | ||
], { marginTop: 10, marginRight: 20, marginBottom: 10, marginLeft: 20 })); | ||
it('transforms margin shorthands using 1 value', () => runTest([ | ||
['margin', '10'], | ||
['margin', '10px'], | ||
], { marginTop: 10, marginRight: 10, marginBottom: 10, marginLeft: 10 })); | ||
it('shorthand with 1 value should override previous values', () => runTest([ | ||
['margin-top', '2'], | ||
['margin', '1'], | ||
['margin-top', '2px'], | ||
['margin', '1px'], | ||
], { marginTop: 1, marginRight: 1, marginBottom: 1, marginLeft: 1 })); | ||
it('transforms flex shorthand with 3 values', () => runTest([ | ||
['flex', '1 2 3'], | ||
['flex', '1 2 3px'], | ||
], { flexGrow: 1, flexShrink: 2, flexBasis: 3 })); | ||
it('transforms flex shorthand with 3 values in reverse order', () => runTest([ | ||
['flex', '3px 1 2'], | ||
], { flexGrow: 1, flexShrink: 2, flexBasis: 3 })); | ||
it('transforms flex shorthand with 2 values', () => runTest([ | ||
@@ -212,3 +233,3 @@ ['flex', '1 2'], | ||
it('transforms font', () => runTest([ | ||
['font', 'bold italic small-caps 16/18 "Helvetica"'], | ||
['font', 'bold italic small-caps 16px/18px "Helvetica"'], | ||
], { | ||
@@ -224,3 +245,3 @@ fontFamily: 'Helvetica', | ||
it('transforms font missing font-variant', () => runTest([ | ||
['font', 'bold italic 16/18 "Helvetica"'], | ||
['font', 'bold italic 16px/18px "Helvetica"'], | ||
], { | ||
@@ -236,3 +257,3 @@ fontFamily: 'Helvetica', | ||
it('transforms font missing font-style', () => runTest([ | ||
['font', 'bold small-caps 16/18 "Helvetica"'], | ||
['font', 'bold small-caps 16px/18px "Helvetica"'], | ||
], { | ||
@@ -248,3 +269,3 @@ fontFamily: 'Helvetica', | ||
it('transforms font missing font-weight', () => runTest([ | ||
['font', 'italic small-caps 16/18 "Helvetica"'], | ||
['font', 'italic small-caps 16px/18px "Helvetica"'], | ||
], { | ||
@@ -260,3 +281,3 @@ fontFamily: 'Helvetica', | ||
it('transforms font with font-weight normal', () => runTest([ | ||
['font', 'normal 16/18 "Helvetica"'], | ||
['font', 'normal 16px/18px "Helvetica"'], | ||
], { | ||
@@ -272,3 +293,3 @@ fontFamily: 'Helvetica', | ||
it('transforms font with font-weight and font-style normal', () => runTest([ | ||
['font', 'normal normal 16/18 "Helvetica"'], | ||
['font', 'normal normal 16px/18px "Helvetica"'], | ||
], { | ||
@@ -284,3 +305,3 @@ fontFamily: 'Helvetica', | ||
it('transforms font with no font-weight, font-style, and font-variant', () => runTest([ | ||
['font', '16/18 "Helvetica"'], | ||
['font', '16px/18px "Helvetica"'], | ||
], { | ||
@@ -296,3 +317,3 @@ fontFamily: 'Helvetica', | ||
it('omits line height if not specified', () => runTest([ | ||
['font', '16 "Helvetica"'], | ||
['font', '16px "Helvetica"'], | ||
], { | ||
@@ -306,2 +327,64 @@ fontFamily: 'Helvetica', | ||
it('allows line height as multiple', () => runTest([ | ||
['font', '16px/1.5 "Helvetica"'], | ||
], { | ||
fontFamily: 'Helvetica', | ||
fontSize: 16, | ||
fontWeight: 'normal', | ||
fontStyle: 'normal', | ||
fontVariant: [], | ||
lineHeight: 24, | ||
})); | ||
it('transforms font without quotes', () => runTest([ | ||
['font', 'bold italic small-caps 16px/18px Helvetica Neue'], | ||
], { | ||
fontFamily: 'Helvetica Neue', | ||
fontSize: 16, | ||
fontWeight: 'bold', | ||
fontStyle: 'italic', | ||
fontVariant: ['small-caps'], | ||
lineHeight: 18, | ||
})); | ||
it('transforms font-family with double quotes', () => runTest([ | ||
['font-family', '"Helvetica Neue"'], | ||
], { | ||
fontFamily: 'Helvetica Neue', | ||
})); | ||
it('transforms font-family with single quotes', () => runTest([ | ||
['font-family', '\'Helvetica Neue\''], | ||
], { | ||
fontFamily: 'Helvetica Neue', | ||
})); | ||
it('transforms font-family without quotes', () => runTest([ | ||
['font-family', 'Helvetica Neue'], | ||
], { | ||
fontFamily: 'Helvetica Neue', | ||
})); | ||
it('transforms font-family with quotes with otherwise invalid values', () => runTest([ | ||
['font-family', '"Goudy Bookletter 1911"'], | ||
], { | ||
fontFamily: 'Goudy Bookletter 1911', | ||
})); | ||
it('transforms font-family with quotes with escaped values', () => runTest([ | ||
['font-family', '"test\\A test"'], | ||
], { | ||
fontFamily: 'test\ntest', | ||
})); | ||
it('transforms font-family with quotes with escaped quote', () => runTest([ | ||
['font-family', '"test\\"test"'], | ||
], { | ||
fontFamily: 'test"test', | ||
})); | ||
it('does not transform invalid unquoted font-family', () => { | ||
expect(() => transformCss([['font-family', 'Goudy Bookletter 1911']])).toThrow(); | ||
}); | ||
it('allows blacklisting shorthands', () => { | ||
@@ -308,0 +391,0 @@ const actualStyles = transformCss([['border-radius', '50']], ['borderRadius']); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
25
1311
167269
1
+ Addedcss-color-keywords@^1.0.0
+ Addedpostcss-value-parser@^3.3.0
+ Addedcss-color-keywords@1.0.0(transitive)
+ Addedpostcss-value-parser@3.3.1(transitive)
- Removedcss-color-list@0.0.1
- Removednearley@^2.7.7
- Removedcommander@2.20.3(transitive)
- Removedcss-color-list@0.0.1(transitive)
- Removedcss-color-names@0.0.1(transitive)
- Removeddiscontinuous-range@1.0.0(transitive)
- Removedmoo@0.5.2(transitive)
- Removednearley@2.20.1(transitive)
- Removedrailroad-diagrams@1.0.0(transitive)
- Removedrandexp@0.4.6(transitive)
- Removedret@0.1.15(transitive)