@cssxjs/css-to-react-native 3.2.0-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -0
- package/README.md +115 -0
- package/index.d.ts +17 -0
- package/index.js +930 -0
- package/package.json +68 -0
- package/src/TokenStream.js +74 -0
- package/src/__tests__/aspectRatio.js +23 -0
- package/src/__tests__/border.js +141 -0
- package/src/__tests__/borderColor.js +92 -0
- package/src/__tests__/boxModel.js +136 -0
- package/src/__tests__/boxShadow.js +167 -0
- package/src/__tests__/colors.js +31 -0
- package/src/__tests__/flex.js +122 -0
- package/src/__tests__/flexFlow.js +22 -0
- package/src/__tests__/font.js +117 -0
- package/src/__tests__/fontFamily.js +43 -0
- package/src/__tests__/fontVariant.js +15 -0
- package/src/__tests__/fontWeight.js +8 -0
- package/src/__tests__/index.js +238 -0
- package/src/__tests__/placeContent.js +19 -0
- package/src/__tests__/shadowOffsets.js +13 -0
- package/src/__tests__/textDecoration.js +165 -0
- package/src/__tests__/textDecorationLine.js +23 -0
- package/src/__tests__/textShadow.js +107 -0
- package/src/__tests__/transform.js +69 -0
- package/src/__tests__/units.js +132 -0
- package/src/devPropertiesWithoutUnitsRegExp.js +19 -0
- package/src/index.js +90 -0
- package/src/tokenTypes.js +112 -0
- package/src/transforms/aspectRatio.js +12 -0
- package/src/transforms/border.js +57 -0
- package/src/transforms/boxShadow.js +11 -0
- package/src/transforms/flex.js +65 -0
- package/src/transforms/flexFlow.js +37 -0
- package/src/transforms/font.js +63 -0
- package/src/transforms/fontFamily.js +20 -0
- package/src/transforms/fontVariant.js +14 -0
- package/src/transforms/index.js +78 -0
- package/src/transforms/placeContent.js +24 -0
- package/src/transforms/textDecoration.js +56 -0
- package/src/transforms/textDecorationLine.js +18 -0
- package/src/transforms/textShadow.js +10 -0
- package/src/transforms/transform.js +74 -0
- package/src/transforms/util.js +103 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import transformCss from '..'
|
|
2
|
+
|
|
3
|
+
it('transforms text-decoration into text-decoration- properties', () => {
|
|
4
|
+
expect(transformCss([['text-decoration', 'underline dotted red']])).toEqual({
|
|
5
|
+
textDecorationLine: 'underline',
|
|
6
|
+
textDecorationStyle: 'dotted',
|
|
7
|
+
textDecorationColor: 'red',
|
|
8
|
+
})
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
it('transforms text-decoration without color', () => {
|
|
12
|
+
expect(transformCss([['text-decoration', 'underline dotted']])).toEqual({
|
|
13
|
+
textDecorationLine: 'underline',
|
|
14
|
+
textDecorationStyle: 'dotted',
|
|
15
|
+
textDecorationColor: 'black',
|
|
16
|
+
})
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
it('transforms text-decoration without style', () => {
|
|
20
|
+
expect(transformCss([['text-decoration', 'underline red']])).toEqual({
|
|
21
|
+
textDecorationLine: 'underline',
|
|
22
|
+
textDecorationStyle: 'solid',
|
|
23
|
+
textDecorationColor: 'red',
|
|
24
|
+
})
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
it('transforms text-decoration without style and color', () => {
|
|
28
|
+
expect(transformCss([['text-decoration', 'underline']])).toEqual({
|
|
29
|
+
textDecorationLine: 'underline',
|
|
30
|
+
textDecorationStyle: 'solid',
|
|
31
|
+
textDecorationColor: 'black',
|
|
32
|
+
})
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('transforms text-decoration with two line properties', () => {
|
|
36
|
+
expect(
|
|
37
|
+
transformCss([['text-decoration', 'underline line-through dashed red']])
|
|
38
|
+
).toEqual({
|
|
39
|
+
textDecorationLine: 'underline line-through',
|
|
40
|
+
textDecorationStyle: 'dashed',
|
|
41
|
+
textDecorationColor: 'red',
|
|
42
|
+
})
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('transforms text-decoration in different order', () => {
|
|
46
|
+
expect(
|
|
47
|
+
transformCss([['text-decoration', 'dashed red underline line-through']])
|
|
48
|
+
).toEqual({
|
|
49
|
+
textDecorationLine: 'underline line-through',
|
|
50
|
+
textDecorationStyle: 'dashed',
|
|
51
|
+
textDecorationColor: 'red',
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it('transforms text-decoration with ine in different order', () => {
|
|
56
|
+
expect(transformCss([['text-decoration', 'line-through underline']])).toEqual(
|
|
57
|
+
{
|
|
58
|
+
textDecorationLine: 'underline line-through',
|
|
59
|
+
textDecorationStyle: 'solid',
|
|
60
|
+
textDecorationColor: 'black',
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it('transforms text-decoration with none', () => {
|
|
66
|
+
expect(transformCss([['text-decoration', 'none']])).toEqual({
|
|
67
|
+
textDecorationLine: 'none',
|
|
68
|
+
textDecorationStyle: 'solid',
|
|
69
|
+
textDecorationColor: 'black',
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it('transforms text-decoration with none as part of multiple terms', () => {
|
|
74
|
+
expect(transformCss([['text-decoration', 'yellow none']])).toEqual({
|
|
75
|
+
textDecorationLine: 'none',
|
|
76
|
+
textDecorationStyle: 'solid',
|
|
77
|
+
textDecorationColor: 'yellow',
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
it('transforms text-decoration with none in capitals', () => {
|
|
82
|
+
expect(transformCss([['text-decoration', 'yellow NONE']])).toEqual({
|
|
83
|
+
textDecorationLine: 'none',
|
|
84
|
+
textDecorationStyle: 'solid',
|
|
85
|
+
textDecorationColor: 'yellow',
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('transforms text-decoration with style in capitals', () => {
|
|
90
|
+
expect(
|
|
91
|
+
transformCss([['text-decoration', 'yellow UNDERLINE LINE-THROUGH']])
|
|
92
|
+
).toEqual({
|
|
93
|
+
textDecorationLine: 'underline line-through',
|
|
94
|
+
textDecorationStyle: 'solid',
|
|
95
|
+
textDecorationColor: 'yellow',
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('does not transform text-decoration if multiple colors are used', () => {
|
|
100
|
+
expect(() =>
|
|
101
|
+
transformCss([['text-decoration', 'underline red yellow']])
|
|
102
|
+
).toThrow()
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
it('transforms text-decoration with var() for color', () => {
|
|
106
|
+
expect(
|
|
107
|
+
transformCss([['text-decoration', 'underline var(--primary-color)']])
|
|
108
|
+
).toEqual({
|
|
109
|
+
textDecorationLine: 'underline',
|
|
110
|
+
textDecorationStyle: 'solid',
|
|
111
|
+
textDecorationColor: 'var(--primary-color)',
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
it('transforms text-decoration with var() and style', () => {
|
|
116
|
+
expect(
|
|
117
|
+
transformCss([['text-decoration', 'underline dotted var(--primary-color)']])
|
|
118
|
+
).toEqual({
|
|
119
|
+
textDecorationLine: 'underline',
|
|
120
|
+
textDecorationStyle: 'dotted',
|
|
121
|
+
textDecorationColor: 'var(--primary-color)',
|
|
122
|
+
})
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
it('transforms text-decoration with var() and fallback', () => {
|
|
126
|
+
expect(
|
|
127
|
+
transformCss([['text-decoration', 'underline var(--primary-color, red)']])
|
|
128
|
+
).toEqual({
|
|
129
|
+
textDecorationLine: 'underline',
|
|
130
|
+
textDecorationStyle: 'solid',
|
|
131
|
+
textDecorationColor: 'var(--primary-color, red)',
|
|
132
|
+
})
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
it('transforms text-decoration with var() and hex fallback', () => {
|
|
136
|
+
expect(
|
|
137
|
+
transformCss([['text-decoration', 'underline var(--primary-color, #f00)']])
|
|
138
|
+
).toEqual({
|
|
139
|
+
textDecorationLine: 'underline',
|
|
140
|
+
textDecorationStyle: 'solid',
|
|
141
|
+
textDecorationColor: 'var(--primary-color, #f00)',
|
|
142
|
+
})
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
it('transforms text-decoration with var() and rgb fallback', () => {
|
|
146
|
+
expect(
|
|
147
|
+
transformCss([
|
|
148
|
+
['text-decoration', 'underline var(--primary-color, rgb(255, 0, 0))'],
|
|
149
|
+
])
|
|
150
|
+
).toEqual({
|
|
151
|
+
textDecorationLine: 'underline',
|
|
152
|
+
textDecorationStyle: 'solid',
|
|
153
|
+
textDecorationColor: 'var(--primary-color, rgb(255,0,0))',
|
|
154
|
+
})
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
it('transforms text-decoration with var() in different order', () => {
|
|
158
|
+
expect(
|
|
159
|
+
transformCss([['text-decoration', 'var(--primary-color) underline dotted']])
|
|
160
|
+
).toEqual({
|
|
161
|
+
textDecorationLine: 'underline',
|
|
162
|
+
textDecorationStyle: 'dotted',
|
|
163
|
+
textDecorationColor: 'var(--primary-color)',
|
|
164
|
+
})
|
|
165
|
+
})
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import transformCss from '..'
|
|
2
|
+
|
|
3
|
+
it('transforms text-decoration-line with underline line-through', () => {
|
|
4
|
+
expect(
|
|
5
|
+
transformCss([['text-decoration-line', 'underline line-through']])
|
|
6
|
+
).toEqual({
|
|
7
|
+
textDecorationLine: 'underline line-through',
|
|
8
|
+
})
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
it('transforms text-decoration-line with line-through underline', () => {
|
|
12
|
+
expect(
|
|
13
|
+
transformCss([['text-decoration-line', 'line-through underline']])
|
|
14
|
+
).toEqual({
|
|
15
|
+
textDecorationLine: 'underline line-through',
|
|
16
|
+
})
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
it('transforms text-decoration-line with none', () => {
|
|
20
|
+
expect(transformCss([['text-decoration-line', 'none']])).toEqual({
|
|
21
|
+
textDecorationLine: 'none',
|
|
22
|
+
})
|
|
23
|
+
})
|
|
@@ -0,0 +1,107 @@
|
|
|
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 color', () => {
|
|
20
|
+
expect(transformCss([['text-shadow', '10px 20px']])).toEqual({
|
|
21
|
+
textShadowOffset: { width: 10, height: 20 },
|
|
22
|
+
textShadowRadius: 0,
|
|
23
|
+
textShadowColor: 'black',
|
|
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 with var() for color', () => {
|
|
33
|
+
expect(
|
|
34
|
+
transformCss([['text-shadow', '10px 20px var(--primary-color)']])
|
|
35
|
+
).toEqual({
|
|
36
|
+
textShadowOffset: { width: 10, height: 20 },
|
|
37
|
+
textShadowRadius: 0,
|
|
38
|
+
textShadowColor: 'var(--primary-color)',
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('textShadow with var() and blur-radius', () => {
|
|
43
|
+
expect(
|
|
44
|
+
transformCss([['text-shadow', '10px 20px 30px var(--primary-color)']])
|
|
45
|
+
).toEqual({
|
|
46
|
+
textShadowOffset: { width: 10, height: 20 },
|
|
47
|
+
textShadowRadius: 30,
|
|
48
|
+
textShadowColor: 'var(--primary-color)',
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('textShadow with var() and named color fallback', () => {
|
|
53
|
+
expect(
|
|
54
|
+
transformCss([['text-shadow', '10px 20px var(--primary-color, red)']])
|
|
55
|
+
).toEqual({
|
|
56
|
+
textShadowOffset: { width: 10, height: 20 },
|
|
57
|
+
textShadowRadius: 0,
|
|
58
|
+
textShadowColor: 'var(--primary-color, red)',
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
it('textShadow with var() and hex color fallback', () => {
|
|
63
|
+
expect(
|
|
64
|
+
transformCss([['text-shadow', '10px 20px var(--primary-color, #f00)']])
|
|
65
|
+
).toEqual({
|
|
66
|
+
textShadowOffset: { width: 10, height: 20 },
|
|
67
|
+
textShadowRadius: 0,
|
|
68
|
+
textShadowColor: 'var(--primary-color, #f00)',
|
|
69
|
+
})
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
it('textShadow with var() and rgb color fallback', () => {
|
|
73
|
+
expect(
|
|
74
|
+
transformCss([
|
|
75
|
+
['text-shadow', '10px 20px var(--primary-color, rgb(255, 0, 0))'],
|
|
76
|
+
])
|
|
77
|
+
).toEqual({
|
|
78
|
+
textShadowOffset: { width: 10, height: 20 },
|
|
79
|
+
textShadowRadius: 0,
|
|
80
|
+
textShadowColor: 'var(--primary-color, rgb(255,0,0))',
|
|
81
|
+
})
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
it('textShadow with var() and rgba color fallback', () => {
|
|
85
|
+
expect(
|
|
86
|
+
transformCss([
|
|
87
|
+
[
|
|
88
|
+
'text-shadow',
|
|
89
|
+
'10px 20px var(--primary-color, rgba(100, 100, 100, 0.5))',
|
|
90
|
+
],
|
|
91
|
+
])
|
|
92
|
+
).toEqual({
|
|
93
|
+
textShadowOffset: { width: 10, height: 20 },
|
|
94
|
+
textShadowRadius: 0,
|
|
95
|
+
textShadowColor: 'var(--primary-color, rgba(100,100,100,0.5))',
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('textShadow with var() color before offset', () => {
|
|
100
|
+
expect(
|
|
101
|
+
transformCss([['text-shadow', 'var(--primary-color) 10px 20px 30px']])
|
|
102
|
+
).toEqual({
|
|
103
|
+
textShadowOffset: { width: 10, height: 20 },
|
|
104
|
+
textShadowRadius: 30,
|
|
105
|
+
textShadowColor: 'var(--primary-color)',
|
|
106
|
+
})
|
|
107
|
+
})
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import transformCss from '..'
|
|
2
|
+
|
|
3
|
+
it('transforms a single transform value with number', () => {
|
|
4
|
+
expect(transformCss([['transform', 'scaleX(5)']])).toEqual({
|
|
5
|
+
transform: [{ scaleX: 5 }],
|
|
6
|
+
})
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
it('transforms a single transform value with string', () => {
|
|
10
|
+
expect(transformCss([['transform', 'rotate(5deg)']])).toEqual({
|
|
11
|
+
transform: [{ rotate: '5deg' }],
|
|
12
|
+
})
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it('transforms a single transform value with percentage', () => {
|
|
16
|
+
expect(transformCss([['transform', 'translate(100%, 100%)']])).toEqual({
|
|
17
|
+
transform: [{ translateY: '100%' }, { translateX: '100%' }],
|
|
18
|
+
})
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('transforms multiple transform values with percentage', () => {
|
|
22
|
+
expect(
|
|
23
|
+
transformCss([['transform', 'translateY(100%) translateX(100%)']])
|
|
24
|
+
).toEqual({
|
|
25
|
+
transform: [{ translateX: '100%' }, { translateY: '100%' }],
|
|
26
|
+
})
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('transforms multiple transform values', () => {
|
|
30
|
+
expect(transformCss([['transform', 'scaleX(5) skewX(1deg)']])).toEqual({
|
|
31
|
+
transform: [{ skewX: '1deg' }, { scaleX: 5 }],
|
|
32
|
+
})
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('transforms scale(number, number) to scaleX and scaleY', () => {
|
|
36
|
+
expect(transformCss([['transform', 'scale(2, 3)']])).toEqual({
|
|
37
|
+
transform: [{ scaleY: 3 }, { scaleX: 2 }],
|
|
38
|
+
})
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it('transforms scale(number) to scale', () => {
|
|
42
|
+
expect(transformCss([['transform', 'scale(5)']])).toEqual({
|
|
43
|
+
transform: [{ scale: 5 }],
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('transforms translate(length, length) to translateX and translateY', () => {
|
|
48
|
+
expect(transformCss([['transform', 'translate(2px, 3px)']])).toEqual({
|
|
49
|
+
transform: [{ translateY: 3 }, { translateX: 2 }],
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('transforms translate(length) to translateX and translateY', () => {
|
|
54
|
+
expect(transformCss([['transform', 'translate(5px)']])).toEqual({
|
|
55
|
+
transform: [{ translateY: 0 }, { translateX: 5 }],
|
|
56
|
+
})
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('transforms skew(angle, angle) to skewX and skewY', () => {
|
|
60
|
+
expect(transformCss([['transform', 'skew(2deg, 3deg)']])).toEqual({
|
|
61
|
+
transform: [{ skewY: '3deg' }, { skewX: '2deg' }],
|
|
62
|
+
})
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it('transforms skew(angle) to skewX and skewY', () => {
|
|
66
|
+
expect(transformCss([['transform', 'skew(5deg)']])).toEqual({
|
|
67
|
+
transform: [{ skewY: '0deg' }, { skewX: '5deg' }],
|
|
68
|
+
})
|
|
69
|
+
})
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import transformCss from '..'
|
|
2
|
+
|
|
3
|
+
// List of units from:
|
|
4
|
+
// https://developer.mozilla.org/en-US/docs/Web/CSS/length
|
|
5
|
+
const lengthUnits = [
|
|
6
|
+
'ch',
|
|
7
|
+
'em',
|
|
8
|
+
'ex',
|
|
9
|
+
'rem',
|
|
10
|
+
'vh',
|
|
11
|
+
'vw',
|
|
12
|
+
'vmin',
|
|
13
|
+
'vmax',
|
|
14
|
+
'cm',
|
|
15
|
+
'mm',
|
|
16
|
+
'in',
|
|
17
|
+
'pc',
|
|
18
|
+
'pt',
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
lengthUnits.forEach(unit => {
|
|
22
|
+
const value = `2${unit}`
|
|
23
|
+
|
|
24
|
+
it('allows CSS length units in transformed values', () => {
|
|
25
|
+
expect(transformCss([['margin', value]])).toEqual({
|
|
26
|
+
marginTop: value,
|
|
27
|
+
marginRight: value,
|
|
28
|
+
marginBottom: value,
|
|
29
|
+
marginLeft: value,
|
|
30
|
+
})
|
|
31
|
+
expect(transformCss([['padding', value]])).toEqual({
|
|
32
|
+
paddingTop: value,
|
|
33
|
+
paddingRight: value,
|
|
34
|
+
paddingBottom: value,
|
|
35
|
+
paddingLeft: value,
|
|
36
|
+
})
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('allows CSS length units with 0 and unit', () => {
|
|
40
|
+
expect(transformCss([['padding', `0${unit}`]])).toEqual({
|
|
41
|
+
paddingTop: `0${unit}`,
|
|
42
|
+
paddingRight: `0${unit}`,
|
|
43
|
+
paddingBottom: `0${unit}`,
|
|
44
|
+
paddingLeft: `0${unit}`,
|
|
45
|
+
})
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it('allows mixed units in transformed values', () => {
|
|
49
|
+
expect(transformCss([['margin', `10px ${value}`]])).toEqual({
|
|
50
|
+
marginTop: 10,
|
|
51
|
+
marginRight: value,
|
|
52
|
+
marginBottom: 10,
|
|
53
|
+
marginLeft: value,
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it('allows units to be used with border shorthand property', () => {
|
|
58
|
+
expect(transformCss([['border', `#f00 ${value} dashed`]])).toEqual({
|
|
59
|
+
borderWidth: value,
|
|
60
|
+
borderColor: '#f00',
|
|
61
|
+
borderStyle: 'dashed',
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
expect(transformCss([['border', value]])).toEqual({
|
|
65
|
+
borderWidth: value,
|
|
66
|
+
borderColor: 'black',
|
|
67
|
+
borderStyle: 'solid',
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
it('allows units to be used with border-width', () => {
|
|
72
|
+
expect(transformCss([['border-width', `1px 2px ${value} 4px`]])).toEqual({
|
|
73
|
+
borderTopWidth: 1,
|
|
74
|
+
borderRightWidth: 2,
|
|
75
|
+
borderBottomWidth: value,
|
|
76
|
+
borderLeftWidth: 4,
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('allows units to be used with border-radius', () => {
|
|
81
|
+
expect(transformCss([['border-radius', `1px ${value} 3px 4px`]])).toEqual({
|
|
82
|
+
borderTopLeftRadius: 1,
|
|
83
|
+
borderTopRightRadius: value,
|
|
84
|
+
borderBottomRightRadius: 3,
|
|
85
|
+
borderBottomLeftRadius: 4,
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('allows units to be used with font-size', () => {
|
|
90
|
+
expect(transformCss([['font-size', value]])).toEqual({
|
|
91
|
+
fontSize: value,
|
|
92
|
+
})
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it('allows units to be used with font shorthand property', () => {
|
|
96
|
+
expect(
|
|
97
|
+
transformCss([['font', `bold italic ${value}/${value} "Helvetica"`]])
|
|
98
|
+
).toEqual({
|
|
99
|
+
fontFamily: 'Helvetica',
|
|
100
|
+
fontSize: value,
|
|
101
|
+
fontWeight: 'bold',
|
|
102
|
+
fontStyle: 'italic',
|
|
103
|
+
fontVariant: [],
|
|
104
|
+
lineHeight: value,
|
|
105
|
+
})
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
it('allows untis to be used with text-shadow ', () => {
|
|
109
|
+
expect(transformCss([['text-shadow', `10px ${value} red`]])).toEqual({
|
|
110
|
+
textShadowOffset: { width: 10, height: value },
|
|
111
|
+
textShadowRadius: 0,
|
|
112
|
+
textShadowColor: 'red',
|
|
113
|
+
})
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it('allows untis to be used with box-shadow', () => {
|
|
117
|
+
expect(
|
|
118
|
+
transformCss([['box-shadow', `10px ${value} ${value} red`]])
|
|
119
|
+
).toEqual({
|
|
120
|
+
shadowOffset: { width: 10, height: value },
|
|
121
|
+
shadowRadius: value,
|
|
122
|
+
shadowColor: 'red',
|
|
123
|
+
shadowOpacity: 1,
|
|
124
|
+
})
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
it('throws for unit that is not supported', () => {
|
|
129
|
+
expect(() => transformCss([['margin', '10ic']])).toThrow(
|
|
130
|
+
'Failed to parse declaration "margin: 10ic"'
|
|
131
|
+
)
|
|
132
|
+
})
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
let propertiesWithoutUnits
|
|
2
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
3
|
+
propertiesWithoutUnits = [
|
|
4
|
+
'aspectRatio',
|
|
5
|
+
'elevation',
|
|
6
|
+
'flexGrow',
|
|
7
|
+
'flexShrink',
|
|
8
|
+
'opacity',
|
|
9
|
+
'shadowOpacity',
|
|
10
|
+
'zIndex',
|
|
11
|
+
]
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const devPropertiesWithUnitsRegExp =
|
|
15
|
+
propertiesWithoutUnits != null
|
|
16
|
+
? new RegExp(propertiesWithoutUnits.join('|'))
|
|
17
|
+
: null
|
|
18
|
+
|
|
19
|
+
export default devPropertiesWithUnitsRegExp
|
package/src/index.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/* eslint-disable no-param-reassign */
|
|
2
|
+
import parse from 'postcss-value-parser'
|
|
3
|
+
import camelizeStyleName from 'camelize'
|
|
4
|
+
import transforms from './transforms/index'
|
|
5
|
+
import devPropertiesWithoutUnitsRegExp from './devPropertiesWithoutUnitsRegExp'
|
|
6
|
+
import TokenStream from './TokenStream'
|
|
7
|
+
|
|
8
|
+
// Note if this is wrong, you'll need to change tokenTypes.js too
|
|
9
|
+
const numberOrLengthRe = /^([+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?)(?:px)?$/i
|
|
10
|
+
const numberOnlyRe = /^[+-]?(?:\d*\.\d*|[1-9]\d*)(?:e[+-]?\d+)?$/i
|
|
11
|
+
const boolRe = /^true|false$/i
|
|
12
|
+
const nullRe = /^null$/i
|
|
13
|
+
const undefinedRe = /^undefined$/i
|
|
14
|
+
|
|
15
|
+
// Undocumented export
|
|
16
|
+
export const transformRawValue = (propName, value) => {
|
|
17
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
18
|
+
const needsUnit = !devPropertiesWithoutUnitsRegExp.test(propName)
|
|
19
|
+
const isNumberWithoutUnit = numberOnlyRe.test(value)
|
|
20
|
+
if (needsUnit && isNumberWithoutUnit) {
|
|
21
|
+
// eslint-disable-next-line no-console
|
|
22
|
+
console.warn(`Expected style "${propName}: ${value}" to contain units`)
|
|
23
|
+
}
|
|
24
|
+
if (!needsUnit && value !== '0' && !isNumberWithoutUnit) {
|
|
25
|
+
// eslint-disable-next-line no-console
|
|
26
|
+
console.warn(`Expected style "${propName}: ${value}" to be unitless`)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const numberMatch = value.match(numberOrLengthRe)
|
|
31
|
+
if (numberMatch !== null) return Number(numberMatch[1])
|
|
32
|
+
|
|
33
|
+
const boolMatch = value.match(boolRe)
|
|
34
|
+
if (boolMatch !== null) return boolMatch[0].toLowerCase() === 'true'
|
|
35
|
+
|
|
36
|
+
const nullMatch = value.match(nullRe)
|
|
37
|
+
if (nullMatch !== null) return null
|
|
38
|
+
|
|
39
|
+
const undefinedMatch = value.match(undefinedRe)
|
|
40
|
+
if (undefinedMatch !== null) return undefined
|
|
41
|
+
|
|
42
|
+
return value
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const baseTransformShorthandValue = (propName, value) => {
|
|
46
|
+
const ast = parse(value)
|
|
47
|
+
const tokenStream = new TokenStream(ast.nodes)
|
|
48
|
+
return transforms[propName](tokenStream)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const transformShorthandValue =
|
|
52
|
+
process.env.NODE_ENV === 'production'
|
|
53
|
+
? baseTransformShorthandValue
|
|
54
|
+
: (propName, value) => {
|
|
55
|
+
try {
|
|
56
|
+
return baseTransformShorthandValue(propName, value)
|
|
57
|
+
} catch (e) {
|
|
58
|
+
throw new Error(`Failed to parse declaration "${propName}: ${value}"`)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const getStylesForProperty = (propName, inputValue, allowShorthand) => {
|
|
63
|
+
const isRawValue = allowShorthand === false || !(propName in transforms)
|
|
64
|
+
const value = inputValue.trim()
|
|
65
|
+
|
|
66
|
+
const propValues = isRawValue
|
|
67
|
+
? { [propName]: transformRawValue(propName, value) }
|
|
68
|
+
: transformShorthandValue(propName, value)
|
|
69
|
+
|
|
70
|
+
return propValues
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export const getPropertyName = propName => {
|
|
74
|
+
const isCustomProp = /^--\w+/.test(propName)
|
|
75
|
+
if (isCustomProp) {
|
|
76
|
+
return propName
|
|
77
|
+
}
|
|
78
|
+
return camelizeStyleName(propName)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export default (rules, shorthandBlacklist = []) =>
|
|
82
|
+
rules.reduce((accum, rule) => {
|
|
83
|
+
const propertyName = getPropertyName(rule[0])
|
|
84
|
+
const value = rule[1]
|
|
85
|
+
const allowShorthand = shorthandBlacklist.indexOf(propertyName) === -1
|
|
86
|
+
return Object.assign(
|
|
87
|
+
accum,
|
|
88
|
+
getStylesForProperty(propertyName, value, allowShorthand)
|
|
89
|
+
)
|
|
90
|
+
}, {})
|