Skip to content

Commit 646c3fd

Browse files
committed
Housekeeping
1 parent 6dce838 commit 646c3fd

File tree

16 files changed

+3615
-2526
lines changed

16 files changed

+3615
-2526
lines changed

.babelrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{ "presets": ["es2015"] }
1+
{ "presets": ["@babel/preset-env"] }

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
/node_modules
22
/index.js
3-
/package-lock.json

.npmrc

Lines changed: 0 additions & 1 deletion
This file was deleted.

index.d.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
1+
export type StyleTuple = [string, string]
2+
13
export interface Style {
2-
[key: string]: string | number | Style;
4+
[key: string]: string | number | Style
35
}
46

5-
export function getPropertyName(name: string): string;
6-
export function getStylesForProperty(name: string, value: string, allowShorthand?: boolean): Style;
7+
export function getPropertyName(name: string): string
8+
export function getStylesForProperty(
9+
name: string,
10+
value: string,
11+
allowShorthand?: boolean
12+
): Style
713

8-
export default function transform(css: Array<[string, string]>, shorthandBlacklist?: string[]): Style;
14+
export default function transform(
15+
styleTuples: StyleTuple[],
16+
shorthandBlacklist?: string[]
17+
): Style

package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "css-to-react-native",
3-
"version": "2.3.2",
3+
"version": "3.0.0",
44
"description": "Convert CSS text to a React Native stylesheet object",
55
"main": "index.js",
66
"scripts": {
@@ -37,22 +37,22 @@
3737
"testURL": "http://localhost"
3838
},
3939
"devDependencies": {
40-
"babel-cli": "^6.26.0",
41-
"babel-preset-es2015": "^6.24.1",
40+
"@babel/cli": "^6.26.0",
41+
"@babel/preset-env": "^6.24.1",
4242
"eslint": "^4.17.0",
4343
"eslint-config-airbnb-base": "^12.1.0",
4444
"eslint-config-prettier": "^2.9.0",
4545
"eslint-plugin-import": "^2.8.0",
4646
"eslint-plugin-prettier": "^2.6.0",
47-
"jest": "^22.2.2",
47+
"jest": "^24.9.0",
4848
"lint-staged": "^6.1.0",
49-
"prettier": "^1.10.2",
50-
"rollup": "^0.55.5"
49+
"prettier": "^1.18.2",
50+
"rollup": "^1.22.0"
5151
},
5252
"dependencies": {
5353
"camelize": "^1.0.0",
5454
"css-color-keywords": "^1.0.0",
55-
"postcss-value-parser": "^3.3.0"
55+
"postcss-value-parser": "^4.0.2"
5656
},
5757
"lint-staged": {
5858
"*.js": [

src/__tests__/border.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,15 @@ it('transforms border shorthand missing color & style', () => {
7171
borderStyle: 'solid',
7272
})
7373
})
74+
75+
it('transforms border for unsupported units', () => {
76+
expect(transformCss([['border', '3em solid black']])).toEqual({
77+
borderWidth: '3em',
78+
borderColor: 'black',
79+
borderStyle: 'solid',
80+
})
81+
})
82+
83+
it('does not transform border with percentage width', () => {
84+
expect(() => transformCss([['border', '3% solid black']])).toThrow()
85+
})

src/__tests__/flex.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,22 @@ it('transforms flex shorthand with flex-basis set to auto', () => {
7777
})
7878
})
7979

80+
it('transforms flex shorthand with flex-basis set to percent', () => {
81+
expect(transformCss([['flex', '1 2 30%']])).toEqual({
82+
flexGrow: 1,
83+
flexShrink: 2,
84+
flexBasis: '30%',
85+
})
86+
})
87+
88+
it('transforms flex shorthand with flex-basis set to unsupported unit', () => {
89+
expect(transformCss([['flex', '1 2 30em']])).toEqual({
90+
flexGrow: 1,
91+
flexShrink: 2,
92+
flexBasis: '30em',
93+
})
94+
})
95+
8096
it('transforms flex shorthand with flex-basis set to auto appearing first', () => {
8197
expect(transformCss([['flex', 'auto 0 1']])).toEqual({
8298
flexGrow: 0,

src/__tests__/index.js

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,31 @@
11
import transformCss, { getStylesForProperty } from '..'
22

33
it('transforms numbers', () => {
4-
expect(
5-
transformCss([['top', '0'], ['left', '0'], ['right', '0'], ['bottom', '0']])
6-
).toEqual({
7-
top: 0,
8-
left: 0,
9-
right: 0,
10-
bottom: 0,
11-
})
4+
expect(transformCss([['zIndex', '0']])).toEqual({ zIndex: 0 })
5+
})
6+
7+
it('warns if missing units on unspecialized transform', () => {
8+
const consoleSpy = jest
9+
.spyOn(global.console, 'warn')
10+
.mockImplementation(() => {
11+
// Silence the warning from the test output
12+
})
13+
14+
transformCss([['top', '1']])
15+
expect(consoleSpy).toHaveBeenCalledWith(
16+
'Expected style "top: 1" to contain units'
17+
)
18+
19+
consoleSpy.mockRestore()
20+
})
21+
22+
it('does not warn for unitless 0 length on unspecialized transform', () => {
23+
const consoleSpy = jest.spyOn(global.console, 'warn')
24+
25+
transformCss([['top', '0']])
26+
expect(consoleSpy).not.toHaveBeenCalled()
27+
28+
consoleSpy.mockRestore()
1229
})
1330

1431
it('allows pixels in unspecialized transform', () => {

src/__tests__/placeContent.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import transformCss from '..'
2+
3+
it('transforms place content', () => {
4+
expect(transformCss([['place-content', 'center center']])).toEqual({
5+
alignContent: 'center',
6+
justifyContent: 'center',
7+
})
8+
})
9+
10+
it('transforms place content with one value', () => {
11+
expect(transformCss([['place-content', 'center']])).toEqual({
12+
alignContent: 'center',
13+
justifyContent: 'stretch',
14+
})
15+
})
16+
17+
it('does not allow justify content without align content', () => {
18+
expect(() => transformCss([['place-content', 'space-everly']])).toThrow()
19+
})
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
let propertiesWitouthUnits
2+
if (process.env.NODE_ENV !== 'production') {
3+
propertiesWitouthUnits = [
4+
'aspectRatio',
5+
'elevation',
6+
'flexGrow',
7+
'flexShrink',
8+
'opacity',
9+
'shadowOpacity',
10+
'zIndex',
11+
]
12+
}
13+
14+
const devPropertiesWithUnitsRegExp =
15+
propertiesWitouthUnits != null
16+
? new RegExp(propertiesWitouthUnits.join('|'))
17+
: null
18+
19+
export default devPropertiesWithUnitsRegExp

src/index.js

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,57 +2,67 @@
22
import parse from 'postcss-value-parser'
33
import camelizeStyleName from 'camelize'
44
import transforms from './transforms/index'
5+
import devPropertiesWithoutUnitsRegExp from './devPropertiesWithoutUnitsRegExp'
56
import TokenStream from './TokenStream'
67

78
// Note if this is wrong, you'll need to change tokenTypes.js too
89
const numberOrLengthRe = /^([+-]?(?:\d*\.)?\d+(?:[Ee][+-]?\d+)?)(?:px)?$/i
910
const boolRe = /^true|false$/i
1011
const nullRe = /^null$/i
1112
const undefinedRe = /^undefined$/i
13+
const numberOnlyRe = /^[1-9.-][\d.Ee+-]*$/
1214

1315
// Undocumented export
14-
export const transformRawValue = input => {
15-
const value = input.trim()
16+
export const transformRawValue = (propName, value) => {
17+
if (process.env.NODE_ENV !== 'production') {
18+
if (
19+
!devPropertiesWithoutUnitsRegExp.test(propName) &&
20+
numberOnlyRe.test(value)
21+
) {
22+
// eslint-disable-next-line no-console
23+
console.warn(`Expected style "${propName}: ${value}" to contain units`)
24+
}
25+
}
1626

1727
const numberMatch = value.match(numberOrLengthRe)
1828
if (numberMatch !== null) return Number(numberMatch[1])
1929

20-
const boolMatch = input.match(boolRe)
30+
const boolMatch = value.match(boolRe)
2131
if (boolMatch !== null) return boolMatch[0].toLowerCase() === 'true'
2232

23-
const nullMatch = input.match(nullRe)
33+
const nullMatch = value.match(nullRe)
2434
if (nullMatch !== null) return null
2535

26-
const undefinedMatch = input.match(undefinedRe)
36+
const undefinedMatch = value.match(undefinedRe)
2737
if (undefinedMatch !== null) return undefined
2838

2939
return value
3040
}
3141

32-
const baseTransformShorthandValue = (propName, inputValue) => {
33-
const ast = parse(inputValue.trim())
42+
const baseTransformShorthandValue = (propName, value) => {
43+
const ast = parse(value)
3444
const tokenStream = new TokenStream(ast.nodes)
3545
return transforms[propName](tokenStream)
3646
}
3747

3848
const transformShorthandValue =
3949
process.env.NODE_ENV === 'production'
4050
? baseTransformShorthandValue
41-
: (propName, inputValue) => {
51+
: (propName, value) => {
4252
try {
43-
return baseTransformShorthandValue(propName, inputValue)
53+
return baseTransformShorthandValue(propName, value)
4454
} catch (e) {
45-
throw new Error(
46-
`Failed to parse declaration "${propName}: ${inputValue}"`
47-
)
55+
throw new Error(`Failed to parse declaration "${propName}: ${value}"`)
4856
}
4957
}
5058

5159
export const getStylesForProperty = (propName, inputValue, allowShorthand) => {
5260
const isRawValue = allowShorthand === false || !(propName in transforms)
61+
const value = inputValue.trim()
62+
5363
const propValues = isRawValue
54-
? { [propName]: transformRawValue(inputValue) }
55-
: transformShorthandValue(propName, inputValue.trim())
64+
? { [propName]: transformRawValue(propName, value) }
65+
: transformShorthandValue(propName, value)
5666

5767
return propValues
5868
}

src/transforms/border.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ export default tokenStream => {
2323
if (partsParsed !== 0) tokenStream.expect(SPACE)
2424

2525
if (
26-
(borderWidth === undefined && tokenStream.matches(LENGTH)) ||
27-
tokenStream.matches(UNSUPPORTED_LENGTH_UNIT)
26+
borderWidth === undefined &&
27+
tokenStream.matches(LENGTH, UNSUPPORTED_LENGTH_UNIT)
2828
) {
2929
borderWidth = tokenStream.lastValue
3030
} else if (borderColor === undefined && tokenStream.matches(COLOR)) {

src/transforms/flex.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
import { tokens } from '../tokenTypes'
22

3-
const { NONE, AUTO, NUMBER, LENGTH, SPACE } = tokens
3+
const {
4+
NONE,
5+
AUTO,
6+
NUMBER,
7+
LENGTH,
8+
UNSUPPORTED_LENGTH_UNIT,
9+
PERCENT,
10+
SPACE,
11+
} = tokens
412

513
const defaultFlexGrow = 1
614
const defaultFlexShrink = 1
@@ -35,7 +43,10 @@ export default tokenStream => {
3543
} else {
3644
tokenStream.rewind()
3745
}
38-
} else if (flexBasis === undefined && tokenStream.matches(LENGTH)) {
46+
} else if (
47+
flexBasis === undefined &&
48+
tokenStream.matches(LENGTH, UNSUPPORTED_LENGTH_UNIT, PERCENT)
49+
) {
3950
flexBasis = tokenStream.lastValue
4051
} else if (flexBasis === undefined && tokenStream.matches(AUTO)) {
4152
flexBasis = 'auto'

src/transforms/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import flex from './flex'
55
import flexFlow from './flexFlow'
66
import font from './font'
77
import fontFamily from './fontFamily'
8+
import placeContent from './placeContent'
89
import textDecoration from './textDecoration'
910
import textDecorationLine from './textDecorationLine'
1011
import textShadow from './textShadow'
@@ -68,6 +69,7 @@ export default {
6869
fontWeight,
6970
margin,
7071
padding,
72+
placeContent,
7173
shadowOffset,
7274
textShadow,
7375
textShadowOffset,

src/transforms/placeContent.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { regExpToken, tokens } from '../tokenTypes'
2+
3+
const { SPACE } = tokens
4+
5+
const ALIGN_CONTENT = regExpToken(
6+
/(flex-(?:start|end)|center|stretch|space-(?:between|around))/
7+
)
8+
const JUSTIFY_CONTENT = regExpToken(
9+
/(flex-(?:start|end)|center|space-(?:between|around|evenly))/
10+
)
11+
12+
export default tokenStream => {
13+
const alignContent = tokenStream.expect(ALIGN_CONTENT)
14+
15+
let justifyContent
16+
if (tokenStream.hasTokens()) {
17+
tokenStream.expect(SPACE)
18+
justifyContent = tokenStream.expect(JUSTIFY_CONTENT)
19+
} else {
20+
justifyContent = 'stretch'
21+
}
22+
23+
tokenStream.expectEmpty()
24+
25+
return { alignContent, justifyContent }
26+
}

0 commit comments

Comments
 (0)