Skip to content

Commit ba73205

Browse files
committed
Implement text shadow, unify text & box shadow, improve spec compliance, begin new test layout
1 parent f91597d commit ba73205

File tree

9 files changed

+1866
-1079
lines changed

9 files changed

+1866
-1079
lines changed

.eslintrc.js

+6
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,10 @@ module.exports = {
44
rules: {
55
'prettier/prettier': 2,
66
},
7+
overrides: [
8+
{
9+
files: '**/__tests__/*.js',
10+
env: { jest: true },
11+
},
12+
],
713
}

package.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@
3434
},
3535
"homepage": "https://github.com/styled-components/css-to-react-native#readme",
3636
"devDependencies": {
37-
"babel-cli": "^6.18.0",
38-
"babel-preset-es2015": "^6.18.0",
39-
"eslint": "^3.9.1",
40-
"eslint-config-airbnb-base": "^10.0.1",
37+
"babel-cli": "^6.26.0",
38+
"babel-preset-es2015": "^6.24.1",
39+
"eslint": "^4.17.0",
40+
"eslint-config-airbnb-base": "^12.1.0",
4141
"eslint-config-prettier": "^2.9.0",
42-
"eslint-plugin-import": "^2.2.0",
42+
"eslint-plugin-import": "^2.8.0",
4343
"eslint-plugin-prettier": "^2.6.0",
44-
"jest": "^17.0.0",
44+
"jest": "^22.2.2",
4545
"lint-staged": "^6.1.0",
4646
"prettier": "^1.10.2"
4747
},

src/index.test.js

+8-21
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* global jest it, expect */
1+
/* global it, expect */
22
import transformCss, { getStylesForProperty } from '.'
33

44
const runTest = (inputCss, expectedStyles) => {
@@ -489,22 +489,6 @@ it('transforms box-shadow without blur-radius', () =>
489489
shadowOpacity: 1,
490490
}))
491491

492-
it('transforms box-shadow without color', () =>
493-
runTest([['box-shadow', '10px 20px 30px']], {
494-
shadowOffset: { width: 10, height: 20 },
495-
shadowRadius: 30,
496-
shadowColor: 'black',
497-
shadowOpacity: 1,
498-
}))
499-
500-
it('transforms box-shadow without blur-radius, color', () =>
501-
runTest([['box-shadow', '10px 20px']], {
502-
shadowOffset: { width: 10, height: 20 },
503-
shadowRadius: 0,
504-
shadowColor: 'black',
505-
shadowOpacity: 1,
506-
}))
507-
508492
it('transforms box-shadow with rgb color', () =>
509493
runTest([['box-shadow', '10px 20px rgb(100, 100, 100)']], {
510494
shadowOffset: { width: 10, height: 20 },
@@ -551,10 +535,13 @@ it('transforms box-shadow enforces offset to be present', () => {
551535
)
552536
})
553537

554-
it('transforms box-shadow and enforces offset-y if offset-x present', () => {
555-
expect(() => transformCss([['box-shadow', '10px']])).toThrow(
556-
'Failed to parse declaration "boxShadow: 10px"'
557-
)
538+
it('transforms box-shadow and enforces offset-x and offset-y', () => {
539+
expect(() => transformCss([['box-shadow', 'black']])).toThrow()
540+
expect(() => transformCss([['box-shadow', '10px black']])).toThrow()
541+
})
542+
543+
it('transforms box-shadow and enforces color', () => {
544+
expect(() => transformCss([['text-decoration', '10px 20px 30px']])).toThrow()
558545
})
559546

560547
it('transforms text-decoration into text-decoration- properties', () =>
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import transformCss from '../..'
2+
3+
it('textShadow with all values', () => {
4+
expect(transformCss([['text-shadow', '10px 20px 30px red']])).toEqual({
5+
textShadowOffset: { width: 10, height: 20 },
6+
textShadowRadius: 30,
7+
textShadowColor: 'red',
8+
})
9+
})
10+
11+
it('textShadow omitting blur', () => {
12+
expect(transformCss([['text-shadow', '10px 20px red']])).toEqual({
13+
textShadowOffset: { width: 10, height: 20 },
14+
textShadowRadius: 0,
15+
textShadowColor: 'red',
16+
})
17+
})
18+
19+
it('textShadow omitting blur, offset-y', () => {
20+
expect(transformCss([['text-shadow', '10px 20px red']])).toEqual({
21+
textShadowOffset: { width: 10, height: 20 },
22+
textShadowRadius: 0,
23+
textShadowColor: 'red',
24+
})
25+
})
26+
27+
it('textShadow enforces offset-x and offset-y', () => {
28+
expect(() => transformCss([['text-shadow', 'red']])).toThrow()
29+
expect(() => transformCss([['text-shadow', '10px red']])).toThrow()
30+
})
31+
32+
it('textShadow enforces color', () => {
33+
expect(() => transformCss([['text-shadow', '10px 20px']])).toThrow()
34+
})

src/transforms/boxShadow.js

+9-52
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,13 @@
1-
const { tokens } = require('../tokenTypes')
2-
3-
const { NONE, SPACE, COLOR, LENGTH } = tokens
1+
const { parseShadow } = require('./util')
42

53
module.exports = tokenStream => {
6-
let offsetX
7-
let offsetY
8-
let blurRadius
9-
let color
10-
11-
if (tokenStream.matches(NONE)) {
12-
tokenStream.expectEmpty()
13-
return {
14-
$merge: {
15-
shadowOffset: { width: 0, height: 0 },
16-
shadowRadius: 0,
17-
shadowColor: 'black',
18-
shadowOpacity: 1,
19-
},
20-
}
21-
}
22-
23-
let didParseFirst = false
24-
while (tokenStream.hasTokens()) {
25-
if (didParseFirst) tokenStream.expect(SPACE)
26-
27-
if (offsetX === undefined && tokenStream.matches(LENGTH)) {
28-
offsetX = tokenStream.lastValue
29-
tokenStream.expect(SPACE)
30-
offsetY = tokenStream.expect(LENGTH)
31-
32-
tokenStream.saveRewindPoint()
33-
if (tokenStream.matches(SPACE) && tokenStream.matches(LENGTH)) {
34-
blurRadius = tokenStream.lastValue
35-
} else {
36-
tokenStream.rewind()
37-
}
38-
} else if (color === undefined && tokenStream.matches(COLOR)) {
39-
color = tokenStream.lastValue
40-
} else {
41-
tokenStream.throw()
42-
}
43-
44-
didParseFirst = true
45-
}
46-
47-
if (offsetX === undefined) tokenStream.throw()
48-
49-
const $merge = {
50-
shadowOffset: { width: offsetX, height: offsetY },
51-
shadowRadius: blurRadius !== undefined ? blurRadius : 0,
52-
shadowColor: color !== undefined ? color : 'black',
53-
shadowOpacity: 1,
4+
const { offset, radius, color } = parseShadow(tokenStream)
5+
return {
6+
$merge: {
7+
shadowOffset: offset,
8+
shadowRadius: radius,
9+
shadowColor: color,
10+
shadowOpacity: 1,
11+
},
5412
}
55-
return { $merge }
5613
}

src/transforms/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const boxShadow = require('./boxShadow')
33
const flex = require('./flex')
44
const font = require('./font')
55
const fontFamily = require('./fontFamily')
6+
const textShadow = require('./textShadow')
67
const textDecoration = require('./textDecoration')
78
const transform = require('./transform')
89
const {
@@ -74,6 +75,7 @@ module.exports = {
7475
margin,
7576
padding,
7677
shadowOffset,
78+
textShadow,
7779
textShadowOffset,
7880
textDecoration,
7981
transform,

src/transforms/textShadow.js

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const { parseShadow } = require('./util')
2+
3+
module.exports = tokenStream => {
4+
const { offset, radius, color } = parseShadow(tokenStream)
5+
return {
6+
$merge: {
7+
textShadowOffset: offset,
8+
textShadowRadius: radius,
9+
textShadowColor: color,
10+
},
11+
}
12+
}

src/transforms/util.js

+49-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const { tokens } = require('../tokenTypes')
22

3-
const { LENGTH, PERCENT, SPACE } = tokens
3+
const { LENGTH, PERCENT, COLOR, SPACE, NONE } = tokens
44

55
module.exports.directionFactory = ({
66
types = [LENGTH, PERCENT],
@@ -76,3 +76,51 @@ module.exports.shadowOffsetFactory = () => tokenStream => {
7676
tokenStream.expectEmpty()
7777
return { width, height }
7878
}
79+
80+
module.exports.parseShadow = tokenStream => {
81+
let offsetX
82+
let offsetY
83+
let radius = 0
84+
let color
85+
86+
if (tokenStream.matches(NONE)) {
87+
tokenStream.expectEmpty()
88+
return {
89+
offset: { width: 0, height: 0 },
90+
radius: 0,
91+
color: 'black',
92+
}
93+
}
94+
95+
let didParseFirst = false
96+
while (tokenStream.hasTokens()) {
97+
if (didParseFirst) tokenStream.expect(SPACE)
98+
99+
if (offsetX === undefined && tokenStream.matches(LENGTH)) {
100+
offsetX = tokenStream.lastValue
101+
tokenStream.expect(SPACE)
102+
offsetY = tokenStream.expect(LENGTH)
103+
104+
tokenStream.saveRewindPoint()
105+
if (tokenStream.matches(SPACE) && tokenStream.matches(LENGTH)) {
106+
radius = tokenStream.lastValue
107+
} else {
108+
tokenStream.rewind()
109+
}
110+
} else if (color === undefined && tokenStream.matches(COLOR)) {
111+
color = tokenStream.lastValue
112+
} else {
113+
tokenStream.throw()
114+
}
115+
116+
didParseFirst = true
117+
}
118+
119+
if (offsetX === undefined || color === undefined) tokenStream.throw()
120+
121+
return {
122+
offset: { width: offsetX, height: offsetY },
123+
radius,
124+
color,
125+
}
126+
}

0 commit comments

Comments
 (0)