1
0
Fork 0

worked on GarageApp stuff

This commit is contained in:
Techognito 2025-08-25 17:46:11 +02:00
parent 60aaf17af3
commit eb606572b0
51919 changed files with 2168177 additions and 18 deletions

21
node_modules/css-to-react-native/LICENSE.md generated vendored Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2016 Jacob Parker and Maximilian Stoiber
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

115
node_modules/css-to-react-native/README.md generated vendored Normal file
View file

@ -0,0 +1,115 @@
# css-to-react-native
Converts CSS text to a React Native stylesheet object.
[Try it here](https://csstox.surge.sh)
```css
font-size: 18px;
line-height: 24px;
color: red;
```
```js
{
fontSize: 18,
lineHeight: 24,
color: 'red',
}
```
Converts all number-like values to numbers, and string-like to strings.
Automatically converts indirect values to their React Native equivalents.
```css
text-shadow-offset: 10px 5px;
font-variant: small-caps;
transform: translate(10px, 5px) scale(5);
```
```js
{
textShadowOffset: { width: 10, height: 5 },
fontVariant: ['small-caps'],
// Fixes backwards transform order
transform: [
{ translateY: 5 },
{ translateX: 10 },
{ scale: 5 },
]
}
```
Also allows shorthand values.
```css
font: bold 14px/16px "Helvetica";
margin: 5px 7px 2px;
```
```js
{
fontFamily: 'Helvetica',
fontSize: 14,
fontWeight: 'bold',
fontStyle: 'normal',
fontVariant: [],
lineHeight: 16,
marginTop: 5,
marginRight: 7,
marginBottom: 2,
marginLeft: 7,
}
```
Shorthands will only accept values that are supported in React, so `background` will only accept a colour, `backgroundColor`
There is also support for the `box-shadow` shorthand, and this converts into `shadow-` properties. Note that these only work on iOS.
#### Shorthand Notes
`border{Top,Right,Bottom,Left}` shorthands are not supported, because `borderStyle` cannot be applied to individual border sides.
# API
The API is mostly for implementors. However, the main API may be useful for non-implementors. The main API is an array of `[property, value]` tuples.
```js
import transform from 'css-to-react-native';
// or const transform = require('css-to-react-native').default;
transform([
['font', 'bold 14px/16px "Helvetica"'],
['margin', '5px 7px 2px'],
['border-left-width', '5px'],
]); // => { fontFamily: 'Helvetica', ... }
```
We don't provide a way to get these style tuples in this library, so you'll need to do that yourself. I expect most people will use postCSS or another CSS parser. You should try avoid getting these with `string.split`, as that has a lot of edge cases (colons and semi-colons appearing in comments etc.)
For implementors, there is also a few extra APIs available.
These are for specific use-cases, and most people should just be using the API above.
```js
import { getPropertyName, getStylesForProperty } from 'css-to-react-native';
getPropertyName('border-width'); // => 'borderWidth'
getStylesForProperty('borderWidth', '1px 0px 2px 0px'); // => { borderTopWidth: 1, ... }
```
Should you wish to opt-out of transforming certain shorthands, an array of property names in camelCase can be passed as a second argument to `transform`.
```js
transform([['border-radius', '50px']], ['borderRadius']);
// { borderRadius: 50 } rather than { borderTopLeft: ... }
```
This can also be done by passing a third argument, `false` to `getStylesForProperty`.
## License
Licensed under the MIT License, Copyright © 2019 Krister Kari, Jacob Parker, and Maximilian Stoiber.
See [LICENSE.md](./LICENSE.md) for more information.

17
node_modules/css-to-react-native/index.d.ts generated vendored Normal file
View file

@ -0,0 +1,17 @@
export type StyleTuple = [string, string]
export interface Style {
[key: string]: string | number | Style
}
export function getPropertyName(name: string): string
export function getStylesForProperty(
name: string,
value: string,
allowShorthand?: boolean
): Style
export default function transform(
styleTuples: StyleTuple[],
shorthandBlacklist?: string[]
): Style

886
node_modules/css-to-react-native/index.js generated vendored Normal file
View file

@ -0,0 +1,886 @@
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
function _interopDefault(ex) {
return ex && typeof ex === 'object' && 'default' in ex ? ex['default'] : ex;
}
var parse = require('postcss-value-parser');
var parse__default = _interopDefault(parse);
var camelizeStyleName = _interopDefault(require('camelize'));
var cssColorKeywords = _interopDefault(require('css-color-keywords'));
var matchString = function matchString(node) {
if (node.type !== 'string') return null;
return node.value.replace(/\\([0-9a-f]{1,6})(?:\s|$)/gi, function (match, charCode) {
return String.fromCharCode(parseInt(charCode, 16));
}).replace(/\\/g, '');
};
var hexColorRe = /^(#(?:[0-9a-f]{3,4}){1,2})$/i;
var cssFunctionNameRe = /^(rgba?|hsla?|hwb|lab|lch|gray|color)$/;
var matchColor = function matchColor(node) {
if (node.type === 'word' && (hexColorRe.test(node.value) || node.value in cssColorKeywords || node.value === 'transparent')) {
return node.value;
} else if (node.type === 'function' && cssFunctionNameRe.test(node.value)) {
return parse.stringify(node);
}
return null;
};
var noneRe = /^(none)$/i;
var autoRe = /^(auto)$/i;
var identRe = /(^-?[_a-z][_a-z0-9-]*$)/i; // Note if these are wrong, you'll need to change index.js too
var numberRe = /^([+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?)$/i; // Note lengthRe is sneaky: you can omit units for 0
var lengthRe = /^(0$|(?:[+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?)(?=px$))/i;
var unsupportedUnitRe = /^([+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?(ch|em|ex|rem|vh|vw|vmin|vmax|cm|mm|in|pc|pt))$/i;
var angleRe = /^([+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?(?:deg|rad))$/i;
var percentRe = /^([+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?%)$/i;
var noopToken = function noopToken(predicate) {
return function (node) {
return predicate(node) ? '<token>' : null;
};
};
var valueForTypeToken = function valueForTypeToken(type) {
return function (node) {
return node.type === type ? node.value : null;
};
};
var regExpToken = function regExpToken(regExp, transform) {
if (transform === void 0) {
transform = String;
}
return function (node) {
if (node.type !== 'word') return null;
var match = node.value.match(regExp);
if (match === null) return null;
var value = transform(match[1]);
return value;
};
};
var SPACE = noopToken(function (node) {
return node.type === 'space';
});
var SLASH = noopToken(function (node) {
return node.type === 'div' && node.value === '/';
});
var COMMA = noopToken(function (node) {
return node.type === 'div' && node.value === ',';
});
var WORD = valueForTypeToken('word');
var NONE = regExpToken(noneRe);
var AUTO = regExpToken(autoRe);
var NUMBER = regExpToken(numberRe, Number);
var LENGTH = regExpToken(lengthRe, Number);
var UNSUPPORTED_LENGTH_UNIT = regExpToken(unsupportedUnitRe);
var ANGLE = regExpToken(angleRe, function (angle) {
return angle.toLowerCase();
});
var PERCENT = regExpToken(percentRe);
var IDENT = regExpToken(identRe);
var STRING = matchString;
var COLOR = matchColor;
var LINE = regExpToken(/^(none|underline|line-through)$/i);
var aspectRatio = function aspectRatio(tokenStream) {
var aspectRatio = tokenStream.expect(NUMBER);
if (tokenStream.hasTokens()) {
tokenStream.expect(SLASH);
aspectRatio /= tokenStream.expect(NUMBER);
}
return {
aspectRatio: aspectRatio
};
};
var BORDER_STYLE = regExpToken(/^(solid|dashed|dotted)$/);
var defaultBorderWidth = 1;
var defaultBorderColor = 'black';
var defaultBorderStyle = 'solid';
var border = function border(tokenStream) {
var borderWidth;
var borderColor;
var borderStyle;
if (tokenStream.matches(NONE)) {
tokenStream.expectEmpty();
return {
borderWidth: 0,
borderColor: 'black',
borderStyle: 'solid'
};
}
var partsParsed = 0;
while (partsParsed < 3 && tokenStream.hasTokens()) {
if (partsParsed !== 0) tokenStream.expect(SPACE);
if (borderWidth === undefined && tokenStream.matches(LENGTH, UNSUPPORTED_LENGTH_UNIT)) {
borderWidth = tokenStream.lastValue;
} else if (borderColor === undefined && tokenStream.matches(COLOR)) {
borderColor = tokenStream.lastValue;
} else if (borderStyle === undefined && tokenStream.matches(BORDER_STYLE)) {
borderStyle = tokenStream.lastValue;
} else {
tokenStream["throw"]();
}
partsParsed += 1;
}
tokenStream.expectEmpty();
if (borderWidth === undefined) borderWidth = defaultBorderWidth;
if (borderColor === undefined) borderColor = defaultBorderColor;
if (borderStyle === undefined) borderStyle = defaultBorderStyle;
return {
borderWidth: borderWidth,
borderColor: borderColor,
borderStyle: borderStyle
};
};
var directionFactory = function directionFactory(_ref) {
var _ref$types = _ref.types,
types = _ref$types === void 0 ? [LENGTH, UNSUPPORTED_LENGTH_UNIT, PERCENT] : _ref$types,
_ref$directions = _ref.directions,
directions = _ref$directions === void 0 ? ['Top', 'Right', 'Bottom', 'Left'] : _ref$directions,
_ref$prefix = _ref.prefix,
prefix = _ref$prefix === void 0 ? '' : _ref$prefix,
_ref$suffix = _ref.suffix,
suffix = _ref$suffix === void 0 ? '' : _ref$suffix;
return function (tokenStream) {
var _ref2;
var values = []; // borderWidth doesn't currently allow a percent value, but may do in the future
values.push(tokenStream.expect.apply(tokenStream, types));
while (values.length < 4 && tokenStream.hasTokens()) {
tokenStream.expect(SPACE);
values.push(tokenStream.expect.apply(tokenStream, types));
}
tokenStream.expectEmpty();
var top = values[0],
_values$ = values[1],
right = _values$ === void 0 ? top : _values$,
_values$2 = values[2],
bottom = _values$2 === void 0 ? top : _values$2,
_values$3 = values[3],
left = _values$3 === void 0 ? right : _values$3;
var keyFor = function keyFor(n) {
return "" + prefix + directions[n] + suffix;
};
return _ref2 = {}, _ref2[keyFor(0)] = top, _ref2[keyFor(1)] = right, _ref2[keyFor(2)] = bottom, _ref2[keyFor(3)] = left, _ref2;
};
};
var parseShadowOffset = function parseShadowOffset(tokenStream) {
var width = tokenStream.expect(LENGTH);
var height = tokenStream.matches(SPACE) ? tokenStream.expect(LENGTH) : width;
tokenStream.expectEmpty();
return {
width: width,
height: height
};
};
var parseShadow = function parseShadow(tokenStream) {
var offsetX;
var offsetY;
var radius;
var color;
if (tokenStream.matches(NONE)) {
tokenStream.expectEmpty();
return {
offset: {
width: 0,
height: 0
},
radius: 0,
color: 'black'
};
}
var didParseFirst = false;
while (tokenStream.hasTokens()) {
if (didParseFirst) tokenStream.expect(SPACE);
if (offsetX === undefined && tokenStream.matches(LENGTH, UNSUPPORTED_LENGTH_UNIT)) {
offsetX = tokenStream.lastValue;
tokenStream.expect(SPACE);
offsetY = tokenStream.expect(LENGTH, UNSUPPORTED_LENGTH_UNIT);
tokenStream.saveRewindPoint();
if (tokenStream.matches(SPACE) && tokenStream.matches(LENGTH, UNSUPPORTED_LENGTH_UNIT)) {
radius = tokenStream.lastValue;
} else {
tokenStream.rewind();
}
} else if (color === undefined && tokenStream.matches(COLOR)) {
color = tokenStream.lastValue;
} else {
tokenStream["throw"]();
}
didParseFirst = true;
}
if (offsetX === undefined) tokenStream["throw"]();
return {
offset: {
width: offsetX,
height: offsetY
},
radius: radius !== undefined ? radius : 0,
color: color !== undefined ? color : 'black'
};
};
var boxShadow = function boxShadow(tokenStream) {
var _parseShadow = parseShadow(tokenStream),
offset = _parseShadow.offset,
radius = _parseShadow.radius,
color = _parseShadow.color;
return {
shadowOffset: offset,
shadowRadius: radius,
shadowColor: color,
shadowOpacity: 1
};
};
var defaultFlexGrow = 1;
var defaultFlexShrink = 1;
var defaultFlexBasis = 0;
var flex = function flex(tokenStream) {
var flexGrow;
var flexShrink;
var flexBasis;
if (tokenStream.matches(NONE)) {
tokenStream.expectEmpty();
return {
flexGrow: 0,
flexShrink: 0,
flexBasis: 'auto'
};
}
tokenStream.saveRewindPoint();
if (tokenStream.matches(AUTO) && !tokenStream.hasTokens()) {
return {
flexGrow: 1,
flexShrink: 1,
flexBasis: 'auto'
};
}
tokenStream.rewind();
var partsParsed = 0;
while (partsParsed < 2 && tokenStream.hasTokens()) {
if (partsParsed !== 0) tokenStream.expect(SPACE);
if (flexGrow === undefined && tokenStream.matches(NUMBER)) {
flexGrow = tokenStream.lastValue;
tokenStream.saveRewindPoint();
if (tokenStream.matches(SPACE) && tokenStream.matches(NUMBER)) {
flexShrink = tokenStream.lastValue;
} else {
tokenStream.rewind();
}
} else if (flexBasis === undefined && tokenStream.matches(LENGTH, UNSUPPORTED_LENGTH_UNIT, PERCENT)) {
flexBasis = tokenStream.lastValue;
} else if (flexBasis === undefined && tokenStream.matches(AUTO)) {
flexBasis = 'auto';
} else {
tokenStream["throw"]();
}
partsParsed += 1;
}
tokenStream.expectEmpty();
if (flexGrow === undefined) flexGrow = defaultFlexGrow;
if (flexShrink === undefined) flexShrink = defaultFlexShrink;
if (flexBasis === undefined) flexBasis = defaultFlexBasis;
return {
flexGrow: flexGrow,
flexShrink: flexShrink,
flexBasis: flexBasis
};
};
var FLEX_WRAP = regExpToken(/(nowrap|wrap|wrap-reverse)/);
var FLEX_DIRECTION = regExpToken(/(row|row-reverse|column|column-reverse)/);
var defaultFlexWrap = 'nowrap';
var defaultFlexDirection = 'row';
var flexFlow = function flexFlow(tokenStream) {
var flexWrap;
var flexDirection;
var partsParsed = 0;
while (partsParsed < 2 && tokenStream.hasTokens()) {
if (partsParsed !== 0) tokenStream.expect(SPACE);
if (flexWrap === undefined && tokenStream.matches(FLEX_WRAP)) {
flexWrap = tokenStream.lastValue;
} else if (flexDirection === undefined && tokenStream.matches(FLEX_DIRECTION)) {
flexDirection = tokenStream.lastValue;
} else {
tokenStream["throw"]();
}
partsParsed += 1;
}
tokenStream.expectEmpty();
if (flexWrap === undefined) flexWrap = defaultFlexWrap;
if (flexDirection === undefined) flexDirection = defaultFlexDirection;
return {
flexWrap: flexWrap,
flexDirection: flexDirection
};
};
var fontFamily = function fontFamily(tokenStream) {
var fontFamily;
if (tokenStream.matches(STRING)) {
fontFamily = tokenStream.lastValue;
} else {
fontFamily = tokenStream.expect(IDENT);
while (tokenStream.hasTokens()) {
tokenStream.expect(SPACE);
var nextIdent = tokenStream.expect(IDENT);
fontFamily += " " + nextIdent;
}
}
tokenStream.expectEmpty();
return {
fontFamily: fontFamily
};
};
var NORMAL = regExpToken(/^(normal)$/);
var STYLE = regExpToken(/^(italic)$/);
var WEIGHT = regExpToken(/^([1-9]00|bold)$/);
var VARIANT = regExpToken(/^(small-caps)$/);
var defaultFontStyle = 'normal';
var defaultFontWeight = 'normal';
var defaultFontVariant = [];
var font = function font(tokenStream) {
var fontStyle;
var fontWeight;
var fontVariant; // let fontSize;
var lineHeight; // let fontFamily;
var numStyleWeightVariantMatched = 0;
while (numStyleWeightVariantMatched < 3 && tokenStream.hasTokens()) {
if (tokenStream.matches(NORMAL)) ;else if (fontStyle === undefined && tokenStream.matches(STYLE)) {
fontStyle = tokenStream.lastValue;
} else if (fontWeight === undefined && tokenStream.matches(WEIGHT)) {
fontWeight = tokenStream.lastValue;
} else if (fontVariant === undefined && tokenStream.matches(VARIANT)) {
fontVariant = [tokenStream.lastValue];
} else {
break;
}
tokenStream.expect(SPACE);
numStyleWeightVariantMatched += 1;
}
var fontSize = tokenStream.expect(LENGTH, UNSUPPORTED_LENGTH_UNIT);
if (tokenStream.matches(SLASH)) {
lineHeight = tokenStream.expect(LENGTH, UNSUPPORTED_LENGTH_UNIT);
}
tokenStream.expect(SPACE);
var _fontFamily = fontFamily(tokenStream),
fontFamily$1 = _fontFamily.fontFamily;
if (fontStyle === undefined) fontStyle = defaultFontStyle;
if (fontWeight === undefined) fontWeight = defaultFontWeight;
if (fontVariant === undefined) fontVariant = defaultFontVariant;
var out = {
fontStyle: fontStyle,
fontWeight: fontWeight,
fontVariant: fontVariant,
fontSize: fontSize,
fontFamily: fontFamily$1
};
if (lineHeight !== undefined) out.lineHeight = lineHeight;
return out;
};
var fontVariant = function fontVariant(tokenStream) {
var values = [tokenStream.expect(IDENT)];
while (tokenStream.hasTokens()) {
tokenStream.expect(SPACE);
values.push(tokenStream.expect(IDENT));
}
return {
fontVariant: values
};
};
var ALIGN_CONTENT = regExpToken(/(flex-(?:start|end)|center|stretch|space-(?:between|around))/);
var JUSTIFY_CONTENT = regExpToken(/(flex-(?:start|end)|center|space-(?:between|around|evenly))/);
var placeContent = function placeContent(tokenStream) {
var alignContent = tokenStream.expect(ALIGN_CONTENT);
var justifyContent;
if (tokenStream.hasTokens()) {
tokenStream.expect(SPACE);
justifyContent = tokenStream.expect(JUSTIFY_CONTENT);
} else {
justifyContent = 'stretch';
}
tokenStream.expectEmpty();
return {
alignContent: alignContent,
justifyContent: justifyContent
};
};
var STYLE$1 = regExpToken(/^(solid|double|dotted|dashed)$/);
var defaultTextDecorationLine = 'none';
var defaultTextDecorationStyle = 'solid';
var defaultTextDecorationColor = 'black';
var textDecoration = function textDecoration(tokenStream) {
var line;
var style;
var color;
var didParseFirst = false;
while (tokenStream.hasTokens()) {
if (didParseFirst) tokenStream.expect(SPACE);
if (line === undefined && tokenStream.matches(LINE)) {
var lines = [tokenStream.lastValue.toLowerCase()];
tokenStream.saveRewindPoint();
if (lines[0] !== 'none' && tokenStream.matches(SPACE) && tokenStream.matches(LINE)) {
lines.push(tokenStream.lastValue.toLowerCase()); // Underline comes before line-through
lines.sort().reverse();
} else {
tokenStream.rewind();
}
line = lines.join(' ');
} else if (style === undefined && tokenStream.matches(STYLE$1)) {
style = tokenStream.lastValue;
} else if (color === undefined && tokenStream.matches(COLOR)) {
color = tokenStream.lastValue;
} else {
tokenStream["throw"]();
}
didParseFirst = true;
}
return {
textDecorationLine: line !== undefined ? line : defaultTextDecorationLine,
textDecorationColor: color !== undefined ? color : defaultTextDecorationColor,
textDecorationStyle: style !== undefined ? style : defaultTextDecorationStyle
};
};
var textDecorationLine = function textDecorationLine(tokenStream) {
var lines = [];
var didParseFirst = false;
while (tokenStream.hasTokens()) {
if (didParseFirst) tokenStream.expect(SPACE);
lines.push(tokenStream.expect(LINE).toLowerCase());
didParseFirst = true;
}
lines.sort().reverse();
return {
textDecorationLine: lines.join(' ')
};
};
var textShadow = function textShadow(tokenStream) {
var _parseShadow2 = parseShadow(tokenStream),
offset = _parseShadow2.offset,
radius = _parseShadow2.radius,
color = _parseShadow2.color;
return {
textShadowOffset: offset,
textShadowRadius: radius,
textShadowColor: color
};
};
var oneOfType = function oneOfType(tokenType) {
return function (functionStream) {
var value = functionStream.expect(tokenType);
functionStream.expectEmpty();
return value;
};
};
var singleNumber = oneOfType(NUMBER);
var singleLength = oneOfType(LENGTH);
var singleAngle = oneOfType(ANGLE);
var xyTransformFactory = function xyTransformFactory(tokenType) {
return function (key, valueIfOmitted) {
return function (functionStream) {
var _ref3, _ref4;
var x = functionStream.expect(tokenType);
var y;
if (functionStream.hasTokens()) {
functionStream.expect(COMMA);
y = functionStream.expect(tokenType);
} else if (valueIfOmitted !== undefined) {
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;
}
functionStream.expectEmpty();
return [(_ref3 = {}, _ref3[key + "Y"] = y, _ref3), (_ref4 = {}, _ref4[key + "X"] = x, _ref4)];
};
};
};
var xyNumber = xyTransformFactory(NUMBER);
var xyLength = xyTransformFactory(LENGTH);
var xyAngle = xyTransformFactory(ANGLE);
var partTransforms = {
perspective: singleNumber,
scale: xyNumber('scale'),
scaleX: singleNumber,
scaleY: singleNumber,
translate: xyLength('translate', 0),
translateX: singleLength,
translateY: singleLength,
rotate: singleAngle,
rotateX: singleAngle,
rotateY: singleAngle,
rotateZ: singleAngle,
skewX: singleAngle,
skewY: singleAngle,
skew: xyAngle('skew', '0deg')
};
var transform = function transform(tokenStream) {
var transforms = [];
var didParseFirst = false;
while (tokenStream.hasTokens()) {
if (didParseFirst) tokenStream.expect(SPACE);
var functionStream = tokenStream.expectFunction();
var functionName = functionStream.functionName;
var transformedValues = partTransforms[functionName](functionStream);
if (!Array.isArray(transformedValues)) {
var _ref5;
transformedValues = [(_ref5 = {}, _ref5[functionName] = transformedValues, _ref5)];
}
transforms = transformedValues.concat(transforms);
didParseFirst = true;
}
return {
transform: transforms
};
};
var background = function background(tokenStream) {
return {
backgroundColor: tokenStream.expect(COLOR)
};
};
var borderColor = directionFactory({
types: [COLOR],
prefix: 'border',
suffix: 'Color'
});
var borderRadius = directionFactory({
directions: ['TopLeft', 'TopRight', 'BottomRight', 'BottomLeft'],
prefix: 'border',
suffix: 'Radius'
});
var borderWidth = directionFactory({
prefix: 'border',
suffix: 'Width'
});
var margin = directionFactory({
types: [LENGTH, UNSUPPORTED_LENGTH_UNIT, PERCENT, AUTO],
prefix: 'margin'
});
var padding = directionFactory({
prefix: 'padding'
});
var fontWeight = function fontWeight(tokenStream) {
return {
fontWeight: tokenStream.expect(WORD) // Also match numbers as strings
};
};
var shadowOffset = function shadowOffset(tokenStream) {
return {
shadowOffset: parseShadowOffset(tokenStream)
};
};
var textShadowOffset = function textShadowOffset(tokenStream) {
return {
textShadowOffset: parseShadowOffset(tokenStream)
};
};
var transforms = {
aspectRatio: aspectRatio,
background: background,
border: border,
borderColor: borderColor,
borderRadius: borderRadius,
borderWidth: borderWidth,
boxShadow: boxShadow,
flex: flex,
flexFlow: flexFlow,
font: font,
fontFamily: fontFamily,
fontVariant: fontVariant,
fontWeight: fontWeight,
margin: margin,
padding: padding,
placeContent: placeContent,
shadowOffset: shadowOffset,
textShadow: textShadow,
textShadowOffset: textShadowOffset,
textDecoration: textDecoration,
textDecorationLine: textDecorationLine,
transform: transform
};
var propertiesWithoutUnits;
if (process.env.NODE_ENV !== 'production') {
propertiesWithoutUnits = ['aspectRatio', 'elevation', 'flexGrow', 'flexShrink', 'opacity', 'shadowOpacity', 'zIndex'];
}
var devPropertiesWithUnitsRegExp = propertiesWithoutUnits != null ? new RegExp(propertiesWithoutUnits.join('|')) : null;
var SYMBOL_MATCH = 'SYMBOL_MATCH';
var TokenStream =
/*#__PURE__*/
function () {
function TokenStream(nodes, parent) {
this.index = 0;
this.nodes = nodes;
this.functionName = parent != null ? parent.value : null;
this.lastValue = null;
this.rewindIndex = -1;
}
var _proto = TokenStream.prototype;
_proto.hasTokens = function hasTokens() {
return this.index <= this.nodes.length - 1;
};
_proto[SYMBOL_MATCH] = function () {
if (!this.hasTokens()) return null;
var node = this.nodes[this.index];
for (var i = 0; i < arguments.length; i += 1) {
var tokenDescriptor = i < 0 || arguments.length <= i ? undefined : arguments[i];
var value = tokenDescriptor(node);
if (value !== null) {
this.index += 1;
this.lastValue = value;
return value;
}
}
return null;
};
_proto.matches = function matches() {
return this[SYMBOL_MATCH].apply(this, arguments) !== null;
};
_proto.expect = function expect() {
var value = this[SYMBOL_MATCH].apply(this, arguments);
return value !== null ? value : this["throw"]();
};
_proto.matchesFunction = function matchesFunction() {
var node = this.nodes[this.index];
if (node.type !== 'function') return null;
var value = new TokenStream(node.nodes, node);
this.index += 1;
this.lastValue = null;
return value;
};
_proto.expectFunction = function expectFunction() {
var value = this.matchesFunction();
return value !== null ? value : this["throw"]();
};
_proto.expectEmpty = function expectEmpty() {
if (this.hasTokens()) this["throw"]();
};
_proto["throw"] = function _throw() {
throw new Error("Unexpected token type: " + this.nodes[this.index].type);
};
_proto.saveRewindPoint = function saveRewindPoint() {
this.rewindIndex = this.index;
};
_proto.rewind = function rewind() {
if (this.rewindIndex === -1) throw new Error('Internal error');
this.index = this.rewindIndex;
this.lastValue = null;
};
return TokenStream;
}();
/* eslint-disable no-param-reassign */
// Note if this is wrong, you'll need to change tokenTypes.js too
var numberOrLengthRe = /^([+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?)(?:px)?$/i;
var numberOnlyRe = /^[+-]?(?:\d*\.\d*|[1-9]\d*)(?:e[+-]?\d+)?$/i;
var boolRe = /^true|false$/i;
var nullRe = /^null$/i;
var undefinedRe = /^undefined$/i; // Undocumented export
var transformRawValue = function transformRawValue(propName, value) {
if (process.env.NODE_ENV !== 'production') {
var needsUnit = !devPropertiesWithUnitsRegExp.test(propName);
var isNumberWithoutUnit = numberOnlyRe.test(value);
if (needsUnit && isNumberWithoutUnit) {
// eslint-disable-next-line no-console
console.warn("Expected style \"" + propName + ": " + value + "\" to contain units");
}
if (!needsUnit && value !== '0' && !isNumberWithoutUnit) {
// eslint-disable-next-line no-console
console.warn("Expected style \"" + propName + ": " + value + "\" to be unitless");
}
}
var numberMatch = value.match(numberOrLengthRe);
if (numberMatch !== null) return Number(numberMatch[1]);
var boolMatch = value.match(boolRe);
if (boolMatch !== null) return boolMatch[0].toLowerCase() === 'true';
var nullMatch = value.match(nullRe);
if (nullMatch !== null) return null;
var undefinedMatch = value.match(undefinedRe);
if (undefinedMatch !== null) return undefined;
return value;
};
var baseTransformShorthandValue = function baseTransformShorthandValue(propName, value) {
var ast = parse__default(value);
var tokenStream = new TokenStream(ast.nodes);
return transforms[propName](tokenStream);
};
var transformShorthandValue = process.env.NODE_ENV === 'production' ? baseTransformShorthandValue : function (propName, value) {
try {
return baseTransformShorthandValue(propName, value);
} catch (e) {
throw new Error("Failed to parse declaration \"" + propName + ": " + value + "\"");
}
};
var getStylesForProperty = function getStylesForProperty(propName, inputValue, allowShorthand) {
var _ref6;
var isRawValue = allowShorthand === false || !(propName in transforms);
var value = inputValue.trim();
var propValues = isRawValue ? (_ref6 = {}, _ref6[propName] = transformRawValue(propName, value), _ref6) : transformShorthandValue(propName, value);
return propValues;
};
var getPropertyName = function getPropertyName(propName) {
var isCustomProp = /^--\w+/.test(propName);
if (isCustomProp) {
return propName;
}
return camelizeStyleName(propName);
};
var index = function index(rules, shorthandBlacklist) {
if (shorthandBlacklist === void 0) {
shorthandBlacklist = [];
}
return rules.reduce(function (accum, rule) {
var propertyName = getPropertyName(rule[0]);
var value = rule[1];
var allowShorthand = shorthandBlacklist.indexOf(propertyName) === -1;
return Object.assign(accum, getStylesForProperty(propertyName, value, allowShorthand));
}, {});
};
exports["default"] = index;
exports.getPropertyName = getPropertyName;
exports.getStylesForProperty = getStylesForProperty;
exports.transformRawValue = transformRawValue;

65
node_modules/css-to-react-native/package.json generated vendored Normal file
View file

@ -0,0 +1,65 @@
{
"name": "css-to-react-native",
"version": "3.2.0",
"description": "Convert CSS text to a React Native stylesheet object",
"main": "index.js",
"types": "index.d.ts",
"scripts": {
"build": "rollup ./src/index.js -o index.js --f cjs && babel index.js -o index.js",
"test": "jest",
"test:watch": "jest --watch",
"lint": "eslint src",
"prepublish": "npm run build",
"precommit": "lint-staged",
"lint-staged": "lint-staged"
},
"files": [
"index.js",
"index.d.ts",
"src"
],
"repository": {
"type": "git",
"url": "git+https://github.com/styled-components/css-to-react-native.git"
},
"keywords": [
"styled-components",
"React",
"ReactNative",
"styles",
"CSS"
],
"author": "Jacob Parker",
"license": "MIT",
"bugs": {
"url": "https://github.com/styled-components/css-to-react-native/issues"
},
"homepage": "https://github.com/styled-components/css-to-react-native#readme",
"jest": {
"testURL": "http://localhost"
},
"devDependencies": {
"@babel/cli": "^7.6.2",
"@babel/preset-env": "^7.6.2",
"eslint": "^4.17.0",
"eslint-config-airbnb-base": "^12.1.0",
"eslint-config-prettier": "^2.9.0",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-prettier": "^2.6.0",
"jest": "^24.9.0",
"lint-staged": "^6.1.0",
"prettier": "^1.18.2",
"rollup": "^1.22.0"
},
"dependencies": {
"camelize": "^1.0.0",
"css-color-keywords": "^1.0.0",
"postcss-value-parser": "^4.0.2"
},
"lint-staged": {
"*.js": [
"eslint --fix",
"git add"
]
}
}

74
node_modules/css-to-react-native/src/TokenStream.js generated vendored Normal file
View file

@ -0,0 +1,74 @@
const SYMBOL_MATCH = 'SYMBOL_MATCH'
export default class TokenStream {
constructor(nodes, parent) {
this.index = 0
this.nodes = nodes
this.functionName = parent != null ? parent.value : null
this.lastValue = null
this.rewindIndex = -1
}
hasTokens() {
return this.index <= this.nodes.length - 1
}
[SYMBOL_MATCH](...tokenDescriptors) {
if (!this.hasTokens()) return null
const node = this.nodes[this.index]
for (let i = 0; i < tokenDescriptors.length; i += 1) {
const tokenDescriptor = tokenDescriptors[i]
const value = tokenDescriptor(node)
if (value !== null) {
this.index += 1
this.lastValue = value
return value
}
}
return null
}
matches(...tokenDescriptors) {
return this[SYMBOL_MATCH](...tokenDescriptors) !== null
}
expect(...tokenDescriptors) {
const value = this[SYMBOL_MATCH](...tokenDescriptors)
return value !== null ? value : this.throw()
}
matchesFunction() {
const node = this.nodes[this.index]
if (node.type !== 'function') return null
const value = new TokenStream(node.nodes, node)
this.index += 1
this.lastValue = null
return value
}
expectFunction() {
const value = this.matchesFunction()
return value !== null ? value : this.throw()
}
expectEmpty() {
if (this.hasTokens()) this.throw()
}
throw() {
throw new Error(`Unexpected token type: ${this.nodes[this.index].type}`)
}
saveRewindPoint() {
this.rewindIndex = this.index
}
rewind() {
if (this.rewindIndex === -1) throw new Error('Internal error')
this.index = this.rewindIndex
this.lastValue = null
}
}

View file

@ -0,0 +1,23 @@
import transformCss from '..'
it('handles regular aspect ratio values', () => {
expect(transformCss([['aspect-ratio', '1.5']])).toEqual({
aspectRatio: 1.5,
})
})
it('handles CSS-style aspect ratios', () => {
expect(transformCss([['aspect-ratio', '3 / 2']])).toEqual({
aspectRatio: 1.5,
})
})
it('handles CSS-style aspect ratios without spaces', () => {
expect(transformCss([['aspect-ratio', '3/2']])).toEqual({
aspectRatio: 1.5,
})
})
it('throws when omitting second value after slash', () => {
expect(() => transformCss([['aspect-ratio', '3/']])).toThrow()
})

View file

@ -0,0 +1,85 @@
import transformCss from '..'
it('transforms border none', () => {
expect(transformCss([['border', 'none']])).toEqual({
borderWidth: 0,
borderColor: 'black',
borderStyle: 'solid',
})
})
it('transforms border shorthand', () => {
expect(transformCss([['border', '2px dashed #f00']])).toEqual({
borderWidth: 2,
borderColor: '#f00',
borderStyle: 'dashed',
})
})
it('transforms border shorthand in other order', () => {
expect(transformCss([['border', '#f00 2px dashed']])).toEqual({
borderWidth: 2,
borderColor: '#f00',
borderStyle: 'dashed',
})
})
it('transforms border shorthand missing color', () => {
expect(transformCss([['border', '2px dashed']])).toEqual({
borderWidth: 2,
borderColor: 'black',
borderStyle: 'dashed',
})
})
it('transforms border shorthand missing style', () => {
expect(transformCss([['border', '2px #f00']])).toEqual({
borderWidth: 2,
borderColor: '#f00',
borderStyle: 'solid',
})
})
it('transforms border shorthand missing width', () => {
expect(transformCss([['border', '#f00 dashed']])).toEqual({
borderWidth: 1,
borderColor: '#f00',
borderStyle: 'dashed',
})
})
it('transforms border shorthand missing color & width', () => {
expect(transformCss([['border', 'dashed']])).toEqual({
borderWidth: 1,
borderColor: 'black',
borderStyle: 'dashed',
})
})
it('transforms border shorthand missing style & width', () => {
expect(transformCss([['border', '#f00']])).toEqual({
borderWidth: 1,
borderColor: '#f00',
borderStyle: 'solid',
})
})
it('transforms border shorthand missing color & style', () => {
expect(transformCss([['border', '2px']])).toEqual({
borderWidth: 2,
borderColor: 'black',
borderStyle: 'solid',
})
})
it('transforms border for unsupported units', () => {
expect(transformCss([['border', '3em solid black']])).toEqual({
borderWidth: '3em',
borderColor: 'black',
borderStyle: 'solid',
})
})
it('does not transform border with percentage width', () => {
expect(() => transformCss([['border', '3% solid black']])).toThrow()
})

View file

@ -0,0 +1,37 @@
import transformCss from '..'
it('transforms border color with multiple values', () => {
expect(transformCss([['border-color', 'red yellow green blue']])).toEqual({
borderTopColor: 'red',
borderRightColor: 'yellow',
borderBottomColor: 'green',
borderLeftColor: 'blue',
})
})
it('transforms border color with hex color', () => {
expect(transformCss([['border-color', '#f00']])).toEqual({
borderBottomColor: '#f00',
borderLeftColor: '#f00',
borderRightColor: '#f00',
borderTopColor: '#f00',
})
})
it('transforms border color with rgb color', () => {
expect(transformCss([['border-color', 'rgb(255, 0, 0)']])).toEqual({
borderBottomColor: 'rgb(255, 0, 0)',
borderLeftColor: 'rgb(255, 0, 0)',
borderRightColor: 'rgb(255, 0, 0)',
borderTopColor: 'rgb(255, 0, 0)',
})
})
it('transforms border color with rgba color', () => {
expect(transformCss([['border-color', 'rgba(255, 0, 0, 0.1)']])).toEqual({
borderBottomColor: 'rgba(255, 0, 0, 0.1)',
borderLeftColor: 'rgba(255, 0, 0, 0.1)',
borderRightColor: 'rgba(255, 0, 0, 0.1)',
borderTopColor: 'rgba(255, 0, 0, 0.1)',
})
})

View file

@ -0,0 +1,136 @@
import transformCss from '..'
it('transforms margin, padding with 1 value', () => {
expect(transformCss([['margin', '1px']])).toEqual({
marginTop: 1,
marginRight: 1,
marginBottom: 1,
marginLeft: 1,
})
expect(transformCss([['padding', '1px']])).toEqual({
paddingTop: 1,
paddingRight: 1,
paddingBottom: 1,
paddingLeft: 1,
})
})
it('transforms margin, padding with 2 values', () => {
expect(transformCss([['margin', '1px 2px']])).toEqual({
marginTop: 1,
marginRight: 2,
marginBottom: 1,
marginLeft: 2,
})
expect(transformCss([['padding', '1px 2px']])).toEqual({
paddingTop: 1,
paddingRight: 2,
paddingBottom: 1,
paddingLeft: 2,
})
})
it('transforms margin, padding with 3 values', () => {
expect(transformCss([['margin', '1px 2px 3px']])).toEqual({
marginTop: 1,
marginRight: 2,
marginBottom: 3,
marginLeft: 2,
})
expect(transformCss([['padding', '1px 2px 3px']])).toEqual({
paddingTop: 1,
paddingRight: 2,
paddingBottom: 3,
paddingLeft: 2,
})
})
it('transforms margin, padding with 4 values', () => {
expect(transformCss([['margin', '1px 2px 3px 4px']])).toEqual({
marginTop: 1,
marginRight: 2,
marginBottom: 3,
marginLeft: 4,
})
expect(transformCss([['padding', '1px 2px 3px 4px']])).toEqual({
paddingTop: 1,
paddingRight: 2,
paddingBottom: 3,
paddingLeft: 4,
})
})
it('transforms margin, allowing unitless zero, percentages', () => {
expect(transformCss([['margin', '0 0% 10% 100%']])).toEqual({
marginTop: 0,
marginRight: '0%',
marginBottom: '10%',
marginLeft: '100%',
})
expect(transformCss([['padding', '0 0% 10% 100%']])).toEqual({
paddingTop: 0,
paddingRight: '0%',
paddingBottom: '10%',
paddingLeft: '100%',
})
})
it('transforms shorthand and overrides previous values', () => {
expect(transformCss([['margin-top', '2px'], ['margin', '1px']])).toEqual({
marginTop: 1,
marginRight: 1,
marginBottom: 1,
marginLeft: 1,
})
})
it('transforms margin shorthand with auto', () => {
expect(transformCss([['margin', 'auto']])).toEqual({
marginTop: 'auto',
marginRight: 'auto',
marginBottom: 'auto',
marginLeft: 'auto',
})
expect(transformCss([['margin', '0 auto']])).toEqual({
marginTop: 0,
marginRight: 'auto',
marginBottom: 0,
marginLeft: 'auto',
})
expect(transformCss([['margin', 'auto 0']])).toEqual({
marginTop: 'auto',
marginRight: 0,
marginBottom: 'auto',
marginLeft: 0,
})
expect(transformCss([['margin', '2px 3px auto']])).toEqual({
marginTop: 2,
marginRight: 3,
marginBottom: 'auto',
marginLeft: 3,
})
expect(transformCss([['margin', '10px auto 4px']])).toEqual({
marginTop: 10,
marginRight: 'auto',
marginBottom: 4,
marginLeft: 'auto',
})
})
it('transforms border width', () => {
expect(transformCss([['border-width', '1px 2px 3px 4px']])).toEqual({
borderTopWidth: 1,
borderRightWidth: 2,
borderBottomWidth: 3,
borderLeftWidth: 4,
})
})
it('transforms border radius', () => {
expect(transformCss([['border-radius', '1px 2px 3px 4px']])).toEqual({
borderTopLeftRadius: 1,
borderTopRightRadius: 2,
borderBottomRightRadius: 3,
borderBottomLeftRadius: 4,
})
})

View file

@ -0,0 +1,83 @@
import transformCss from '..'
it('transforms box-shadow into shadow- properties', () => {
expect(transformCss([['box-shadow', '10px 20px 30px red']])).toEqual({
shadowOffset: { width: 10, height: 20 },
shadowRadius: 30,
shadowColor: 'red',
shadowOpacity: 1,
})
})
it('transforms box-shadow without blur-radius', () => {
expect(transformCss([['box-shadow', '10px 20px red']])).toEqual({
shadowOffset: { width: 10, height: 20 },
shadowRadius: 0,
shadowColor: 'red',
shadowOpacity: 1,
})
})
it('transforms box-shadow without color', () => {
expect(transformCss([['box-shadow', '10px 20px']])).toEqual({
shadowOffset: { width: 10, height: 20 },
shadowRadius: 0,
shadowColor: 'black',
shadowOpacity: 1,
})
})
it('transforms box-shadow with rgb color', () => {
expect(
transformCss([['box-shadow', '10px 20px rgb(100, 100, 100)']])
).toEqual({
shadowOffset: { width: 10, height: 20 },
shadowRadius: 0,
shadowColor: 'rgb(100, 100, 100)',
shadowOpacity: 1,
})
})
it('transforms box-shadow with rgba color', () => {
expect(
transformCss([['box-shadow', '10px 20px rgba(100, 100, 100, 0.5)']])
).toEqual({
shadowOffset: { width: 10, height: 20 },
shadowRadius: 0,
shadowColor: 'rgba(100, 100, 100, 0.5)',
shadowOpacity: 1,
})
})
it('transforms box-shadow with hsl color', () => {
expect(
transformCss([['box-shadow', '10px 20px hsl(120, 100%, 50%)']])
).toEqual({
shadowOffset: { width: 10, height: 20 },
shadowRadius: 0,
shadowColor: 'hsl(120, 100%, 50%)',
shadowOpacity: 1,
})
})
it('transforms box-shadow with hsla color', () => {
expect(
transformCss([['box-shadow', '10px 20px hsla(120, 100%, 50%, 0.7)']])
).toEqual({
shadowOffset: { width: 10, height: 20 },
shadowRadius: 0,
shadowColor: 'hsla(120, 100%, 50%, 0.7)',
shadowOpacity: 1,
})
})
it('transforms box-shadow and throws if multiple colors are used', () => {
expect(() =>
transformCss([['box-shadow', '0 0 0 red yellow green blue']])
).toThrow()
})
it('transforms box-shadow enforces offset to be present', () => {
expect(() => transformCss([['box-shadow', 'red']])).toThrow()
expect(() => transformCss([['box-shadow', '10px red']])).toThrow()
})

View file

@ -0,0 +1,31 @@
import transformCss from '..'
it('transforms hex colors', () => {
expect(transformCss([['color', '#f00']])).toEqual({ color: '#f00' })
})
it('transforms rgb colors', () => {
expect(transformCss([['color', 'rgb(255, 0, 0)']])).toEqual({
color: 'rgb(255, 0, 0)',
})
})
it('transforms transparent color', () => {
expect(transformCss([['color', 'transparent']])).toEqual({
color: 'transparent',
})
})
it('transforms border shorthand with transparent color', () => {
expect(transformCss([['border', '2px dashed transparent']])).toEqual({
borderColor: 'transparent',
borderStyle: 'dashed',
borderWidth: 2,
})
})
it('transforms background shorthand with transparent color', () => {
expect(transformCss([['background', 'transparent']])).toEqual({
backgroundColor: 'transparent',
})
})

122
node_modules/css-to-react-native/src/__tests__/flex.js generated vendored Normal file
View file

@ -0,0 +1,122 @@
import transformCss from '..'
it('transforms flex shorthand with 3 values', () => {
expect(transformCss([['flex', '1 2 3px']])).toEqual({
flexGrow: 1,
flexShrink: 2,
flexBasis: 3,
})
})
it('transforms flex shorthand with 3 values in reverse order', () => {
expect(transformCss([['flex', '3px 1 2']])).toEqual({
flexGrow: 1,
flexShrink: 2,
flexBasis: 3,
})
})
it('transforms flex shorthand with 2 values of flex-grow and flex-shrink', () => {
expect(transformCss([['flex', '1 2']])).toEqual({
flexGrow: 1,
flexShrink: 2,
flexBasis: 0,
})
})
it('transforms flex shorthand with 2 values of flex-grow and flex-basis', () => {
expect(transformCss([['flex', '2 2px']])).toEqual({
flexGrow: 2,
flexShrink: 1,
flexBasis: 2,
})
})
it('transforms flex shorthand with 2 values of flex-grow and flex-basis (reversed)', () => {
expect(transformCss([['flex', '2px 2']])).toEqual({
flexGrow: 2,
flexShrink: 1,
flexBasis: 2,
})
})
it('transforms flex shorthand with 1 value of flex-grow', () => {
expect(transformCss([['flex', '2']])).toEqual({
flexGrow: 2,
flexShrink: 1,
flexBasis: 0,
})
})
it('transforms flex shorthand with 1 value of flex-basis', () => {
expect(transformCss([['flex', '10px']])).toEqual({
flexGrow: 1,
flexShrink: 1,
flexBasis: 10,
})
})
/*
A unitless zero that is not already preceded by two flex factors must be interpreted as a flex
factor. To avoid misinterpretation or invalid declarations, authors must specify a zero
<flex-basis> component with a unit or precede it by two flex factors.
*/
it('transforms flex shorthand with flex-grow/shrink taking priority over basis', () => {
expect(transformCss([['flex', '0 1 0']])).toEqual({
flexGrow: 0,
flexShrink: 1,
flexBasis: 0,
})
})
it('transforms flex shorthand with flex-basis set to auto', () => {
expect(transformCss([['flex', '0 1 auto']])).toEqual({
flexGrow: 0,
flexShrink: 1,
flexBasis: 'auto',
})
})
it('transforms flex shorthand with flex-basis set to percent', () => {
expect(transformCss([['flex', '1 2 30%']])).toEqual({
flexGrow: 1,
flexShrink: 2,
flexBasis: '30%',
})
})
it('transforms flex shorthand with flex-basis set to unsupported unit', () => {
expect(transformCss([['flex', '1 2 30em']])).toEqual({
flexGrow: 1,
flexShrink: 2,
flexBasis: '30em',
})
})
it('transforms flex shorthand with flex-basis set to auto appearing first', () => {
expect(transformCss([['flex', 'auto 0 1']])).toEqual({
flexGrow: 0,
flexShrink: 1,
flexBasis: 'auto',
})
})
it('transforms flex auto keyword', () => {
expect(transformCss([['flex', 'auto']])).toEqual({
flexGrow: 1,
flexShrink: 1,
flexBasis: 'auto',
})
})
it('transforms flex none keyword', () => {
expect(transformCss([['flex', 'none']])).toEqual({
flexGrow: 0,
flexShrink: 0,
flexBasis: 'auto',
})
})
it('does not transform invalid flex', () => {
expect(() => transformCss([['flex', '1 2px 3']])).toThrow()
})

View file

@ -0,0 +1,22 @@
import transformCss from '..'
it('transforms flexFlow shorthand with two values', () => {
expect(transformCss([['flex-flow', 'column wrap']])).toEqual({
flexDirection: 'column',
flexWrap: 'wrap',
})
})
it('transforms flexFlow shorthand missing flexDirection', () => {
expect(transformCss([['flex-flow', 'wrap']])).toEqual({
flexDirection: 'row',
flexWrap: 'wrap',
})
})
it('transforms flexFlow shorthand missing flexWrap', () => {
expect(transformCss([['flex-flow', 'column']])).toEqual({
flexDirection: 'column',
flexWrap: 'nowrap',
})
})

117
node_modules/css-to-react-native/src/__tests__/font.js generated vendored Normal file
View file

@ -0,0 +1,117 @@
import transformCss from '..'
it('transforms font', () => {
expect(
transformCss([['font', 'bold italic small-caps 16px/18px "Helvetica"']])
).toEqual({
fontFamily: 'Helvetica',
fontSize: 16,
fontWeight: 'bold',
fontStyle: 'italic',
fontVariant: ['small-caps'],
lineHeight: 18,
})
})
it('transforms font missing font-variant', () => {
expect(transformCss([['font', 'bold italic 16px/18px "Helvetica"']])).toEqual(
{
fontFamily: 'Helvetica',
fontSize: 16,
fontWeight: 'bold',
fontStyle: 'italic',
fontVariant: [],
lineHeight: 18,
}
)
})
it('transforms font missing font-style', () => {
expect(
transformCss([['font', 'bold small-caps 16px/18px "Helvetica"']])
).toEqual({
fontFamily: 'Helvetica',
fontSize: 16,
fontWeight: 'bold',
fontStyle: 'normal',
fontVariant: ['small-caps'],
lineHeight: 18,
})
})
it('transforms font missing font-weight', () => {
expect(
transformCss([['font', 'italic small-caps 16px/18px "Helvetica"']])
).toEqual({
fontFamily: 'Helvetica',
fontSize: 16,
fontWeight: 'normal',
fontStyle: 'italic',
fontVariant: ['small-caps'],
lineHeight: 18,
})
})
it('transforms font with font-weight normal', () => {
expect(transformCss([['font', 'normal 16px/18px "Helvetica"']])).toEqual({
fontFamily: 'Helvetica',
fontSize: 16,
fontWeight: 'normal',
fontStyle: 'normal',
fontVariant: [],
lineHeight: 18,
})
})
it('transforms font with font-weight and font-style normal', () => {
expect(
transformCss([['font', 'normal normal 16px/18px "Helvetica"']])
).toEqual({
fontFamily: 'Helvetica',
fontSize: 16,
fontWeight: 'normal',
fontStyle: 'normal',
fontVariant: [],
lineHeight: 18,
})
})
it('transforms font with no font-weight, font-style, and font-variant', () => {
expect(transformCss([['font', '16px/18px "Helvetica"']])).toEqual({
fontFamily: 'Helvetica',
fontSize: 16,
fontWeight: 'normal',
fontStyle: 'normal',
fontVariant: [],
lineHeight: 18,
})
})
it('omits line height if not specified', () => {
expect(transformCss([['font', '16px "Helvetica"']])).toEqual({
fontFamily: 'Helvetica',
fontSize: 16,
fontWeight: 'normal',
fontStyle: 'normal',
fontVariant: [],
})
})
it('does not allow line height as multiple', () => {
expect(() => {
transformCss([['font', '16px/1.5 "Helvetica"']])
}).toThrow()
})
it('transforms font without quotes', () => {
expect(
transformCss([['font', 'bold italic small-caps 16px/18px Helvetica Neue']])
).toEqual({
fontFamily: 'Helvetica Neue',
fontSize: 16,
fontWeight: 'bold',
fontStyle: 'italic',
fontVariant: ['small-caps'],
lineHeight: 18,
})
})

View file

@ -0,0 +1,43 @@
import transformCss from '..'
it('transforms font-family with double quotes', () => {
expect(transformCss([['font-family', '"Helvetica Neue"']])).toEqual({
fontFamily: 'Helvetica Neue',
})
})
it('transforms font-family with single quotes', () => {
expect(transformCss([['font-family', "'Helvetica Neue'"]])).toEqual({
fontFamily: 'Helvetica Neue',
})
})
it('transforms font-family without quotes', () => {
expect(transformCss([['font-family', 'Helvetica Neue']])).toEqual({
fontFamily: 'Helvetica Neue',
})
})
it('transforms font-family with quotes with otherwise invalid values', () => {
expect(transformCss([['font-family', '"Goudy Bookletter 1911"']])).toEqual({
fontFamily: 'Goudy Bookletter 1911',
})
})
it('transforms font-family with quotes with escaped values', () => {
expect(transformCss([['font-family', '"test\\A test"']])).toEqual({
fontFamily: 'test\ntest',
})
})
it('transforms font-family with quotes with escaped quote', () => {
expect(transformCss([['font-family', '"test\\"test"']])).toEqual({
fontFamily: 'test"test',
})
})
it('does not transform invalid unquoted font-family', () => {
expect(() =>
transformCss([['font-family', 'Goudy Bookletter 1911']])
).toThrow()
})

View file

@ -0,0 +1,15 @@
import transformCss from '..'
it('transforms font variant as an array', () => {
expect(transformCss([['font-variant', 'tabular-nums']])).toEqual({
fontVariant: ['tabular-nums'],
})
})
it('transforms multiple font variant as an array', () => {
expect(
transformCss([['font-variant', 'tabular-nums oldstyle-nums']])
).toEqual({
fontVariant: ['tabular-nums', 'oldstyle-nums'],
})
})

View file

@ -0,0 +1,8 @@
import transformCss from '..'
it('transforms font weights as strings', () => {
expect(transformCss([['font-weight', '400']])).toEqual({ fontWeight: '400' })
expect(transformCss([['font-weight', 'bold']])).toEqual({
fontWeight: 'bold',
})
})

204
node_modules/css-to-react-native/src/__tests__/index.js generated vendored Normal file
View file

@ -0,0 +1,204 @@
import transformCss, { getStylesForProperty } from '..'
it('transforms numbers', () => {
expect(transformCss([['z-index', '0']])).toEqual({ zIndex: 0 })
})
it('warns if missing units on unspecialized transform', () => {
const consoleSpy = jest
.spyOn(global.console, 'warn')
.mockImplementation(() => {
// Silence the warning from the test output
})
transformCss([['top', '1']])
expect(consoleSpy).toHaveBeenCalledWith(
'Expected style "top: 1" to contain units'
)
consoleSpy.mockRestore()
})
it('does not warn for unitless 0 length on unspecialized transform', () => {
const consoleSpy = jest.spyOn(global.console, 'warn')
transformCss([['top', '0']])
expect(consoleSpy).not.toHaveBeenCalled()
consoleSpy.mockRestore()
})
it('warns if adding etraneous units on unspecialized transform', () => {
const consoleSpy = jest
.spyOn(global.console, 'warn')
.mockImplementation(() => {
// Silence the warning from the test output
})
transformCss([['opacity', '1px']])
expect(consoleSpy).toHaveBeenCalledWith(
'Expected style "opacity: 1px" to be unitless'
)
consoleSpy.mockRestore()
})
it('does not warn for unitless 0 length on unitless transform', () => {
const consoleSpy = jest.spyOn(global.console, 'warn')
transformCss([['opacity', '0']])
expect(consoleSpy).not.toHaveBeenCalled()
consoleSpy.mockRestore()
})
it('allows pixels in unspecialized transform', () => {
expect(transformCss([['top', '0px']])).toEqual({ top: 0 })
})
it('allows boolean values', () => {
expect(
transformCss([
['boolTrue1', 'true'],
['boolTrue2', 'TRUE'],
['boolFalse1', 'false'],
['boolFalse2', 'FALSE'],
])
).toEqual({
boolTrue1: true,
boolTrue2: true,
boolFalse1: false,
boolFalse2: false,
})
})
it('allows null values', () => {
expect(transformCss([['null1', 'null'], ['null2', 'NULL']])).toEqual({
null1: null,
null2: null,
})
})
it('allows undefined values', () => {
expect(
transformCss([['undefined1', 'undefined'], ['undefined2', 'UNDEFINED']])
).toEqual({
undefined1: undefined,
undefined2: undefined,
})
})
it('allows CSS custom properties to pass through', () => {
expect(transformCss([['--my-prop', '0%']])).toEqual({ '--my-prop': '0%' })
})
it('allows percent in unspecialized transform', () => {
expect(transformCss([['top', '0%']])).toEqual({ top: '0%' })
})
it('allows decimal values', () => {
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', () => {
expect(transformCss([['border-radius', '1.5px']])).toEqual({
borderTopLeftRadius: 1.5,
borderTopRightRadius: 1.5,
borderBottomRightRadius: 1.5,
borderBottomLeftRadius: 1.5,
})
})
it('allows negative values in transformed values', () => {
expect(transformCss([['border-radius', '-1.5px']])).toEqual({
borderTopLeftRadius: -1.5,
borderTopRightRadius: -1.5,
borderBottomRightRadius: -1.5,
borderBottomLeftRadius: -1.5,
})
})
it('allows uppercase units', () => {
expect(transformCss([['top', '0PX']])).toEqual({ top: 0 })
expect(transformCss([['transform', 'rotate(30DEG)']])).toEqual({
transform: [{ rotate: '30deg' }],
})
})
it('allows percent values in transformed values', () => {
expect(transformCss([['margin', '10%']])).toEqual({
marginTop: '10%',
marginRight: '10%',
marginBottom: '10%',
marginLeft: '10%',
})
})
it('allows color values in transformed border-color values', () => {
expect(transformCss([['border-color', 'red']])).toEqual({
borderTopColor: 'red',
borderRightColor: 'red',
borderBottomColor: 'red',
borderLeftColor: 'red',
})
})
it('allows omitting units for 0', () => {
expect(transformCss([['margin', '10px 0']])).toEqual({
marginTop: 10,
marginRight: 0,
marginBottom: 10,
marginLeft: 0,
})
})
it('transforms strings', () => {
expect(transformCss([['color', 'red']])).toEqual({ color: 'red' })
})
it('converts to camel-case', () => {
expect(transformCss([['background-color', 'red']])).toEqual({
backgroundColor: 'red',
})
})
it('transforms background to backgroundColor', () => {
expect(transformCss([['background', '#f00']])).toEqual({
backgroundColor: '#f00',
})
})
it('transforms background to backgroundColor with rgb', () => {
expect(transformCss([['background', 'rgb(255, 0, 0)']])).toEqual({
backgroundColor: 'rgb(255, 0, 0)',
})
})
it('transforms background to backgroundColor with named colour', () => {
expect(transformCss([['background', 'red']])).toEqual({
backgroundColor: 'red',
})
})
it('allows blacklisting shorthands', () => {
const actualStyles = transformCss(
[['border-radius', '50px']],
['borderRadius']
)
expect(actualStyles).toEqual({ borderRadius: 50 })
})
it('throws useful errors', () => {
expect(() => transformCss([['margin', '10']])).toThrow(
'Failed to parse declaration "margin: 10"'
)
})

View file

@ -0,0 +1,19 @@
import transformCss from '..'
it('transforms place content', () => {
expect(transformCss([['place-content', 'center center']])).toEqual({
alignContent: 'center',
justifyContent: 'center',
})
})
it('transforms place content with one value', () => {
expect(transformCss([['place-content', 'center']])).toEqual({
alignContent: 'center',
justifyContent: 'stretch',
})
})
it('does not allow justify content without align content', () => {
expect(() => transformCss([['place-content', 'space-evenly']])).toThrow()
})

View file

@ -0,0 +1,13 @@
import transformCss from '..'
it('transforms shadow offsets', () => {
expect(transformCss([['shadow-offset', '10px 5px']])).toEqual({
shadowOffset: { width: 10, height: 5 },
})
})
it('transforms text shadow offsets', () => {
expect(transformCss([['text-shadow-offset', '10px 5px']])).toEqual({
textShadowOffset: { width: 10, height: 5 },
})
})

View file

@ -0,0 +1,103 @@
import transformCss from '..'
it('transforms text-decoration into text-decoration- properties', () => {
expect(transformCss([['text-decoration', 'underline dotted red']])).toEqual({
textDecorationLine: 'underline',
textDecorationStyle: 'dotted',
textDecorationColor: 'red',
})
})
it('transforms text-decoration without color', () => {
expect(transformCss([['text-decoration', 'underline dotted']])).toEqual({
textDecorationLine: 'underline',
textDecorationStyle: 'dotted',
textDecorationColor: 'black',
})
})
it('transforms text-decoration without style', () => {
expect(transformCss([['text-decoration', 'underline red']])).toEqual({
textDecorationLine: 'underline',
textDecorationStyle: 'solid',
textDecorationColor: 'red',
})
})
it('transforms text-decoration without style and color', () => {
expect(transformCss([['text-decoration', 'underline']])).toEqual({
textDecorationLine: 'underline',
textDecorationStyle: 'solid',
textDecorationColor: 'black',
})
})
it('transforms text-decoration with two line properties', () => {
expect(
transformCss([['text-decoration', 'underline line-through dashed red']])
).toEqual({
textDecorationLine: 'underline line-through',
textDecorationStyle: 'dashed',
textDecorationColor: 'red',
})
})
it('transforms text-decoration in different order', () => {
expect(
transformCss([['text-decoration', 'dashed red underline line-through']])
).toEqual({
textDecorationLine: 'underline line-through',
textDecorationStyle: 'dashed',
textDecorationColor: 'red',
})
})
it('transforms text-decoration with ine in different order', () => {
expect(transformCss([['text-decoration', 'line-through underline']])).toEqual(
{
textDecorationLine: 'underline line-through',
textDecorationStyle: 'solid',
textDecorationColor: 'black',
}
)
})
it('transforms text-decoration with none', () => {
expect(transformCss([['text-decoration', 'none']])).toEqual({
textDecorationLine: 'none',
textDecorationStyle: 'solid',
textDecorationColor: 'black',
})
})
it('transforms text-decoration with none as part of multiple terms', () => {
expect(transformCss([['text-decoration', 'yellow none']])).toEqual({
textDecorationLine: 'none',
textDecorationStyle: 'solid',
textDecorationColor: 'yellow',
})
})
it('transforms text-decoration with none in capitals', () => {
expect(transformCss([['text-decoration', 'yellow NONE']])).toEqual({
textDecorationLine: 'none',
textDecorationStyle: 'solid',
textDecorationColor: 'yellow',
})
})
it('transforms text-decoration with style in capitals', () => {
expect(
transformCss([['text-decoration', 'yellow UNDERLINE LINE-THROUGH']])
).toEqual({
textDecorationLine: 'underline line-through',
textDecorationStyle: 'solid',
textDecorationColor: 'yellow',
})
})
it('does not transform text-decoration if multiple colors are used', () => {
expect(() =>
transformCss([['text-decoration', 'underline red yellow']])
).toThrow()
})

View file

@ -0,0 +1,23 @@
import transformCss from '..'
it('transforms text-decoration-line with underline line-through', () => {
expect(
transformCss([['text-decoration-line', 'underline line-through']])
).toEqual({
textDecorationLine: 'underline line-through',
})
})
it('transforms text-decoration-line with line-through underline', () => {
expect(
transformCss([['text-decoration-line', 'line-through underline']])
).toEqual({
textDecorationLine: 'underline line-through',
})
})
it('transforms text-decoration-line with none', () => {
expect(transformCss([['text-decoration-line', 'none']])).toEqual({
textDecorationLine: 'none',
})
})

View file

@ -0,0 +1,30 @@
import transformCss from '..'
it('textShadow with all values', () => {
expect(transformCss([['text-shadow', '10px 20px 30px red']])).toEqual({
textShadowOffset: { width: 10, height: 20 },
textShadowRadius: 30,
textShadowColor: 'red',
})
})
it('textShadow omitting blur', () => {
expect(transformCss([['text-shadow', '10px 20px red']])).toEqual({
textShadowOffset: { width: 10, height: 20 },
textShadowRadius: 0,
textShadowColor: 'red',
})
})
it('textShadow omitting color', () => {
expect(transformCss([['text-shadow', '10px 20px']])).toEqual({
textShadowOffset: { width: 10, height: 20 },
textShadowRadius: 0,
textShadowColor: 'black',
})
})
it('textShadow enforces offset-x and offset-y', () => {
expect(() => transformCss([['text-shadow', 'red']])).toThrow()
expect(() => transformCss([['text-shadow', '10px red']])).toThrow()
})

View file

@ -0,0 +1,55 @@
import transformCss from '..'
it('transforms a single transform value with number', () => {
expect(transformCss([['transform', 'scaleX(5)']])).toEqual({
transform: [{ scaleX: 5 }],
})
})
it('transforms a single transform value with string', () => {
expect(transformCss([['transform', 'rotate(5deg)']])).toEqual({
transform: [{ rotate: '5deg' }],
})
})
it('transforms multiple transform values', () => {
expect(transformCss([['transform', 'scaleX(5) skewX(1deg)']])).toEqual({
transform: [{ skewX: '1deg' }, { scaleX: 5 }],
})
})
it('transforms scale(number, number) to scaleX and scaleY', () => {
expect(transformCss([['transform', 'scale(2, 3)']])).toEqual({
transform: [{ scaleY: 3 }, { scaleX: 2 }],
})
})
it('transforms scale(number) to scale', () => {
expect(transformCss([['transform', 'scale(5)']])).toEqual({
transform: [{ scale: 5 }],
})
})
it('transforms translate(length, length) to translateX and translateY', () => {
expect(transformCss([['transform', 'translate(2px, 3px)']])).toEqual({
transform: [{ translateY: 3 }, { translateX: 2 }],
})
})
it('transforms translate(length) to translateX and translateY', () => {
expect(transformCss([['transform', 'translate(5px)']])).toEqual({
transform: [{ translateY: 0 }, { translateX: 5 }],
})
})
it('transforms skew(angle, angle) to skewX and skewY', () => {
expect(transformCss([['transform', 'skew(2deg, 3deg)']])).toEqual({
transform: [{ skewY: '3deg' }, { skewX: '2deg' }],
})
})
it('transforms skew(angle) to skewX and skewY', () => {
expect(transformCss([['transform', 'skew(5deg)']])).toEqual({
transform: [{ skewY: '0deg' }, { skewX: '5deg' }],
})
})

132
node_modules/css-to-react-native/src/__tests__/units.js generated vendored Normal file
View file

@ -0,0 +1,132 @@
import transformCss from '..'
// List of units from:
// https://developer.mozilla.org/en-US/docs/Web/CSS/length
const lengthUnits = [
'ch',
'em',
'ex',
'rem',
'vh',
'vw',
'vmin',
'vmax',
'cm',
'mm',
'in',
'pc',
'pt',
]
lengthUnits.forEach(unit => {
const value = `2${unit}`
it('allows CSS length units in transformed values', () => {
expect(transformCss([['margin', value]])).toEqual({
marginTop: value,
marginRight: value,
marginBottom: value,
marginLeft: value,
})
expect(transformCss([['padding', value]])).toEqual({
paddingTop: value,
paddingRight: value,
paddingBottom: value,
paddingLeft: value,
})
})
it('allows CSS length units with 0 and unit', () => {
expect(transformCss([['padding', `0${unit}`]])).toEqual({
paddingTop: `0${unit}`,
paddingRight: `0${unit}`,
paddingBottom: `0${unit}`,
paddingLeft: `0${unit}`,
})
})
it('allows mixed units in transformed values', () => {
expect(transformCss([['margin', `10px ${value}`]])).toEqual({
marginTop: 10,
marginRight: value,
marginBottom: 10,
marginLeft: value,
})
})
it('allows units to be used with border shorthand property', () => {
expect(transformCss([['border', `#f00 ${value} dashed`]])).toEqual({
borderWidth: value,
borderColor: '#f00',
borderStyle: 'dashed',
})
expect(transformCss([['border', value]])).toEqual({
borderWidth: value,
borderColor: 'black',
borderStyle: 'solid',
})
})
it('allows units to be used with border-width', () => {
expect(transformCss([['border-width', `1px 2px ${value} 4px`]])).toEqual({
borderTopWidth: 1,
borderRightWidth: 2,
borderBottomWidth: value,
borderLeftWidth: 4,
})
})
it('allows units to be used with border-radius', () => {
expect(transformCss([['border-radius', `1px ${value} 3px 4px`]])).toEqual({
borderTopLeftRadius: 1,
borderTopRightRadius: value,
borderBottomRightRadius: 3,
borderBottomLeftRadius: 4,
})
})
it('allows units to be used with font-size', () => {
expect(transformCss([['font-size', value]])).toEqual({
fontSize: value,
})
})
it('allows units to be used with font shorthand property', () => {
expect(
transformCss([['font', `bold italic ${value}/${value} "Helvetica"`]])
).toEqual({
fontFamily: 'Helvetica',
fontSize: value,
fontWeight: 'bold',
fontStyle: 'italic',
fontVariant: [],
lineHeight: value,
})
})
it('allows untis to be used with text-shadow ', () => {
expect(transformCss([['text-shadow', `10px ${value} red`]])).toEqual({
textShadowOffset: { width: 10, height: value },
textShadowRadius: 0,
textShadowColor: 'red',
})
})
it('allows untis to be used with box-shadow', () => {
expect(
transformCss([['box-shadow', `10px ${value} ${value} red`]])
).toEqual({
shadowOffset: { width: 10, height: value },
shadowRadius: value,
shadowColor: 'red',
shadowOpacity: 1,
})
})
})
it('throws for unit that is not supported', () => {
expect(() => transformCss([['margin', '10ic']])).toThrow(
'Failed to parse declaration "margin: 10ic"'
)
})

View file

@ -0,0 +1,19 @@
let propertiesWithoutUnits
if (process.env.NODE_ENV !== 'production') {
propertiesWithoutUnits = [
'aspectRatio',
'elevation',
'flexGrow',
'flexShrink',
'opacity',
'shadowOpacity',
'zIndex',
]
}
const devPropertiesWithUnitsRegExp =
propertiesWithoutUnits != null
? new RegExp(propertiesWithoutUnits.join('|'))
: null
export default devPropertiesWithUnitsRegExp

90
node_modules/css-to-react-native/src/index.js generated vendored Normal file
View file

@ -0,0 +1,90 @@
/* eslint-disable no-param-reassign */
import parse from 'postcss-value-parser'
import camelizeStyleName from 'camelize'
import transforms from './transforms/index'
import devPropertiesWithoutUnitsRegExp from './devPropertiesWithoutUnitsRegExp'
import TokenStream from './TokenStream'
// Note if this is wrong, you'll need to change tokenTypes.js too
const numberOrLengthRe = /^([+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?)(?:px)?$/i
const numberOnlyRe = /^[+-]?(?:\d*\.\d*|[1-9]\d*)(?:e[+-]?\d+)?$/i
const boolRe = /^true|false$/i
const nullRe = /^null$/i
const undefinedRe = /^undefined$/i
// Undocumented export
export const transformRawValue = (propName, value) => {
if (process.env.NODE_ENV !== 'production') {
const needsUnit = !devPropertiesWithoutUnitsRegExp.test(propName)
const isNumberWithoutUnit = numberOnlyRe.test(value)
if (needsUnit && isNumberWithoutUnit) {
// eslint-disable-next-line no-console
console.warn(`Expected style "${propName}: ${value}" to contain units`)
}
if (!needsUnit && value !== '0' && !isNumberWithoutUnit) {
// eslint-disable-next-line no-console
console.warn(`Expected style "${propName}: ${value}" to be unitless`)
}
}
const numberMatch = value.match(numberOrLengthRe)
if (numberMatch !== null) return Number(numberMatch[1])
const boolMatch = value.match(boolRe)
if (boolMatch !== null) return boolMatch[0].toLowerCase() === 'true'
const nullMatch = value.match(nullRe)
if (nullMatch !== null) return null
const undefinedMatch = value.match(undefinedRe)
if (undefinedMatch !== null) return undefined
return value
}
const baseTransformShorthandValue = (propName, value) => {
const ast = parse(value)
const tokenStream = new TokenStream(ast.nodes)
return transforms[propName](tokenStream)
}
const transformShorthandValue =
process.env.NODE_ENV === 'production'
? baseTransformShorthandValue
: (propName, value) => {
try {
return baseTransformShorthandValue(propName, value)
} catch (e) {
throw new Error(`Failed to parse declaration "${propName}: ${value}"`)
}
}
export const getStylesForProperty = (propName, inputValue, allowShorthand) => {
const isRawValue = allowShorthand === false || !(propName in transforms)
const value = inputValue.trim()
const propValues = isRawValue
? { [propName]: transformRawValue(propName, value) }
: transformShorthandValue(propName, value)
return propValues
}
export const getPropertyName = propName => {
const isCustomProp = /^--\w+/.test(propName)
if (isCustomProp) {
return propName
}
return camelizeStyleName(propName)
}
export default (rules, shorthandBlacklist = []) =>
rules.reduce((accum, rule) => {
const propertyName = getPropertyName(rule[0])
const value = rule[1]
const allowShorthand = shorthandBlacklist.indexOf(propertyName) === -1
return Object.assign(
accum,
getStylesForProperty(propertyName, value, allowShorthand)
)
}, {})

75
node_modules/css-to-react-native/src/tokenTypes.js generated vendored Normal file
View file

@ -0,0 +1,75 @@
import { stringify } from 'postcss-value-parser'
import cssColorKeywords from 'css-color-keywords'
const matchString = node => {
if (node.type !== 'string') return null
return node.value
.replace(/\\([0-9a-f]{1,6})(?:\s|$)/gi, (match, charCode) =>
String.fromCharCode(parseInt(charCode, 16))
)
.replace(/\\/g, '')
}
const hexColorRe = /^(#(?:[0-9a-f]{3,4}){1,2})$/i
const cssFunctionNameRe = /^(rgba?|hsla?|hwb|lab|lch|gray|color)$/
const matchColor = node => {
if (
node.type === 'word' &&
(hexColorRe.test(node.value) ||
node.value in cssColorKeywords ||
node.value === 'transparent')
) {
return node.value
} else if (node.type === 'function' && cssFunctionNameRe.test(node.value)) {
return stringify(node)
}
return null
}
const noneRe = /^(none)$/i
const autoRe = /^(auto)$/i
const identRe = /(^-?[_a-z][_a-z0-9-]*$)/i
// Note if these are wrong, you'll need to change index.js too
const numberRe = /^([+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?)$/i
// Note lengthRe is sneaky: you can omit units for 0
const lengthRe = /^(0$|(?:[+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?)(?=px$))/i
const unsupportedUnitRe = /^([+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?(ch|em|ex|rem|vh|vw|vmin|vmax|cm|mm|in|pc|pt))$/i
const angleRe = /^([+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?(?:deg|rad))$/i
const percentRe = /^([+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?%)$/i
const noopToken = predicate => node => (predicate(node) ? '<token>' : null)
const valueForTypeToken = type => node =>
node.type === type ? node.value : null
export const regExpToken = (regExp, transform = String) => node => {
if (node.type !== 'word') return null
const match = node.value.match(regExp)
if (match === null) return null
const value = transform(match[1])
return value
}
export const SPACE = noopToken(node => node.type === 'space')
export const SLASH = noopToken(
node => node.type === 'div' && node.value === '/'
)
export const COMMA = noopToken(
node => node.type === 'div' && node.value === ','
)
export const WORD = valueForTypeToken('word')
export const NONE = regExpToken(noneRe)
export const AUTO = regExpToken(autoRe)
export const NUMBER = regExpToken(numberRe, Number)
export const LENGTH = regExpToken(lengthRe, Number)
export const UNSUPPORTED_LENGTH_UNIT = regExpToken(unsupportedUnitRe)
export const ANGLE = regExpToken(angleRe, angle => angle.toLowerCase())
export const PERCENT = regExpToken(percentRe)
export const IDENT = regExpToken(identRe)
export const STRING = matchString
export const COLOR = matchColor
export const LINE = regExpToken(/^(none|underline|line-through)$/i)

View file

@ -0,0 +1,12 @@
import { NUMBER, SLASH } from '../tokenTypes'
export default tokenStream => {
let aspectRatio = tokenStream.expect(NUMBER)
if (tokenStream.hasTokens()) {
tokenStream.expect(SLASH)
aspectRatio /= tokenStream.expect(NUMBER)
}
return { aspectRatio }
}

View file

@ -0,0 +1,53 @@
import {
regExpToken,
NONE,
COLOR,
LENGTH,
UNSUPPORTED_LENGTH_UNIT,
SPACE,
} from '../tokenTypes'
const BORDER_STYLE = regExpToken(/^(solid|dashed|dotted)$/)
const defaultBorderWidth = 1
const defaultBorderColor = 'black'
const defaultBorderStyle = 'solid'
export default tokenStream => {
let borderWidth
let borderColor
let borderStyle
if (tokenStream.matches(NONE)) {
tokenStream.expectEmpty()
return { borderWidth: 0, borderColor: 'black', borderStyle: 'solid' }
}
let partsParsed = 0
while (partsParsed < 3 && tokenStream.hasTokens()) {
if (partsParsed !== 0) tokenStream.expect(SPACE)
if (
borderWidth === undefined &&
tokenStream.matches(LENGTH, UNSUPPORTED_LENGTH_UNIT)
) {
borderWidth = tokenStream.lastValue
} else if (borderColor === undefined && tokenStream.matches(COLOR)) {
borderColor = tokenStream.lastValue
} else if (borderStyle === undefined && tokenStream.matches(BORDER_STYLE)) {
borderStyle = tokenStream.lastValue
} else {
tokenStream.throw()
}
partsParsed += 1
}
tokenStream.expectEmpty()
if (borderWidth === undefined) borderWidth = defaultBorderWidth
if (borderColor === undefined) borderColor = defaultBorderColor
if (borderStyle === undefined) borderStyle = defaultBorderStyle
return { borderWidth, borderColor, borderStyle }
}

View file

@ -0,0 +1,11 @@
import { parseShadow } from './util'
export default tokenStream => {
const { offset, radius, color } = parseShadow(tokenStream)
return {
shadowOffset: offset,
shadowRadius: radius,
shadowColor: color,
shadowOpacity: 1,
}
}

View file

@ -0,0 +1,65 @@
import {
NONE,
AUTO,
NUMBER,
LENGTH,
UNSUPPORTED_LENGTH_UNIT,
PERCENT,
SPACE,
} from '../tokenTypes'
const defaultFlexGrow = 1
const defaultFlexShrink = 1
const defaultFlexBasis = 0
export default tokenStream => {
let flexGrow
let flexShrink
let flexBasis
if (tokenStream.matches(NONE)) {
tokenStream.expectEmpty()
return { flexGrow: 0, flexShrink: 0, flexBasis: 'auto' }
}
tokenStream.saveRewindPoint()
if (tokenStream.matches(AUTO) && !tokenStream.hasTokens()) {
return { flexGrow: 1, flexShrink: 1, flexBasis: 'auto' }
}
tokenStream.rewind()
let partsParsed = 0
while (partsParsed < 2 && tokenStream.hasTokens()) {
if (partsParsed !== 0) tokenStream.expect(SPACE)
if (flexGrow === undefined && tokenStream.matches(NUMBER)) {
flexGrow = tokenStream.lastValue
tokenStream.saveRewindPoint()
if (tokenStream.matches(SPACE) && tokenStream.matches(NUMBER)) {
flexShrink = tokenStream.lastValue
} else {
tokenStream.rewind()
}
} else if (
flexBasis === undefined &&
tokenStream.matches(LENGTH, UNSUPPORTED_LENGTH_UNIT, PERCENT)
) {
flexBasis = tokenStream.lastValue
} else if (flexBasis === undefined && tokenStream.matches(AUTO)) {
flexBasis = 'auto'
} else {
tokenStream.throw()
}
partsParsed += 1
}
tokenStream.expectEmpty()
if (flexGrow === undefined) flexGrow = defaultFlexGrow
if (flexShrink === undefined) flexShrink = defaultFlexShrink
if (flexBasis === undefined) flexBasis = defaultFlexBasis
return { flexGrow, flexShrink, flexBasis }
}

View file

@ -0,0 +1,37 @@
import { regExpToken, SPACE } from '../tokenTypes'
const FLEX_WRAP = regExpToken(/(nowrap|wrap|wrap-reverse)/)
const FLEX_DIRECTION = regExpToken(/(row|row-reverse|column|column-reverse)/)
const defaultFlexWrap = 'nowrap'
const defaultFlexDirection = 'row'
export default tokenStream => {
let flexWrap
let flexDirection
let partsParsed = 0
while (partsParsed < 2 && tokenStream.hasTokens()) {
if (partsParsed !== 0) tokenStream.expect(SPACE)
if (flexWrap === undefined && tokenStream.matches(FLEX_WRAP)) {
flexWrap = tokenStream.lastValue
} else if (
flexDirection === undefined &&
tokenStream.matches(FLEX_DIRECTION)
) {
flexDirection = tokenStream.lastValue
} else {
tokenStream.throw()
}
partsParsed += 1
}
tokenStream.expectEmpty()
if (flexWrap === undefined) flexWrap = defaultFlexWrap
if (flexDirection === undefined) flexDirection = defaultFlexDirection
return { flexWrap, flexDirection }
}

View file

@ -0,0 +1,63 @@
import parseFontFamily from './fontFamily'
import {
regExpToken,
SPACE,
LENGTH,
UNSUPPORTED_LENGTH_UNIT,
SLASH,
} from '../tokenTypes'
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 = []
export default tokenStream => {
let fontStyle
let fontWeight
let fontVariant
// let fontSize;
let lineHeight
// let fontFamily;
let numStyleWeightVariantMatched = 0
while (numStyleWeightVariantMatched < 3 && tokenStream.hasTokens()) {
if (tokenStream.matches(NORMAL)) {
/* pass */
} else if (fontStyle === undefined && tokenStream.matches(STYLE)) {
fontStyle = tokenStream.lastValue
} else if (fontWeight === undefined && tokenStream.matches(WEIGHT)) {
fontWeight = tokenStream.lastValue
} else if (fontVariant === undefined && tokenStream.matches(VARIANT)) {
fontVariant = [tokenStream.lastValue]
} else {
break
}
tokenStream.expect(SPACE)
numStyleWeightVariantMatched += 1
}
const fontSize = tokenStream.expect(LENGTH, UNSUPPORTED_LENGTH_UNIT)
if (tokenStream.matches(SLASH)) {
lineHeight = tokenStream.expect(LENGTH, UNSUPPORTED_LENGTH_UNIT)
}
tokenStream.expect(SPACE)
const { fontFamily } = parseFontFamily(tokenStream)
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
return out
}

View file

@ -0,0 +1,20 @@
import { SPACE, IDENT, STRING } from '../tokenTypes'
export default tokenStream => {
let fontFamily
if (tokenStream.matches(STRING)) {
fontFamily = tokenStream.lastValue
} else {
fontFamily = tokenStream.expect(IDENT)
while (tokenStream.hasTokens()) {
tokenStream.expect(SPACE)
const nextIdent = tokenStream.expect(IDENT)
fontFamily += ` ${nextIdent}`
}
}
tokenStream.expectEmpty()
return { fontFamily }
}

View file

@ -0,0 +1,14 @@
import { SPACE, IDENT } from '../tokenTypes'
export default tokenStream => {
const values = [tokenStream.expect(IDENT)]
while (tokenStream.hasTokens()) {
tokenStream.expect(SPACE)
values.push(tokenStream.expect(IDENT))
}
return {
fontVariant: values,
}
}

View file

@ -0,0 +1,77 @@
import {
AUTO,
COLOR,
LENGTH,
PERCENT,
UNSUPPORTED_LENGTH_UNIT,
WORD,
} from '../tokenTypes'
import aspectRatio from './aspectRatio'
import border from './border'
import boxShadow from './boxShadow'
import flex from './flex'
import flexFlow from './flexFlow'
import font from './font'
import fontFamily from './fontFamily'
import fontVariant from './fontVariant'
import placeContent from './placeContent'
import textDecoration from './textDecoration'
import textDecorationLine from './textDecorationLine'
import textShadow from './textShadow'
import transform from './transform'
import { directionFactory, parseShadowOffset } from './util'
const background = tokenStream => ({
backgroundColor: tokenStream.expect(COLOR),
})
const borderColor = directionFactory({
types: [COLOR],
prefix: 'border',
suffix: 'Color',
})
const borderRadius = directionFactory({
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' })
const fontWeight = tokenStream => ({
fontWeight: tokenStream.expect(WORD), // Also match numbers as strings
})
const shadowOffset = tokenStream => ({
shadowOffset: parseShadowOffset(tokenStream),
})
const textShadowOffset = tokenStream => ({
textShadowOffset: parseShadowOffset(tokenStream),
})
export default {
aspectRatio,
background,
border,
borderColor,
borderRadius,
borderWidth,
boxShadow,
flex,
flexFlow,
font,
fontFamily,
fontVariant,
fontWeight,
margin,
padding,
placeContent,
shadowOffset,
textShadow,
textShadowOffset,
textDecoration,
textDecorationLine,
transform,
}

View file

@ -0,0 +1,24 @@
import { regExpToken, SPACE } from '../tokenTypes'
const ALIGN_CONTENT = regExpToken(
/(flex-(?:start|end)|center|stretch|space-(?:between|around))/
)
const JUSTIFY_CONTENT = regExpToken(
/(flex-(?:start|end)|center|space-(?:between|around|evenly))/
)
export default tokenStream => {
const alignContent = tokenStream.expect(ALIGN_CONTENT)
let justifyContent
if (tokenStream.hasTokens()) {
tokenStream.expect(SPACE)
justifyContent = tokenStream.expect(JUSTIFY_CONTENT)
} else {
justifyContent = 'stretch'
}
tokenStream.expectEmpty()
return { alignContent, justifyContent }
}

View file

@ -0,0 +1,53 @@
import { regExpToken, SPACE, LINE, COLOR } from '../tokenTypes'
const STYLE = regExpToken(/^(solid|double|dotted|dashed)$/)
const defaultTextDecorationLine = 'none'
const defaultTextDecorationStyle = 'solid'
const defaultTextDecorationColor = 'black'
export default tokenStream => {
let line
let style
let color
let didParseFirst = false
while (tokenStream.hasTokens()) {
if (didParseFirst) tokenStream.expect(SPACE)
if (line === undefined && tokenStream.matches(LINE)) {
const lines = [tokenStream.lastValue.toLowerCase()]
tokenStream.saveRewindPoint()
if (
lines[0] !== 'none' &&
tokenStream.matches(SPACE) &&
tokenStream.matches(LINE)
) {
lines.push(tokenStream.lastValue.toLowerCase())
// Underline comes before line-through
lines.sort().reverse()
} else {
tokenStream.rewind()
}
line = lines.join(' ')
} else if (style === undefined && tokenStream.matches(STYLE)) {
style = tokenStream.lastValue
} else if (color === undefined && tokenStream.matches(COLOR)) {
color = tokenStream.lastValue
} else {
tokenStream.throw()
}
didParseFirst = true
}
return {
textDecorationLine: line !== undefined ? line : defaultTextDecorationLine,
textDecorationColor:
color !== undefined ? color : defaultTextDecorationColor,
textDecorationStyle:
style !== undefined ? style : defaultTextDecorationStyle,
}
}

View file

@ -0,0 +1,18 @@
import { SPACE, LINE } from '../tokenTypes'
export default tokenStream => {
const lines = []
let didParseFirst = false
while (tokenStream.hasTokens()) {
if (didParseFirst) tokenStream.expect(SPACE)
lines.push(tokenStream.expect(LINE).toLowerCase())
didParseFirst = true
}
lines.sort().reverse()
return { textDecorationLine: lines.join(' ') }
}

View file

@ -0,0 +1,10 @@
import { parseShadow } from './util'
export default tokenStream => {
const { offset, radius, color } = parseShadow(tokenStream)
return {
textShadowOffset: offset,
textShadowRadius: radius,
textShadowColor: color,
}
}

View file

@ -0,0 +1,74 @@
import { SPACE, COMMA, LENGTH, NUMBER, ANGLE } from '../tokenTypes'
const oneOfType = tokenType => functionStream => {
const value = functionStream.expect(tokenType)
functionStream.expectEmpty()
return value
}
const singleNumber = oneOfType(NUMBER)
const singleLength = oneOfType(LENGTH)
const singleAngle = oneOfType(ANGLE)
const xyTransformFactory = tokenType => (
key,
valueIfOmitted
) => functionStream => {
const x = functionStream.expect(tokenType)
let y
if (functionStream.hasTokens()) {
functionStream.expect(COMMA)
y = functionStream.expect(tokenType)
} else if (valueIfOmitted !== undefined) {
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
}
functionStream.expectEmpty()
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'),
scaleX: singleNumber,
scaleY: singleNumber,
translate: xyLength('translate', 0),
translateX: singleLength,
translateY: singleLength,
rotate: singleAngle,
rotateX: singleAngle,
rotateY: singleAngle,
rotateZ: singleAngle,
skewX: singleAngle,
skewY: singleAngle,
skew: xyAngle('skew', '0deg'),
}
export default tokenStream => {
let transforms = []
let didParseFirst = false
while (tokenStream.hasTokens()) {
if (didParseFirst) tokenStream.expect(SPACE)
const functionStream = tokenStream.expectFunction()
const { functionName } = functionStream
let transformedValues = partTransforms[functionName](functionStream)
if (!Array.isArray(transformedValues)) {
transformedValues = [{ [functionName]: transformedValues }]
}
transforms = transformedValues.concat(transforms)
didParseFirst = true
}
return { transform: transforms }
}

View file

@ -0,0 +1,99 @@
import {
LENGTH,
UNSUPPORTED_LENGTH_UNIT,
PERCENT,
COLOR,
SPACE,
NONE,
} from '../tokenTypes'
export const directionFactory = ({
types = [LENGTH, UNSUPPORTED_LENGTH_UNIT, PERCENT],
directions = ['Top', 'Right', 'Bottom', 'Left'],
prefix = '',
suffix = '',
}) => tokenStream => {
const values = []
// borderWidth doesn't currently allow a percent value, but may do in the future
values.push(tokenStream.expect(...types))
while (values.length < 4 && tokenStream.hasTokens()) {
tokenStream.expect(SPACE)
values.push(tokenStream.expect(...types))
}
tokenStream.expectEmpty()
const [top, right = top, bottom = top, left = right] = values
const keyFor = n => `${prefix}${directions[n]}${suffix}`
return {
[keyFor(0)]: top,
[keyFor(1)]: right,
[keyFor(2)]: bottom,
[keyFor(3)]: left,
}
}
export const parseShadowOffset = tokenStream => {
const width = tokenStream.expect(LENGTH)
const height = tokenStream.matches(SPACE) ? tokenStream.expect(LENGTH) : width
tokenStream.expectEmpty()
return { width, height }
}
export const parseShadow = tokenStream => {
let offsetX
let offsetY
let radius
let color
if (tokenStream.matches(NONE)) {
tokenStream.expectEmpty()
return {
offset: { width: 0, height: 0 },
radius: 0,
color: 'black',
}
}
let didParseFirst = false
while (tokenStream.hasTokens()) {
if (didParseFirst) tokenStream.expect(SPACE)
if (
offsetX === undefined &&
tokenStream.matches(LENGTH, UNSUPPORTED_LENGTH_UNIT)
) {
offsetX = tokenStream.lastValue
tokenStream.expect(SPACE)
offsetY = tokenStream.expect(LENGTH, UNSUPPORTED_LENGTH_UNIT)
tokenStream.saveRewindPoint()
if (
tokenStream.matches(SPACE) &&
tokenStream.matches(LENGTH, UNSUPPORTED_LENGTH_UNIT)
) {
radius = tokenStream.lastValue
} else {
tokenStream.rewind()
}
} else if (color === undefined && tokenStream.matches(COLOR)) {
color = tokenStream.lastValue
} else {
tokenStream.throw()
}
didParseFirst = true
}
if (offsetX === undefined) tokenStream.throw()
return {
offset: { width: offsetX, height: offsetY },
radius: radius !== undefined ? radius : 0,
color: color !== undefined ? color : 'black',
}
}