taro-css-to-react-native
Advanced tools
Comparing version 2.2.16 to 3.2.0-beta.0
@@ -58,3 +58,3 @@ "use strict"; | ||
var transformShorthandValue = process.env.NODE_ENV === 'production' ? baseTransformShorthandValue : function (propName, inputValue) { | ||
var checkBaseTransformShorthandValue = function checkBaseTransformShorthandValue(propName, inputValue) { | ||
try { | ||
@@ -67,2 +67,4 @@ return baseTransformShorthandValue(propName, inputValue); | ||
var transformShorthandValue = process.env.NODE_ENV === 'production' ? baseTransformShorthandValue : checkBaseTransformShorthandValue; | ||
var getStylesForProperty = function getStylesForProperty(propName, inputValue, allowShorthand) { | ||
@@ -69,0 +71,0 @@ var isRawValue = allowShorthand === false || !(propName in _index["default"]); |
@@ -30,3 +30,3 @@ "use strict"; | ||
flexShrink: 0, | ||
flexBasis: "auto" | ||
flexBasis: 'auto' | ||
} | ||
@@ -43,3 +43,3 @@ }; | ||
flexShrink: 1, | ||
flexBasis: "auto" | ||
flexBasis: 'auto' | ||
} | ||
@@ -67,3 +67,3 @@ }; | ||
} else if (flexBasis === undefined && tokenStream.matches(AUTO)) { | ||
flexBasis = "auto"; | ||
flexBasis = 'auto'; | ||
} else { | ||
@@ -70,0 +70,0 @@ tokenStream["throw"](); |
@@ -23,4 +23,4 @@ "use strict"; | ||
var VARIANT = (0, _tokenTypes.regExpToken)(/^(small-caps)$/); | ||
var defaultFontStyle = "normal"; | ||
var defaultFontWeight = "normal"; | ||
var defaultFontStyle = 'normal'; | ||
var defaultFontWeight = 'normal'; | ||
var defaultFontVariant = []; | ||
@@ -27,0 +27,0 @@ |
@@ -53,7 +53,7 @@ "use strict"; | ||
tokens: [COLOR], | ||
"default": "black" | ||
"default": 'black' | ||
}, | ||
borderStyle: { | ||
tokens: [(0, _tokenTypes.regExpToken)(/^(solid|dashed|dotted)$/)], | ||
"default": "solid" | ||
"default": 'solid' | ||
} | ||
@@ -63,20 +63,20 @@ }); | ||
types: [WORD], | ||
prefix: "border", | ||
suffix: "Color" | ||
prefix: 'border', | ||
suffix: 'Color' | ||
}); | ||
var borderRadius = (0, _util.directionFactory)({ | ||
directions: ["TopLeft", "TopRight", "BottomRight", "BottomLeft"], | ||
prefix: "border", | ||
suffix: "Radius" | ||
directions: ['TopLeft', 'TopRight', 'BottomRight', 'BottomLeft'], | ||
prefix: 'border', | ||
suffix: 'Radius' | ||
}); | ||
var borderWidth = (0, _util.directionFactory)({ | ||
prefix: "border", | ||
suffix: "Width" | ||
prefix: 'border', | ||
suffix: 'Width' | ||
}); | ||
var margin = (0, _util.directionFactory)({ | ||
types: [LENGTH, UNSUPPORTED_LENGTH_UNIT, PERCENT, AUTO], | ||
prefix: "margin" | ||
prefix: 'margin' | ||
}); | ||
var padding = (0, _util.directionFactory)({ | ||
prefix: "padding" | ||
prefix: 'padding' | ||
}); | ||
@@ -86,7 +86,7 @@ var flexFlow = (0, _util.anyOrderFactory)({ | ||
tokens: [(0, _tokenTypes.regExpToken)(/(nowrap|wrap|wrap-reverse)/)], | ||
"default": "nowrap" | ||
"default": 'nowrap' | ||
}, | ||
flexDirection: { | ||
tokens: [(0, _tokenTypes.regExpToken)(/(row|row-reverse|column|column-reverse)/)], | ||
"default": "row" | ||
"default": 'row' | ||
} | ||
@@ -93,0 +93,0 @@ }); |
@@ -14,5 +14,5 @@ "use strict"; | ||
var STYLE = (0, _tokenTypes.regExpToken)(/^(solid|double|dotted|dashed)$/); | ||
var defaultTextDecorationLine = "none"; | ||
var defaultTextDecorationStyle = "solid"; | ||
var defaultTextDecorationColor = "black"; | ||
var defaultTextDecorationLine = 'none'; | ||
var defaultTextDecorationStyle = 'solid'; | ||
var defaultTextDecorationColor = 'black'; | ||
@@ -32,3 +32,3 @@ var _default = function _default(tokenStream) { | ||
if (lines[0] !== "none" && tokenStream.matches(SPACE) && tokenStream.matches(LINE)) { | ||
if (lines[0] !== 'none' && tokenStream.matches(SPACE) && tokenStream.matches(LINE)) { | ||
lines.push(tokenStream.lastValue.toLowerCase()); // Underline comes before line-through | ||
@@ -41,3 +41,3 @@ | ||
line = lines.join(" "); | ||
line = lines.join(' '); | ||
} else if (style === undefined && tokenStream.matches(STYLE)) { | ||
@@ -44,0 +44,0 @@ style = tokenStream.lastValue; |
@@ -24,5 +24,5 @@ "use strict"; | ||
lines.sort().reverse(); | ||
return lines.join(" "); | ||
return lines.join(' '); | ||
}; | ||
exports["default"] = _default; |
@@ -58,6 +58,6 @@ "use strict"; | ||
perspective: singleNumber, | ||
scale: xyNumber("scale"), | ||
scale: xyNumber('scale'), | ||
scaleX: singleNumber, | ||
scaleY: singleNumber, | ||
translate: xyLength("translate", 0), | ||
translate: xyLength('translate', 0), | ||
translateX: singleLength, | ||
@@ -71,3 +71,3 @@ translateY: singleLength, | ||
skewY: singleAngle, | ||
skew: xyAngle("skew", "0deg") | ||
skew: xyAngle('skew', '0deg') | ||
}; | ||
@@ -74,0 +74,0 @@ |
@@ -35,7 +35,7 @@ "use strict"; | ||
_ref$directions = _ref.directions, | ||
directions = _ref$directions === void 0 ? ["Top", "Right", "Bottom", "Left"] : _ref$directions, | ||
directions = _ref$directions === void 0 ? ['Top', 'Right', 'Bottom', 'Left'] : _ref$directions, | ||
_ref$prefix = _ref.prefix, | ||
prefix = _ref$prefix === void 0 ? "" : _ref$prefix, | ||
prefix = _ref$prefix === void 0 ? '' : _ref$prefix, | ||
_ref$suffix = _ref.suffix, | ||
suffix = _ref$suffix === void 0 ? "" : _ref$suffix; | ||
suffix = _ref$suffix === void 0 ? '' : _ref$suffix; | ||
return function (tokenStream) { | ||
@@ -105,3 +105,5 @@ var _output; | ||
propertyNames.forEach(function (propertyName) { | ||
if (values[propertyName] === undefined) values[propertyName] = properties[propertyName]["default"]; | ||
if (values[propertyName] === undefined) { | ||
values[propertyName] = properties[propertyName]["default"]; | ||
} | ||
}); | ||
@@ -144,3 +146,3 @@ return { | ||
radius: 0, | ||
color: "black" | ||
color: 'black' | ||
}; | ||
@@ -181,3 +183,3 @@ } | ||
radius: radius !== undefined ? radius : 0, | ||
color: color !== undefined ? color : "black" | ||
color: color !== undefined ? color : 'black' | ||
}; | ||
@@ -184,0 +186,0 @@ }; |
@@ -6,2 +6,8 @@ "use strict"; | ||
}); | ||
Object.defineProperty(exports, "transformCSS", { | ||
enumerable: true, | ||
get: function get() { | ||
return _cssToReactNative["default"]; | ||
} | ||
}); | ||
exports["default"] = void 0; | ||
@@ -35,8 +41,8 @@ | ||
var unsupportedUnitRe = /^([+-]?(?:\d*\.)?\d+(?:[Ee][+-]?\d+)?(ch|em|ex|cm|mm|in|pc|pt))$/; | ||
var shorthandBorderProps = ["border-radius", "border-width", "border-color", "border-style"]; | ||
var shorthandBorderProps = ['border-radius', 'border-width', 'border-color', 'border-style']; | ||
var transformDecls = function transformDecls(styles, declarations, result) { | ||
var transformDecls = function transformDecls(styles, declarations, result, options) { | ||
for (var d in declarations) { | ||
var declaration = declarations[d]; | ||
if (declaration.type !== "declaration") continue; | ||
if (declaration.type !== 'declaration') continue; | ||
var property = declaration.property; | ||
@@ -49,3 +55,3 @@ var value = (0, _rem.remToPx)(declaration.value); | ||
if (property === "line-height" && !isLengthUnit && !isViewportUnit && !isPercent && !isUnsupportedUnit) { | ||
if (property === 'line-height' && !isLengthUnit && !isViewportUnit && !isPercent && !isUnsupportedUnit) { | ||
throw new Error("Failed to parse declaration \"".concat(property, ": ").concat(value, "\"")); | ||
@@ -56,2 +62,8 @@ } | ||
result.__viewportUnits = true; | ||
} // scalable option, when it is false, transform single value 'px' unit to 'PX' | ||
// do not be wrapped by scalePx2dp function | ||
if (!options.scalable && isLengthUnit && /px/.test(value)) { | ||
value = value.replace(/px/g, 'PX'); | ||
} | ||
@@ -89,3 +101,3 @@ | ||
for (var s in rule.selectors) { | ||
if (rule.selectors[s] === ":export") { | ||
if (rule.selectors[s] === ':export') { | ||
if (!result.__exportProps) { | ||
@@ -109,12 +121,12 @@ result.__exportProps = {}; | ||
if (rule.selectors[s].indexOf(".") !== 0 || rule.selectors[s].indexOf(":") !== -1 || rule.selectors[s].indexOf("[") !== -1 || rule.selectors[s].indexOf("~") !== -1 || rule.selectors[s].indexOf(">") !== -1 || rule.selectors[s].indexOf("+") !== -1 || rule.selectors[s].indexOf(" ") !== -1) { | ||
if (rule.selectors[s].indexOf('.') !== 0 || rule.selectors[s].indexOf(':') !== -1 || rule.selectors[s].indexOf('[') !== -1 || rule.selectors[s].indexOf('~') !== -1 || rule.selectors[s].indexOf('>') !== -1 || rule.selectors[s].indexOf('+') !== -1 || rule.selectors[s].indexOf(' ') !== -1) { | ||
continue; | ||
} | ||
var selector = rule.selectors[s].replace(/^\./, ""); | ||
var selector = rule.selectors[s].replace(/^\./, ''); | ||
var styles = result[selector] = result[selector] || {}; | ||
transformDecls(styles, rule.declarations, result); | ||
transformDecls(styles, rule.declarations, result, options); | ||
} | ||
if (rule.type == "media" && options != null && options.parseMediaQueries === true) { | ||
if (rule.type === 'media' && options != null && options.parseMediaQueries === true) { | ||
var parsed = _cssMediaquery["default"].parse(rule.media); | ||
@@ -129,3 +141,3 @@ | ||
var mf = e.modifier ? "".concat(e.modifier, "-").concat(e.feature) : e.feature; | ||
var val = e.value ? ": ".concat(e.value) : ""; | ||
var val = e.value ? ": ".concat(e.value) : ''; | ||
@@ -141,3 +153,3 @@ if (_features.mediaQueryFeatures.indexOf(e.feature) === -1) { | ||
}); | ||
var media = "@media " + rule.media; | ||
var media = '@media ' + rule.media; | ||
result.__mediaQueries = result.__mediaQueries || {}; | ||
@@ -152,6 +164,6 @@ result.__mediaQueries[media] = parsed; | ||
var _selector = ruleRule.selectors[_s].replace(/^\./, ""); | ||
var _selector = ruleRule.selectors[_s].replace(/^\./, ''); | ||
var mediaStyles = result[media][_selector] = result[media][_selector] || {}; | ||
transformDecls(mediaStyles, ruleRule.declarations, result); | ||
transformDecls(mediaStyles, ruleRule.declarations, result, options); | ||
} | ||
@@ -158,0 +170,0 @@ } |
@@ -7,5 +7,5 @@ "use strict"; | ||
exports.mediaQueryFeatures = exports.dimensionFeatures = void 0; | ||
var dimensionFeatures = ["width", "height", "device-width", "device-height"]; | ||
var dimensionFeatures = ['width', 'height', 'device-width', 'device-height']; | ||
exports.dimensionFeatures = dimensionFeatures; | ||
var mediaQueryFeatures = ["orientation", "scan", "resolution", "aspect-ratio", "device-aspect-ratio", "grid", "color", "color-index", "monochrome"].concat(dimensionFeatures); | ||
var mediaQueryFeatures = ['orientation', 'scan', 'resolution', 'aspect-ratio', 'device-aspect-ratio', 'grid', 'color', 'color-index', 'monochrome'].concat(dimensionFeatures); | ||
exports.mediaQueryFeatures = mediaQueryFeatures; |
@@ -7,9 +7,9 @@ "use strict"; | ||
exports.mediaQueryTypes = exports.reactNativeMediaQueryTypes = exports.cssnextMediaQueryTypes = exports.defaultTypes = void 0; | ||
var defaultTypes = ["all", "braille", "embossed", "handheld", "print", "projection", "screen", "speech", "tty", "tv"]; | ||
var defaultTypes = ['all', 'braille', 'embossed', 'handheld', 'print', 'projection', 'screen', 'speech', 'tty', 'tv']; | ||
exports.defaultTypes = defaultTypes; | ||
var cssnextMediaQueryTypes = ["pointer", "hover", "block-overflow"]; | ||
var cssnextMediaQueryTypes = ['pointer', 'hover', 'block-overflow']; | ||
exports.cssnextMediaQueryTypes = cssnextMediaQueryTypes; | ||
var reactNativeMediaQueryTypes = ["android", "dom", "ios", "macos", "web", "windows"]; | ||
var reactNativeMediaQueryTypes = ['android', 'dom', 'ios', 'macos', 'web', 'windows']; | ||
exports.reactNativeMediaQueryTypes = reactNativeMediaQueryTypes; | ||
var mediaQueryTypes = defaultTypes.concat(cssnextMediaQueryTypes).concat(reactNativeMediaQueryTypes); | ||
exports.mediaQueryTypes = mediaQueryTypes; |
export default function transform(css: string, options?: { | ||
parseMediaQueries?: boolean; | ||
}): { [selector: string]: unknown; }; | ||
parseMediaQueries?: boolean; | ||
scalable?: boolean; | ||
}): { [selector: string]: unknown; } | ||
export declare function transformCSS(rules: Array<any[]>, shorthandBlacklist?: Array<{ [key: string]: any }>): { [key: string]: any }; |
{ | ||
"name": "taro-css-to-react-native", | ||
"description": "Convert CSS text to a React Native stylesheet object", | ||
"version": "2.2.16", | ||
"version": "3.2.0-beta.0", | ||
"main": "dist/index.js", | ||
"license": "MIT", | ||
"dependencies": { | ||
"camelize": "^1.0.0", | ||
"css": "^2.2.4", | ||
"css-color-keywords": "^1.0.0", | ||
"css-mediaquery": "^0.1.2", | ||
"postcss-value-parser": "^3.3.0" | ||
}, | ||
"scripts": { | ||
"prettify": "prettier --write '**/*.@(js|json|md)'", | ||
"precommit": "lint-staged", | ||
"build": "babel src --ignore *.spec.js --out-dir dist", | ||
"test": "jest --coverage", | ||
"prepublish": "npm run build", | ||
"release": "npmpub" | ||
"build": "babel src --ignore *.spec.js --out-dir ./dist", | ||
"test": "jest" | ||
}, | ||
"devDependencies": { | ||
"@babel/cli": "^7.2.3", | ||
"@babel/core": "^7.3.4", | ||
"@babel/preset-env": "^7.3.4", | ||
"babel-jest": "^24.3.1", | ||
"coveralls": "^3.0.3", | ||
"husky": "^1.3.1", | ||
"jest": "^24.3.1", | ||
"lint-staged": "^8.1.5", | ||
"npmpub": "^4.1.0", | ||
"prettier": "^1.16.4" | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/NervJS/taro.git" | ||
}, | ||
"keywords": [ | ||
"React", | ||
"ReactNative", | ||
"styles", | ||
"CSS" | ||
], | ||
"jest": { | ||
@@ -58,19 +59,2 @@ "transform": { | ||
}, | ||
"dependencies": { | ||
"camelize": "^1.0.0", | ||
"css": "^2.2.4", | ||
"css-color-keywords": "^1.0.0", | ||
"css-mediaquery": "^0.1.2", | ||
"postcss-value-parser": "^3.3.0" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/NervJS/taro.git" | ||
}, | ||
"keywords": [ | ||
"React", | ||
"ReactNative", | ||
"styles", | ||
"CSS" | ||
], | ||
"files": [ | ||
@@ -83,3 +67,3 @@ "dist", | ||
], | ||
"gitHead": "835ce2ad35a1d8e6f24b5c6c315bbef607223c4a" | ||
"gitHead": "2b734bbdae643a14d6c046d658a74292702be570" | ||
} |
@@ -46,25 +46,19 @@ /* eslint-disable no-param-reassign */ | ||
const checkBaseTransformShorthandValue = (propName, inputValue) => { | ||
try { | ||
return baseTransformShorthandValue(propName, inputValue) | ||
} catch (e) { | ||
throw new Error(`${e.message} Failed to parse declaration "${propName}: ${inputValue}"`) | ||
} | ||
} | ||
const transformShorthandValue = | ||
process.env.NODE_ENV === 'production' | ||
? baseTransformShorthandValue | ||
: (propName, inputValue) => { | ||
try { | ||
return baseTransformShorthandValue(propName, inputValue) | ||
} catch (e) { | ||
throw new Error( | ||
`${ | ||
e.message | ||
} Failed to parse declaration "${propName}: ${inputValue}"` | ||
) | ||
} | ||
} | ||
: checkBaseTransformShorthandValue | ||
export const getStylesForProperty = (propName, inputValue, allowShorthand) => { | ||
const isRawValue = allowShorthand === false || !(propName in transforms) | ||
const propValue = isRawValue | ||
? transformRawValue(inputValue) | ||
: transformShorthandValue(propName, inputValue.trim()) | ||
return propValue && propValue.$merge | ||
? propValue.$merge | ||
: { [propName]: propValue } | ||
const propValue = isRawValue ? transformRawValue(inputValue) : transformShorthandValue(propName, inputValue.trim()) | ||
return propValue && propValue.$merge ? propValue.$merge : { [propName]: propValue } | ||
} | ||
@@ -85,6 +79,3 @@ | ||
const allowShorthand = shorthandBlacklist.indexOf(propertyName) === -1 | ||
return Object.assign( | ||
accum, | ||
getStylesForProperty(propertyName, value, allowShorthand) | ||
) | ||
return Object.assign(accum, getStylesForProperty(propertyName, value, allowShorthand)) | ||
}, {}) |
@@ -7,5 +7,3 @@ import { stringify } from 'postcss-value-parser' | ||
return node.value | ||
.replace(/\\([0-9a-f]{1,6})(?:\s|$)/gi, (match, charCode) => | ||
String.fromCharCode(parseInt(charCode, 16)) | ||
) | ||
.replace(/\\([0-9a-f]{1,6})(?:\s|$)/gi, (match, charCode) => String.fromCharCode(parseInt(charCode, 16))) | ||
.replace(/\\/g, '') | ||
@@ -20,5 +18,3 @@ } | ||
node.type === 'word' && | ||
(hexColorRe.test(node.value) || | ||
node.value in cssColorKeywords || | ||
node.value === 'transparent') | ||
(hexColorRe.test(node.value) || node.value in cssColorKeywords || node.value === 'transparent') | ||
) { | ||
@@ -45,4 +41,3 @@ return node.value | ||
const valueForTypeToken = type => node => | ||
node.type === type ? node.value : null | ||
const valueForTypeToken = type => node => (node.type === type ? node.value : null) | ||
@@ -49,0 +44,0 @@ export const regExpToken = (regExp, transform = String) => node => { |
@@ -1,5 +0,5 @@ | ||
import { parseShadow } from "./util"; | ||
import { parseShadow } from './util' | ||
export default tokenStream => { | ||
const { offset, radius, color } = parseShadow(tokenStream); | ||
const { offset, radius, color } = parseShadow(tokenStream) | ||
return { | ||
@@ -10,5 +10,5 @@ $merge: { | ||
shadowColor: color, | ||
shadowOpacity: 1, | ||
}, | ||
}; | ||
}; | ||
shadowOpacity: 1 | ||
} | ||
} | ||
} |
@@ -1,56 +0,56 @@ | ||
import { tokens } from "../tokenTypes"; | ||
import { tokens } from '../tokenTypes' | ||
const { NONE, AUTO, NUMBER, LENGTH, SPACE } = tokens; | ||
const { NONE, AUTO, NUMBER, LENGTH, SPACE } = tokens | ||
const defaultFlexGrow = 1; | ||
const defaultFlexShrink = 1; | ||
const defaultFlexBasis = 0; | ||
const defaultFlexGrow = 1 | ||
const defaultFlexShrink = 1 | ||
const defaultFlexBasis = 0 | ||
export default tokenStream => { | ||
let flexGrow; | ||
let flexShrink; | ||
let flexBasis; | ||
let flexGrow | ||
let flexShrink | ||
let flexBasis | ||
if (tokenStream.matches(NONE)) { | ||
tokenStream.expectEmpty(); | ||
return { $merge: { flexGrow: 0, flexShrink: 0, flexBasis: "auto" } }; | ||
tokenStream.expectEmpty() | ||
return { $merge: { flexGrow: 0, flexShrink: 0, flexBasis: 'auto' } } | ||
} | ||
tokenStream.saveRewindPoint(); | ||
tokenStream.saveRewindPoint() | ||
if (tokenStream.matches(AUTO) && !tokenStream.hasTokens()) { | ||
return { $merge: { flexGrow: 1, flexShrink: 1, flexBasis: "auto" } }; | ||
return { $merge: { flexGrow: 1, flexShrink: 1, flexBasis: 'auto' } } | ||
} | ||
tokenStream.rewind(); | ||
tokenStream.rewind() | ||
let partsParsed = 0; | ||
let partsParsed = 0 | ||
while (partsParsed < 2 && tokenStream.hasTokens()) { | ||
if (partsParsed !== 0) tokenStream.expect(SPACE); | ||
if (partsParsed !== 0) tokenStream.expect(SPACE) | ||
if (flexGrow === undefined && tokenStream.matches(NUMBER)) { | ||
flexGrow = tokenStream.lastValue; | ||
flexGrow = tokenStream.lastValue | ||
tokenStream.saveRewindPoint(); | ||
tokenStream.saveRewindPoint() | ||
if (tokenStream.matches(SPACE) && tokenStream.matches(NUMBER)) { | ||
flexShrink = tokenStream.lastValue; | ||
flexShrink = tokenStream.lastValue | ||
} else { | ||
tokenStream.rewind(); | ||
tokenStream.rewind() | ||
} | ||
} else if (flexBasis === undefined && tokenStream.matches(LENGTH)) { | ||
flexBasis = tokenStream.lastValue; | ||
flexBasis = tokenStream.lastValue | ||
} else if (flexBasis === undefined && tokenStream.matches(AUTO)) { | ||
flexBasis = "auto"; | ||
flexBasis = 'auto' | ||
} else { | ||
tokenStream.throw(); | ||
tokenStream.throw() | ||
} | ||
partsParsed += 1; | ||
partsParsed += 1 | ||
} | ||
tokenStream.expectEmpty(); | ||
tokenStream.expectEmpty() | ||
if (flexGrow === undefined) flexGrow = defaultFlexGrow; | ||
if (flexShrink === undefined) flexShrink = defaultFlexShrink; | ||
if (flexBasis === undefined) flexBasis = defaultFlexBasis; | ||
if (flexGrow === undefined) flexGrow = defaultFlexGrow | ||
if (flexShrink === undefined) flexShrink = defaultFlexShrink | ||
if (flexBasis === undefined) flexBasis = defaultFlexBasis | ||
return { $merge: { flexGrow, flexShrink, flexBasis } }; | ||
}; | ||
return { $merge: { flexGrow, flexShrink, flexBasis } } | ||
} |
@@ -1,23 +0,23 @@ | ||
import parseFontFamily from "./fontFamily"; | ||
import { regExpToken, tokens } from "../tokenTypes"; | ||
import parseFontFamily from './fontFamily' | ||
import { regExpToken, tokens } from '../tokenTypes' | ||
const { SPACE, LENGTH, UNSUPPORTED_LENGTH_UNIT, NUMBER, SLASH } = tokens; | ||
const NORMAL = regExpToken(/^(normal)$/); | ||
const STYLE = regExpToken(/^(italic)$/); | ||
const WEIGHT = regExpToken(/^([1-9]00|bold)$/); | ||
const VARIANT = regExpToken(/^(small-caps)$/); | ||
const { SPACE, LENGTH, UNSUPPORTED_LENGTH_UNIT, NUMBER, SLASH } = tokens | ||
const NORMAL = regExpToken(/^(normal)$/) | ||
const STYLE = regExpToken(/^(italic)$/) | ||
const WEIGHT = regExpToken(/^([1-9]00|bold)$/) | ||
const VARIANT = regExpToken(/^(small-caps)$/) | ||
const defaultFontStyle = "normal"; | ||
const defaultFontWeight = "normal"; | ||
const defaultFontVariant = []; | ||
const defaultFontStyle = 'normal' | ||
const defaultFontWeight = 'normal' | ||
const defaultFontVariant = [] | ||
export default tokenStream => { | ||
let fontStyle; | ||
let fontWeight; | ||
let fontVariant; | ||
let fontStyle | ||
let fontWeight | ||
let fontVariant | ||
// let fontSize; | ||
let lineHeight; | ||
let lineHeight | ||
// let fontFamily; | ||
let numStyleWeightVariantMatched = 0; | ||
let numStyleWeightVariantMatched = 0 | ||
while (numStyleWeightVariantMatched < 3 && tokenStream.hasTokens()) { | ||
@@ -27,37 +27,37 @@ if (tokenStream.matches(NORMAL)) { | ||
} else if (fontStyle === undefined && tokenStream.matches(STYLE)) { | ||
fontStyle = tokenStream.lastValue; | ||
fontStyle = tokenStream.lastValue | ||
} else if (fontWeight === undefined && tokenStream.matches(WEIGHT)) { | ||
fontWeight = tokenStream.lastValue; | ||
fontWeight = tokenStream.lastValue | ||
} else if (fontVariant === undefined && tokenStream.matches(VARIANT)) { | ||
fontVariant = [tokenStream.lastValue]; | ||
fontVariant = [tokenStream.lastValue] | ||
} else { | ||
break; | ||
break | ||
} | ||
tokenStream.expect(SPACE); | ||
numStyleWeightVariantMatched += 1; | ||
tokenStream.expect(SPACE) | ||
numStyleWeightVariantMatched += 1 | ||
} | ||
const fontSize = tokenStream.expect(LENGTH, UNSUPPORTED_LENGTH_UNIT); | ||
const fontSize = tokenStream.expect(LENGTH, UNSUPPORTED_LENGTH_UNIT) | ||
if (tokenStream.matches(SLASH)) { | ||
if (tokenStream.matches(NUMBER)) { | ||
lineHeight = fontSize * tokenStream.lastValue; | ||
lineHeight = fontSize * tokenStream.lastValue | ||
} else { | ||
lineHeight = tokenStream.expect(LENGTH, UNSUPPORTED_LENGTH_UNIT); | ||
lineHeight = tokenStream.expect(LENGTH, UNSUPPORTED_LENGTH_UNIT) | ||
} | ||
} | ||
tokenStream.expect(SPACE); | ||
tokenStream.expect(SPACE) | ||
const fontFamily = parseFontFamily(tokenStream); | ||
const fontFamily = parseFontFamily(tokenStream) | ||
if (fontStyle === undefined) fontStyle = defaultFontStyle; | ||
if (fontWeight === undefined) fontWeight = defaultFontWeight; | ||
if (fontVariant === undefined) fontVariant = defaultFontVariant; | ||
if (fontStyle === undefined) fontStyle = defaultFontStyle | ||
if (fontWeight === undefined) fontWeight = defaultFontWeight | ||
if (fontVariant === undefined) fontVariant = defaultFontVariant | ||
const out = { fontStyle, fontWeight, fontVariant, fontSize, fontFamily }; | ||
if (lineHeight !== undefined) out.lineHeight = lineHeight; | ||
const out = { fontStyle, fontWeight, fontVariant, fontSize, fontFamily } | ||
if (lineHeight !== undefined) out.lineHeight = lineHeight | ||
return { $merge: out }; | ||
}; | ||
return { $merge: out } | ||
} |
@@ -1,22 +0,22 @@ | ||
import { tokens } from "../tokenTypes"; | ||
import { tokens } from '../tokenTypes' | ||
const { SPACE, IDENT, STRING } = tokens; | ||
const { SPACE, IDENT, STRING } = tokens | ||
export default tokenStream => { | ||
let fontFamily; | ||
let fontFamily | ||
if (tokenStream.matches(STRING)) { | ||
fontFamily = tokenStream.lastValue; | ||
fontFamily = tokenStream.lastValue | ||
} else { | ||
fontFamily = tokenStream.expect(IDENT); | ||
fontFamily = tokenStream.expect(IDENT) | ||
while (tokenStream.hasTokens()) { | ||
tokenStream.expect(SPACE); | ||
const nextIdent = tokenStream.expect(IDENT); | ||
fontFamily += ` ${nextIdent}`; | ||
tokenStream.expect(SPACE) | ||
const nextIdent = tokenStream.expect(IDENT) | ||
fontFamily += ` ${nextIdent}` | ||
} | ||
} | ||
tokenStream.expectEmpty(); | ||
tokenStream.expectEmpty() | ||
return fontFamily; | ||
}; | ||
return fontFamily | ||
} |
@@ -1,11 +0,11 @@ | ||
import { regExpToken, tokens } from "../tokenTypes"; | ||
import boxShadow from "./boxShadow"; | ||
import flex from "./flex"; | ||
import font from "./font"; | ||
import fontFamily from "./fontFamily"; | ||
import textShadow from "./textShadow"; | ||
import textDecoration from "./textDecoration"; | ||
import textDecorationLine from "./textDecorationLine"; | ||
import transform from "./transform"; | ||
import { directionFactory, anyOrderFactory, shadowOffsetFactory } from "./util"; | ||
import { regExpToken, tokens } from '../tokenTypes' | ||
import boxShadow from './boxShadow' | ||
import flex from './flex' | ||
import font from './font' | ||
import fontFamily from './fontFamily' | ||
import textShadow from './textShadow' | ||
import textDecoration from './textDecoration' | ||
import textDecorationLine from './textDecorationLine' | ||
import transform from './transform' | ||
import { directionFactory, anyOrderFactory, shadowOffsetFactory } from './util' | ||
@@ -19,52 +19,52 @@ const { | ||
PERCENT, | ||
AUTO, | ||
} = tokens; | ||
AUTO | ||
} = tokens | ||
const background = tokenStream => ({ | ||
$merge: { backgroundColor: tokenStream.expect(COLOR) }, | ||
}); | ||
$merge: { backgroundColor: tokenStream.expect(COLOR) } | ||
}) | ||
const border = anyOrderFactory({ | ||
borderWidth: { | ||
tokens: [LENGTH, UNSUPPORTED_LENGTH_UNIT], | ||
default: 1, | ||
default: 1 | ||
}, | ||
borderColor: { | ||
tokens: [COLOR], | ||
default: "black", | ||
default: 'black' | ||
}, | ||
borderStyle: { | ||
tokens: [regExpToken(/^(solid|dashed|dotted)$/)], | ||
default: "solid", | ||
}, | ||
}); | ||
default: 'solid' | ||
} | ||
}) | ||
const borderColor = directionFactory({ | ||
types: [WORD], | ||
prefix: "border", | ||
suffix: "Color", | ||
}); | ||
prefix: 'border', | ||
suffix: 'Color' | ||
}) | ||
const borderRadius = directionFactory({ | ||
directions: ["TopLeft", "TopRight", "BottomRight", "BottomLeft"], | ||
prefix: "border", | ||
suffix: "Radius", | ||
}); | ||
const borderWidth = directionFactory({ prefix: "border", suffix: "Width" }); | ||
directions: ['TopLeft', 'TopRight', 'BottomRight', 'BottomLeft'], | ||
prefix: 'border', | ||
suffix: 'Radius' | ||
}) | ||
const borderWidth = directionFactory({ prefix: 'border', suffix: 'Width' }) | ||
const margin = directionFactory({ | ||
types: [LENGTH, UNSUPPORTED_LENGTH_UNIT, PERCENT, AUTO], | ||
prefix: "margin", | ||
}); | ||
const padding = directionFactory({ prefix: "padding" }); | ||
prefix: 'margin' | ||
}) | ||
const padding = directionFactory({ prefix: 'padding' }) | ||
const flexFlow = anyOrderFactory({ | ||
flexWrap: { | ||
tokens: [regExpToken(/(nowrap|wrap|wrap-reverse)/)], | ||
default: "nowrap", | ||
default: 'nowrap' | ||
}, | ||
flexDirection: { | ||
tokens: [regExpToken(/(row|row-reverse|column|column-reverse)/)], | ||
default: "row", | ||
}, | ||
}); | ||
const fontVariant = tokenStream => [tokenStream.expect(IDENT)]; | ||
const fontWeight = tokenStream => tokenStream.expect(WORD); // Also match numbers as strings | ||
const shadowOffset = shadowOffsetFactory(); | ||
const textShadowOffset = shadowOffsetFactory(); | ||
default: 'row' | ||
} | ||
}) | ||
const fontVariant = tokenStream => [tokenStream.expect(IDENT)] | ||
const fontWeight = tokenStream => tokenStream.expect(WORD) // Also match numbers as strings | ||
const shadowOffset = shadowOffsetFactory() | ||
const textShadowOffset = shadowOffsetFactory() | ||
@@ -91,3 +91,3 @@ export default { | ||
textDecorationLine, | ||
transform, | ||
}; | ||
transform | ||
} |
@@ -1,46 +0,46 @@ | ||
import { regExpToken, tokens } from "../tokenTypes"; | ||
import { regExpToken, tokens } from '../tokenTypes' | ||
const { SPACE, LINE, COLOR } = tokens; | ||
const { SPACE, LINE, COLOR } = tokens | ||
const STYLE = regExpToken(/^(solid|double|dotted|dashed)$/); | ||
const STYLE = regExpToken(/^(solid|double|dotted|dashed)$/) | ||
const defaultTextDecorationLine = "none"; | ||
const defaultTextDecorationStyle = "solid"; | ||
const defaultTextDecorationColor = "black"; | ||
const defaultTextDecorationLine = 'none' | ||
const defaultTextDecorationStyle = 'solid' | ||
const defaultTextDecorationColor = 'black' | ||
export default tokenStream => { | ||
let line; | ||
let style; | ||
let color; | ||
let line | ||
let style | ||
let color | ||
let didParseFirst = false; | ||
let didParseFirst = false | ||
while (tokenStream.hasTokens()) { | ||
if (didParseFirst) tokenStream.expect(SPACE); | ||
if (didParseFirst) tokenStream.expect(SPACE) | ||
if (line === undefined && tokenStream.matches(LINE)) { | ||
const lines = [tokenStream.lastValue.toLowerCase()]; | ||
const lines = [tokenStream.lastValue.toLowerCase()] | ||
tokenStream.saveRewindPoint(); | ||
tokenStream.saveRewindPoint() | ||
if ( | ||
lines[0] !== "none" && | ||
lines[0] !== 'none' && | ||
tokenStream.matches(SPACE) && | ||
tokenStream.matches(LINE) | ||
) { | ||
lines.push(tokenStream.lastValue.toLowerCase()); | ||
lines.push(tokenStream.lastValue.toLowerCase()) | ||
// Underline comes before line-through | ||
lines.sort().reverse(); | ||
lines.sort().reverse() | ||
} else { | ||
tokenStream.rewind(); | ||
tokenStream.rewind() | ||
} | ||
line = lines.join(" "); | ||
line = lines.join(' ') | ||
} else if (style === undefined && tokenStream.matches(STYLE)) { | ||
style = tokenStream.lastValue; | ||
style = tokenStream.lastValue | ||
} else if (color === undefined && tokenStream.matches(COLOR)) { | ||
color = tokenStream.lastValue; | ||
color = tokenStream.lastValue | ||
} else { | ||
tokenStream.throw(); | ||
tokenStream.throw() | ||
} | ||
didParseFirst = true; | ||
didParseFirst = true | ||
} | ||
@@ -53,5 +53,5 @@ | ||
textDecorationStyle: | ||
style !== undefined ? style : defaultTextDecorationStyle, | ||
}; | ||
return { $merge }; | ||
}; | ||
style !== undefined ? style : defaultTextDecorationStyle | ||
} | ||
return { $merge } | ||
} |
@@ -1,20 +0,20 @@ | ||
import { tokens } from "../tokenTypes"; | ||
import { tokens } from '../tokenTypes' | ||
const { SPACE, LINE } = tokens; | ||
const { SPACE, LINE } = tokens | ||
export default tokenStream => { | ||
const lines = []; | ||
const lines = [] | ||
let didParseFirst = false; | ||
let didParseFirst = false | ||
while (tokenStream.hasTokens()) { | ||
if (didParseFirst) tokenStream.expect(SPACE); | ||
if (didParseFirst) tokenStream.expect(SPACE) | ||
lines.push(tokenStream.expect(LINE).toLowerCase()); | ||
lines.push(tokenStream.expect(LINE).toLowerCase()) | ||
didParseFirst = true; | ||
didParseFirst = true | ||
} | ||
lines.sort().reverse(); | ||
lines.sort().reverse() | ||
return lines.join(" "); | ||
}; | ||
return lines.join(' ') | ||
} |
@@ -1,5 +0,5 @@ | ||
import { parseShadow } from "./util"; | ||
import { parseShadow } from './util' | ||
export default tokenStream => { | ||
const { offset, radius, color } = parseShadow(tokenStream); | ||
const { offset, radius, color } = parseShadow(tokenStream) | ||
return { | ||
@@ -9,5 +9,5 @@ $merge: { | ||
textShadowRadius: radius, | ||
textShadowColor: color, | ||
}, | ||
}; | ||
}; | ||
textShadowColor: color | ||
} | ||
} | ||
} |
@@ -1,46 +0,46 @@ | ||
import { tokens } from "../tokenTypes"; | ||
import { tokens } from '../tokenTypes' | ||
const { SPACE, COMMA, LENGTH, NUMBER, ANGLE } = tokens; | ||
const { SPACE, COMMA, LENGTH, NUMBER, ANGLE } = tokens | ||
const oneOfType = tokenType => functionStream => { | ||
const value = functionStream.expect(tokenType); | ||
functionStream.expectEmpty(); | ||
return value; | ||
}; | ||
const value = functionStream.expect(tokenType) | ||
functionStream.expectEmpty() | ||
return value | ||
} | ||
const singleNumber = oneOfType(NUMBER); | ||
const singleLength = oneOfType(LENGTH); | ||
const singleAngle = oneOfType(ANGLE); | ||
const singleNumber = oneOfType(NUMBER) | ||
const singleLength = oneOfType(LENGTH) | ||
const singleAngle = oneOfType(ANGLE) | ||
const xyTransformFactory = tokenType => ( | ||
key, | ||
valueIfOmitted, | ||
valueIfOmitted | ||
) => functionStream => { | ||
const x = functionStream.expect(tokenType); | ||
const x = functionStream.expect(tokenType) | ||
let y; | ||
let y | ||
if (functionStream.hasTokens()) { | ||
functionStream.expect(COMMA); | ||
y = functionStream.expect(tokenType); | ||
functionStream.expect(COMMA) | ||
y = functionStream.expect(tokenType) | ||
} else if (valueIfOmitted !== undefined) { | ||
y = valueIfOmitted; | ||
y = valueIfOmitted | ||
} else { | ||
// Assumption, if x === y, then we can omit XY | ||
// I.e. scale(5) => [{ scale: 5 }] rather than [{ scaleX: 5 }, { scaleY: 5 }] | ||
return x; | ||
return x | ||
} | ||
functionStream.expectEmpty(); | ||
functionStream.expectEmpty() | ||
return [{ [`${key}Y`]: y }, { [`${key}X`]: x }]; | ||
}; | ||
const xyNumber = xyTransformFactory(NUMBER); | ||
const xyLength = xyTransformFactory(LENGTH); | ||
const xyAngle = xyTransformFactory(ANGLE); | ||
return [{ [`${key}Y`]: y }, { [`${key}X`]: x }] | ||
} | ||
const xyNumber = xyTransformFactory(NUMBER) | ||
const xyLength = xyTransformFactory(LENGTH) | ||
const xyAngle = xyTransformFactory(ANGLE) | ||
const partTransforms = { | ||
perspective: singleNumber, | ||
scale: xyNumber("scale"), | ||
scale: xyNumber('scale'), | ||
scaleX: singleNumber, | ||
scaleY: singleNumber, | ||
translate: xyLength("translate", 0), | ||
translate: xyLength('translate', 0), | ||
translateX: singleLength, | ||
@@ -54,24 +54,24 @@ translateY: singleLength, | ||
skewY: singleAngle, | ||
skew: xyAngle("skew", "0deg"), | ||
}; | ||
skew: xyAngle('skew', '0deg') | ||
} | ||
export default tokenStream => { | ||
let transforms = []; | ||
let transforms = [] | ||
let didParseFirst = false; | ||
let didParseFirst = false | ||
while (tokenStream.hasTokens()) { | ||
if (didParseFirst) tokenStream.expect(SPACE); | ||
if (didParseFirst) tokenStream.expect(SPACE) | ||
const functionStream = tokenStream.expectFunction(); | ||
const { functionName } = functionStream; | ||
let transformedValues = partTransforms[functionName](functionStream); | ||
const functionStream = tokenStream.expectFunction() | ||
const { functionName } = functionStream | ||
let transformedValues = partTransforms[functionName](functionStream) | ||
if (!Array.isArray(transformedValues)) { | ||
transformedValues = [{ [functionName]: transformedValues }]; | ||
transformedValues = [{ [functionName]: transformedValues }] | ||
} | ||
transforms = transformedValues.concat(transforms); | ||
transforms = transformedValues.concat(transforms) | ||
didParseFirst = true; | ||
didParseFirst = true | ||
} | ||
return transforms; | ||
}; | ||
return transforms | ||
} |
@@ -1,26 +0,26 @@ | ||
import { tokens } from "../tokenTypes"; | ||
import { tokens } from '../tokenTypes' | ||
const { LENGTH, UNSUPPORTED_LENGTH_UNIT, PERCENT, COLOR, SPACE, NONE } = tokens; | ||
const { LENGTH, UNSUPPORTED_LENGTH_UNIT, PERCENT, COLOR, SPACE, NONE } = tokens | ||
export const directionFactory = ({ | ||
types = [LENGTH, UNSUPPORTED_LENGTH_UNIT, PERCENT], | ||
directions = ["Top", "Right", "Bottom", "Left"], | ||
prefix = "", | ||
suffix = "", | ||
directions = ['Top', 'Right', 'Bottom', 'Left'], | ||
prefix = '', | ||
suffix = '' | ||
}) => tokenStream => { | ||
const values = []; | ||
const values = [] | ||
// borderWidth doesn't currently allow a percent value, but may do in the future | ||
values.push(tokenStream.expect(...types)); | ||
values.push(tokenStream.expect(...types)) | ||
while (values.length < 4 && tokenStream.hasTokens()) { | ||
tokenStream.expect(SPACE); | ||
values.push(tokenStream.expect(...types)); | ||
tokenStream.expect(SPACE) | ||
values.push(tokenStream.expect(...types)) | ||
} | ||
tokenStream.expectEmpty(); | ||
tokenStream.expectEmpty() | ||
const [top, right = top, bottom = top, left = right] = values; | ||
const [top, right = top, bottom = top, left = right] = values | ||
const keyFor = n => `${prefix}${directions[n]}${suffix}`; | ||
const keyFor = n => `${prefix}${directions[n]}${suffix}` | ||
@@ -31,18 +31,18 @@ const output = { | ||
[keyFor(2)]: bottom, | ||
[keyFor(3)]: left, | ||
}; | ||
[keyFor(3)]: left | ||
} | ||
return { $merge: output }; | ||
}; | ||
return { $merge: output } | ||
} | ||
export const anyOrderFactory = (properties, delim = SPACE) => tokenStream => { | ||
const propertyNames = Object.keys(properties); | ||
const propertyNames = Object.keys(properties) | ||
const values = propertyNames.reduce((accum, propertyName) => { | ||
accum[propertyName] === undefined; // eslint-disable-line | ||
return accum; | ||
}, {}); | ||
return accum | ||
}, {}) | ||
let numParsed = 0; | ||
let numParsed = 0 | ||
while (numParsed < propertyNames.length && tokenStream.hasTokens()) { | ||
if (numParsed) tokenStream.expect(delim); | ||
if (numParsed) tokenStream.expect(delim) | ||
@@ -53,52 +53,51 @@ const matchedPropertyName = propertyNames.find( | ||
properties[propertyName].tokens.some(token => | ||
tokenStream.matches(token), | ||
), | ||
); | ||
tokenStream.matches(token) | ||
) | ||
) | ||
if (!matchedPropertyName) { | ||
tokenStream.throw(); | ||
tokenStream.throw() | ||
} else { | ||
values[matchedPropertyName] = tokenStream.lastValue; | ||
values[matchedPropertyName] = tokenStream.lastValue | ||
} | ||
numParsed += 1; | ||
numParsed += 1 | ||
} | ||
tokenStream.expectEmpty(); | ||
tokenStream.expectEmpty() | ||
propertyNames.forEach(propertyName => { | ||
if (values[propertyName] === undefined) | ||
values[propertyName] = properties[propertyName].default; | ||
}); | ||
if (values[propertyName] === undefined) { values[propertyName] = properties[propertyName].default } | ||
}) | ||
return { $merge: values }; | ||
}; | ||
return { $merge: values } | ||
} | ||
export const shadowOffsetFactory = () => tokenStream => { | ||
const width = tokenStream.expect(LENGTH); | ||
const width = tokenStream.expect(LENGTH) | ||
const height = tokenStream.matches(SPACE) | ||
? tokenStream.expect(LENGTH) | ||
: width; | ||
tokenStream.expectEmpty(); | ||
return { width, height }; | ||
}; | ||
: width | ||
tokenStream.expectEmpty() | ||
return { width, height } | ||
} | ||
export const parseShadow = tokenStream => { | ||
let offsetX; | ||
let offsetY; | ||
let radius; | ||
let color; | ||
let offsetX | ||
let offsetY | ||
let radius | ||
let color | ||
if (tokenStream.matches(NONE)) { | ||
tokenStream.expectEmpty(); | ||
tokenStream.expectEmpty() | ||
return { | ||
offset: { width: 0, height: 0 }, | ||
radius: 0, | ||
color: "black", | ||
}; | ||
color: 'black' | ||
} | ||
} | ||
let didParseFirst = false; | ||
let didParseFirst = false | ||
while (tokenStream.hasTokens()) { | ||
if (didParseFirst) tokenStream.expect(SPACE); | ||
if (didParseFirst) tokenStream.expect(SPACE) | ||
@@ -109,7 +108,7 @@ if ( | ||
) { | ||
offsetX = tokenStream.lastValue; | ||
tokenStream.expect(SPACE); | ||
offsetY = tokenStream.expect(LENGTH, UNSUPPORTED_LENGTH_UNIT); | ||
offsetX = tokenStream.lastValue | ||
tokenStream.expect(SPACE) | ||
offsetY = tokenStream.expect(LENGTH, UNSUPPORTED_LENGTH_UNIT) | ||
tokenStream.saveRewindPoint(); | ||
tokenStream.saveRewindPoint() | ||
if ( | ||
@@ -119,16 +118,16 @@ tokenStream.matches(SPACE) && | ||
) { | ||
radius = tokenStream.lastValue; | ||
radius = tokenStream.lastValue | ||
} else { | ||
tokenStream.rewind(); | ||
tokenStream.rewind() | ||
} | ||
} else if (color === undefined && tokenStream.matches(COLOR)) { | ||
color = tokenStream.lastValue; | ||
color = tokenStream.lastValue | ||
} else { | ||
tokenStream.throw(); | ||
tokenStream.throw() | ||
} | ||
didParseFirst = true; | ||
didParseFirst = true | ||
} | ||
if (offsetX === undefined) tokenStream.throw(); | ||
if (offsetX === undefined) tokenStream.throw() | ||
@@ -138,4 +137,4 @@ return { | ||
radius: radius !== undefined ? radius : 0, | ||
color: color !== undefined ? color : "black", | ||
}; | ||
}; | ||
color: color !== undefined ? color : 'black' | ||
} | ||
} |
185
src/index.js
@@ -1,41 +0,41 @@ | ||
import mediaQuery from "css-mediaquery"; | ||
import transformCSS from "./css-to-react-native"; | ||
import parseCSS from "css/lib/parse"; | ||
import mediaQuery from 'css-mediaquery' | ||
import transformCSS from './css-to-react-native' | ||
import parseCSS from 'css/lib/parse' | ||
import { | ||
dimensionFeatures, | ||
mediaQueryFeatures, | ||
} from "./transforms/media-queries/features"; | ||
import { mediaQueryTypes } from "./transforms/media-queries/types"; | ||
import { remToPx } from "./transforms/rem"; | ||
import { allEqual } from "./utils/allEqual"; | ||
import { camelCase } from "./utils/camelCase"; | ||
import { sortRules } from "./utils/sortRules"; | ||
import { values } from "./utils/values"; | ||
mediaQueryFeatures | ||
} from './transforms/media-queries/features' | ||
import { mediaQueryTypes } from './transforms/media-queries/types' | ||
import { remToPx } from './transforms/rem' | ||
import { allEqual } from './utils/allEqual' | ||
import { camelCase } from './utils/camelCase' | ||
import { sortRules } from './utils/sortRules' | ||
import { values } from './utils/values' | ||
const lengthRe = /^(0$|(?:[+-]?(?:\d*\.)?\d+(?:[Ee][+-]?\d+)?)(?=px|rem$))/; | ||
const viewportUnitRe = /^([+-]?[0-9.]+)(vh|vw|vmin|vmax)$/; | ||
const percentRe = /^([+-]?(?:\d*\.)?\d+(?:[Ee][+-]?\d+)?%)$/; | ||
const unsupportedUnitRe = /^([+-]?(?:\d*\.)?\d+(?:[Ee][+-]?\d+)?(ch|em|ex|cm|mm|in|pc|pt))$/; | ||
const lengthRe = /^(0$|(?:[+-]?(?:\d*\.)?\d+(?:[Ee][+-]?\d+)?)(?=px|rem$))/ | ||
const viewportUnitRe = /^([+-]?[0-9.]+)(vh|vw|vmin|vmax)$/ | ||
const percentRe = /^([+-]?(?:\d*\.)?\d+(?:[Ee][+-]?\d+)?%)$/ | ||
const unsupportedUnitRe = /^([+-]?(?:\d*\.)?\d+(?:[Ee][+-]?\d+)?(ch|em|ex|cm|mm|in|pc|pt))$/ | ||
const shorthandBorderProps = [ | ||
"border-radius", | ||
"border-width", | ||
"border-color", | ||
"border-style", | ||
]; | ||
'border-radius', | ||
'border-width', | ||
'border-color', | ||
'border-style' | ||
] | ||
const transformDecls = (styles, declarations, result) => { | ||
const transformDecls = (styles, declarations, result, options) => { | ||
for (const d in declarations) { | ||
const declaration = declarations[d]; | ||
if (declaration.type !== "declaration") continue; | ||
const declaration = declarations[d] | ||
if (declaration.type !== 'declaration') continue | ||
const property = declaration.property; | ||
const value = remToPx(declaration.value); | ||
const property = declaration.property | ||
let value = remToPx(declaration.value) | ||
const isLengthUnit = lengthRe.test(value); | ||
const isViewportUnit = viewportUnitRe.test(value); | ||
const isPercent = percentRe.test(value); | ||
const isUnsupportedUnit = unsupportedUnitRe.test(value); | ||
const isLengthUnit = lengthRe.test(value) | ||
const isViewportUnit = viewportUnitRe.test(value) | ||
const isPercent = percentRe.test(value) | ||
const isUnsupportedUnit = unsupportedUnitRe.test(value) | ||
if ( | ||
property === "line-height" && | ||
property === 'line-height' && | ||
!isLengthUnit && | ||
@@ -46,8 +46,17 @@ !isViewportUnit && | ||
) { | ||
throw new Error(`Failed to parse declaration "${property}: ${value}"`); | ||
throw new Error(`Failed to parse declaration "${property}: ${value}"`) | ||
} | ||
if (!result.__viewportUnits && isViewportUnit) { | ||
result.__viewportUnits = true; | ||
result.__viewportUnits = true | ||
} | ||
// scalable option, when it is false, transform single value 'px' unit to 'PX' | ||
// do not be wrapped by scalePx2dp function | ||
if ( | ||
!options.scalable && | ||
isLengthUnit && | ||
/px/.test(value) | ||
) { | ||
value = value.replace(/px/g, 'PX') | ||
} | ||
@@ -57,29 +66,29 @@ if (shorthandBorderProps.indexOf(property) > -1) { | ||
// shorthand form to support styling `Image`. | ||
const transformed = transformCSS([[property, value]]); | ||
const vals = values(transformed); | ||
const transformed = transformCSS([[property, value]]) | ||
const vals = values(transformed) | ||
if (allEqual(vals)) { | ||
const replacement = {}; | ||
replacement[camelCase(property)] = vals[0]; | ||
Object.assign(styles, replacement); | ||
const replacement = {} | ||
replacement[camelCase(property)] = vals[0] | ||
Object.assign(styles, replacement) | ||
} else { | ||
Object.assign(styles, transformed); | ||
Object.assign(styles, transformed) | ||
} | ||
} else { | ||
Object.assign(styles, transformCSS([[property, value]])); | ||
Object.assign(styles, transformCSS([[property, value]])) | ||
} | ||
} | ||
}; | ||
} | ||
const transform = (css, options) => { | ||
const { stylesheet } = parseCSS(css); | ||
const rules = sortRules(stylesheet.rules); | ||
const { stylesheet } = parseCSS(css) | ||
const rules = sortRules(stylesheet.rules) | ||
const result = {}; | ||
const result = {} | ||
for (const r in rules) { | ||
const rule = rules[r]; | ||
const rule = rules[r] | ||
for (const s in rule.selectors) { | ||
if (rule.selectors[s] === ":export") { | ||
if (rule.selectors[s] === ':export') { | ||
if (!result.__exportProps) { | ||
result.__exportProps = {}; | ||
result.__exportProps = {} | ||
} | ||
@@ -90,50 +99,50 @@ | ||
result[property] !== undefined && | ||
result.__exportProps[property] === undefined; | ||
result.__exportProps[property] === undefined | ||
if (isAlreadyDefinedAsClass) { | ||
throw new Error( | ||
`Failed to parse :export block because a CSS class in the same file is already using the name "${property}"`, | ||
); | ||
`Failed to parse :export block because a CSS class in the same file is already using the name "${property}"` | ||
) | ||
} | ||
result.__exportProps[property] = value; | ||
}); | ||
continue; | ||
result.__exportProps[property] = value | ||
}) | ||
continue | ||
} | ||
if ( | ||
rule.selectors[s].indexOf(".") !== 0 || | ||
rule.selectors[s].indexOf(":") !== -1 || | ||
rule.selectors[s].indexOf("[") !== -1 || | ||
rule.selectors[s].indexOf("~") !== -1 || | ||
rule.selectors[s].indexOf(">") !== -1 || | ||
rule.selectors[s].indexOf("+") !== -1 || | ||
rule.selectors[s].indexOf(" ") !== -1 | ||
rule.selectors[s].indexOf('.') !== 0 || | ||
rule.selectors[s].indexOf(':') !== -1 || | ||
rule.selectors[s].indexOf('[') !== -1 || | ||
rule.selectors[s].indexOf('~') !== -1 || | ||
rule.selectors[s].indexOf('>') !== -1 || | ||
rule.selectors[s].indexOf('+') !== -1 || | ||
rule.selectors[s].indexOf(' ') !== -1 | ||
) { | ||
continue; | ||
continue | ||
} | ||
const selector = rule.selectors[s].replace(/^\./, ""); | ||
const styles = (result[selector] = result[selector] || {}); | ||
transformDecls(styles, rule.declarations, result); | ||
const selector = rule.selectors[s].replace(/^\./, '') | ||
const styles = (result[selector] = result[selector] || {}) | ||
transformDecls(styles, rule.declarations, result, options) | ||
} | ||
if ( | ||
rule.type == "media" && | ||
rule.type === 'media' && | ||
options != null && | ||
options.parseMediaQueries === true | ||
) { | ||
const parsed = mediaQuery.parse(rule.media); | ||
const parsed = mediaQuery.parse(rule.media) | ||
parsed.forEach(mq => { | ||
if (mediaQueryTypes.indexOf(mq.type) === -1) { | ||
throw new Error(`Failed to parse media query type "${mq.type}"`); | ||
throw new Error(`Failed to parse media query type "${mq.type}"`) | ||
} | ||
mq.expressions.forEach(e => { | ||
const mf = e.modifier ? `${e.modifier}-${e.feature}` : e.feature; | ||
const val = e.value ? `: ${e.value}` : ""; | ||
const mf = e.modifier ? `${e.modifier}-${e.feature}` : e.feature | ||
const val = e.value ? `: ${e.value}` : '' | ||
if (mediaQueryFeatures.indexOf(e.feature) === -1) { | ||
throw new Error(`Failed to parse media query feature "${mf}"`); | ||
throw new Error(`Failed to parse media query feature "${mf}"`) | ||
} | ||
@@ -146,21 +155,21 @@ | ||
throw new Error( | ||
`Failed to parse media query expression "(${mf}${val})"`, | ||
); | ||
`Failed to parse media query expression "(${mf}${val})"` | ||
) | ||
} | ||
}); | ||
}); | ||
}) | ||
}) | ||
const media = "@media " + rule.media; | ||
const media = '@media ' + rule.media | ||
result.__mediaQueries = result.__mediaQueries || {}; | ||
result.__mediaQueries[media] = parsed; | ||
result.__mediaQueries = result.__mediaQueries || {} | ||
result.__mediaQueries[media] = parsed | ||
for (const r in rule.rules) { | ||
const ruleRule = rule.rules[r]; | ||
const ruleRule = rule.rules[r] | ||
for (const s in ruleRule.selectors) { | ||
result[media] = result[media] || {}; | ||
const selector = ruleRule.selectors[s].replace(/^\./, ""); | ||
result[media] = result[media] || {} | ||
const selector = ruleRule.selectors[s].replace(/^\./, '') | ||
const mediaStyles = (result[media][selector] = | ||
result[media][selector] || {}); | ||
transformDecls(mediaStyles, ruleRule.declarations, result); | ||
result[media][selector] || {}) | ||
transformDecls(mediaStyles, ruleRule.declarations, result, options) | ||
} | ||
@@ -172,9 +181,13 @@ } | ||
if (result.__exportProps) { | ||
Object.assign(result, result.__exportProps); | ||
delete result.__exportProps; | ||
Object.assign(result, result.__exportProps) | ||
delete result.__exportProps | ||
} | ||
return result; | ||
}; | ||
return result | ||
} | ||
export default transform; | ||
export { | ||
transformCSS | ||
} | ||
export default transform |
export const dimensionFeatures = [ | ||
"width", | ||
"height", | ||
"device-width", | ||
"device-height", | ||
]; | ||
'width', | ||
'height', | ||
'device-width', | ||
'device-height' | ||
] | ||
export const mediaQueryFeatures = [ | ||
"orientation", | ||
"scan", | ||
"resolution", | ||
"aspect-ratio", | ||
"device-aspect-ratio", | ||
"grid", | ||
"color", | ||
"color-index", | ||
"monochrome", | ||
].concat(dimensionFeatures); | ||
'orientation', | ||
'scan', | ||
'resolution', | ||
'aspect-ratio', | ||
'device-aspect-ratio', | ||
'grid', | ||
'color', | ||
'color-index', | ||
'monochrome' | ||
].concat(dimensionFeatures) |
export const defaultTypes = [ | ||
"all", | ||
"braille", | ||
"embossed", | ||
"handheld", | ||
"print", | ||
"projection", | ||
"screen", | ||
"speech", | ||
"tty", | ||
"tv", | ||
]; | ||
export const cssnextMediaQueryTypes = ["pointer", "hover", "block-overflow"]; | ||
'all', | ||
'braille', | ||
'embossed', | ||
'handheld', | ||
'print', | ||
'projection', | ||
'screen', | ||
'speech', | ||
'tty', | ||
'tv' | ||
] | ||
export const cssnextMediaQueryTypes = ['pointer', 'hover', 'block-overflow'] | ||
export const reactNativeMediaQueryTypes = [ | ||
"android", | ||
"dom", | ||
"ios", | ||
"macos", | ||
"web", | ||
"windows", | ||
]; | ||
'android', | ||
'dom', | ||
'ios', | ||
'macos', | ||
'web', | ||
'windows' | ||
] | ||
export const mediaQueryTypes = defaultTypes | ||
.concat(cssnextMediaQueryTypes) | ||
.concat(reactNativeMediaQueryTypes); | ||
.concat(reactNativeMediaQueryTypes) |
export const remToPx = value => { | ||
return value.replace( | ||
/(\d*\.?\d+)rem/g, | ||
(match, m1) => parseFloat(m1, 10) * 16 + 'px' | ||
) | ||
return value.replace(/(\d*\.?\d+)rem/g, (match, m1) => parseFloat(m1, 10) * 16 + 'px') | ||
} |
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
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
0
94353
48
2803
2
1