@react-pdf/stylesheet 5.2.1 → 6.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/lib/index.d.ts +284 -0
- package/lib/index.js +673 -678
- package/package.json +4 -4
package/lib/index.js
CHANGED
|
@@ -1,768 +1,763 @@
|
|
|
1
1
|
import { compose, castArray, matchPercent } from '@react-pdf/fns';
|
|
2
|
-
import
|
|
3
|
-
import parseUnit from 'postcss-value-parser/lib/unit.js';
|
|
2
|
+
import matchMedia from 'media-engine';
|
|
4
3
|
import hlsToHex from 'hsl-to-hex';
|
|
5
4
|
import colorString from 'color-string';
|
|
6
|
-
import
|
|
5
|
+
import parse$1 from 'postcss-value-parser/lib/parse.js';
|
|
6
|
+
import parseUnit from 'postcss-value-parser/lib/unit.js';
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Remove nil values from array
|
|
10
|
+
*
|
|
11
|
+
* @param array - Style array
|
|
12
|
+
* @returns Style array without nils
|
|
13
|
+
*/
|
|
14
|
+
const compact = (array) => array.filter(Boolean);
|
|
15
|
+
/**
|
|
16
|
+
* Merges style objects array
|
|
17
|
+
*
|
|
18
|
+
* @param styles - Style array
|
|
19
|
+
* @returns Merged style object
|
|
20
|
+
*/
|
|
21
|
+
const mergeStyles = (styles) => styles.reduce((acc, style) => {
|
|
22
|
+
const s = Array.isArray(style) ? flatten(style) : style;
|
|
23
|
+
Object.keys(s).forEach((key) => {
|
|
24
|
+
if (s[key] !== null && s[key] !== undefined) {
|
|
25
|
+
acc[key] = s[key];
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
return acc;
|
|
29
|
+
}, {});
|
|
30
|
+
/**
|
|
31
|
+
* Flattens an array of style objects, into one aggregated style object.
|
|
32
|
+
*
|
|
33
|
+
* @param styles - Style or style array
|
|
34
|
+
* @returns Flattened style object
|
|
35
|
+
*/
|
|
36
|
+
const flatten = compose(mergeStyles, compact, (castArray));
|
|
9
37
|
|
|
10
|
-
// TODO: change flex defaults to [0, 1, 'auto'] as in spec in next major release
|
|
11
|
-
const flexDefaults = [1, 1, 0];
|
|
12
38
|
/**
|
|
13
|
-
*
|
|
39
|
+
* Resolves media queries in styles object
|
|
40
|
+
*
|
|
41
|
+
* @param container - Container for which styles are resolved
|
|
42
|
+
* @param style - Style description
|
|
43
|
+
* @returns Resolved style object
|
|
14
44
|
*/
|
|
45
|
+
const resolveMediaQueries = (container, style) => {
|
|
46
|
+
return Object.keys(style).reduce((acc, key) => {
|
|
47
|
+
if (/@media/.test(key)) {
|
|
48
|
+
return {
|
|
49
|
+
...acc,
|
|
50
|
+
...matchMedia({ [key]: style[key] }, container),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return { ...acc, [key]: style[key] };
|
|
54
|
+
}, {});
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const isRgb = (value) => /rgba?/g.test(value);
|
|
58
|
+
const isHsl = (value) => /hsla?/g.test(value);
|
|
59
|
+
/**
|
|
60
|
+
* Transform rgb color to hexa
|
|
61
|
+
*
|
|
62
|
+
* @param value - Styles value
|
|
63
|
+
* @returns Transformed value
|
|
64
|
+
*/
|
|
65
|
+
const parseRgb = (value) => {
|
|
66
|
+
const rgb = colorString.get.rgb(value);
|
|
67
|
+
return colorString.to.hex(rgb);
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Transform Hsl color to hexa
|
|
71
|
+
*
|
|
72
|
+
* @param value - Styles value
|
|
73
|
+
* @returns Transformed value
|
|
74
|
+
*/
|
|
75
|
+
const parseHsl = (value) => {
|
|
76
|
+
const hsl = colorString.get.hsl(value).map(Math.round);
|
|
77
|
+
const hex = hlsToHex(...hsl);
|
|
78
|
+
return hex.toUpperCase();
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Transform given color to hexa
|
|
82
|
+
*
|
|
83
|
+
* @param value - Styles value
|
|
84
|
+
* @returns Transformed value
|
|
85
|
+
*/
|
|
86
|
+
const transformColor = (value) => {
|
|
87
|
+
if (isRgb(value))
|
|
88
|
+
return parseRgb(value);
|
|
89
|
+
if (isHsl(value))
|
|
90
|
+
return parseHsl(value);
|
|
91
|
+
return value;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Parses scalar value in value and unit pairs
|
|
96
|
+
*
|
|
97
|
+
* @param value - Scalar value
|
|
98
|
+
* @returns Parsed value
|
|
99
|
+
*/
|
|
100
|
+
const parseValue = (value) => {
|
|
101
|
+
if (typeof value === 'number')
|
|
102
|
+
return { value, unit: undefined };
|
|
103
|
+
const match = /^(-?\d*\.?\d+)(in|mm|cm|pt|vh|vw|px|rem)?$/g.exec(value);
|
|
104
|
+
return match
|
|
105
|
+
? { value: parseFloat(match[1]), unit: match[2] || 'pt' }
|
|
106
|
+
: { value, unit: undefined };
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Transform given scalar value
|
|
110
|
+
*
|
|
111
|
+
* @param container
|
|
112
|
+
* @param value - Styles value
|
|
113
|
+
* @returns Transformed value
|
|
114
|
+
*/
|
|
115
|
+
const transformUnit = (container, value) => {
|
|
116
|
+
const scalar = parseValue(value);
|
|
117
|
+
const outputDpi = 72;
|
|
118
|
+
const inputDpi = container.dpi || 72;
|
|
119
|
+
const mmFactor = (1 / 25.4) * outputDpi;
|
|
120
|
+
const cmFactor = (1 / 2.54) * outputDpi;
|
|
121
|
+
if (typeof scalar.value !== 'number')
|
|
122
|
+
return scalar.value;
|
|
123
|
+
switch (scalar.unit) {
|
|
124
|
+
case 'rem':
|
|
125
|
+
return scalar.value * (container.remBase || 18);
|
|
126
|
+
case 'in':
|
|
127
|
+
return scalar.value * outputDpi;
|
|
128
|
+
case 'mm':
|
|
129
|
+
return scalar.value * mmFactor;
|
|
130
|
+
case 'cm':
|
|
131
|
+
return scalar.value * cmFactor;
|
|
132
|
+
case 'vh':
|
|
133
|
+
return scalar.value * (container.height / 100);
|
|
134
|
+
case 'vw':
|
|
135
|
+
return scalar.value * (container.width / 100);
|
|
136
|
+
case 'px':
|
|
137
|
+
return Math.round(scalar.value * (outputDpi / inputDpi));
|
|
138
|
+
default:
|
|
139
|
+
return scalar.value;
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const processNumberValue = (key, value) => ({
|
|
144
|
+
[key]: parseFloat(value),
|
|
145
|
+
});
|
|
146
|
+
const processUnitValue = (key, value, container) => ({
|
|
147
|
+
[key]: transformUnit(container, value),
|
|
148
|
+
});
|
|
149
|
+
const processColorValue = (key, value) => {
|
|
150
|
+
const result = { [key]: transformColor(value) };
|
|
151
|
+
return result;
|
|
152
|
+
};
|
|
153
|
+
const processNoopValue = (key, value) => ({
|
|
154
|
+
[key]: value,
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
const BORDER_SHORTHAND_REGEX = /(-?\d+(\.\d+)?(in|mm|cm|pt|vw|vh|px|rem)?)\s(\S+)\s(.+)/;
|
|
158
|
+
const matchBorderShorthand = (value) => value.match(BORDER_SHORTHAND_REGEX) || [];
|
|
159
|
+
const resolveBorderShorthand = (key, value, container) => {
|
|
160
|
+
const match = matchBorderShorthand(`${value}`);
|
|
161
|
+
if (match) {
|
|
162
|
+
const widthMatch = match[1] || value;
|
|
163
|
+
const styleMatch = match[4] || value;
|
|
164
|
+
const colorMatch = match[5] || value;
|
|
165
|
+
const style = styleMatch;
|
|
166
|
+
const color = colorMatch ? transformColor(colorMatch) : undefined;
|
|
167
|
+
const width = widthMatch ? transformUnit(container, widthMatch) : undefined;
|
|
168
|
+
if (key.match(/(Top|Right|Bottom|Left)$/)) {
|
|
169
|
+
return {
|
|
170
|
+
[`${key}Color`]: color,
|
|
171
|
+
[`${key}Style`]: style,
|
|
172
|
+
[`${key}Width`]: width,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
if (key.match(/Color$/)) {
|
|
176
|
+
return {
|
|
177
|
+
borderTopColor: color,
|
|
178
|
+
borderRightColor: color,
|
|
179
|
+
borderBottomColor: color,
|
|
180
|
+
borderLeftColor: color,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
if (key.match(/Style$/)) {
|
|
184
|
+
if (typeof style === 'number')
|
|
185
|
+
throw new Error(`Invalid border style: ${style}`);
|
|
186
|
+
return {
|
|
187
|
+
borderTopStyle: style,
|
|
188
|
+
borderRightStyle: style,
|
|
189
|
+
borderBottomStyle: style,
|
|
190
|
+
borderLeftStyle: style,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
if (key.match(/Width$/)) {
|
|
194
|
+
if (typeof width !== 'number')
|
|
195
|
+
throw new Error(`Invalid border width: ${width}`);
|
|
196
|
+
return {
|
|
197
|
+
borderTopWidth: width,
|
|
198
|
+
borderRightWidth: width,
|
|
199
|
+
borderBottomWidth: width,
|
|
200
|
+
borderLeftWidth: width,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
if (key.match(/Radius$/)) {
|
|
204
|
+
const radius = value ? transformUnit(container, value) : undefined;
|
|
205
|
+
if (typeof radius !== 'number')
|
|
206
|
+
throw new Error(`Invalid border radius: ${radius}`);
|
|
207
|
+
return {
|
|
208
|
+
borderTopLeftRadius: radius,
|
|
209
|
+
borderTopRightRadius: radius,
|
|
210
|
+
borderBottomRightRadius: radius,
|
|
211
|
+
borderBottomLeftRadius: radius,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
if (typeof width !== 'number')
|
|
215
|
+
throw new Error(`Invalid border width: ${width}`);
|
|
216
|
+
if (typeof style === 'number')
|
|
217
|
+
throw new Error(`Invalid border style: ${style}`);
|
|
218
|
+
return {
|
|
219
|
+
borderTopColor: color,
|
|
220
|
+
borderTopStyle: style,
|
|
221
|
+
borderTopWidth: width,
|
|
222
|
+
borderRightColor: color,
|
|
223
|
+
borderRightStyle: style,
|
|
224
|
+
borderRightWidth: width,
|
|
225
|
+
borderBottomColor: color,
|
|
226
|
+
borderBottomStyle: style,
|
|
227
|
+
borderBottomWidth: width,
|
|
228
|
+
borderLeftColor: color,
|
|
229
|
+
borderLeftStyle: style,
|
|
230
|
+
borderLeftWidth: width,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
return { [key]: value };
|
|
234
|
+
};
|
|
235
|
+
const handlers$b = {
|
|
236
|
+
border: resolveBorderShorthand,
|
|
237
|
+
borderBottom: resolveBorderShorthand,
|
|
238
|
+
borderBottomColor: processColorValue,
|
|
239
|
+
borderBottomLeftRadius: processUnitValue,
|
|
240
|
+
borderBottomRightRadius: processUnitValue,
|
|
241
|
+
borderBottomStyle: processNoopValue,
|
|
242
|
+
borderBottomWidth: processUnitValue,
|
|
243
|
+
borderColor: resolveBorderShorthand,
|
|
244
|
+
borderLeft: resolveBorderShorthand,
|
|
245
|
+
borderLeftColor: processColorValue,
|
|
246
|
+
borderLeftStyle: processNoopValue,
|
|
247
|
+
borderLeftWidth: processUnitValue,
|
|
248
|
+
borderRadius: resolveBorderShorthand,
|
|
249
|
+
borderRight: resolveBorderShorthand,
|
|
250
|
+
borderRightColor: processColorValue,
|
|
251
|
+
borderRightStyle: processNoopValue,
|
|
252
|
+
borderRightWidth: processUnitValue,
|
|
253
|
+
borderStyle: resolveBorderShorthand,
|
|
254
|
+
borderTop: resolveBorderShorthand,
|
|
255
|
+
borderTopColor: processColorValue,
|
|
256
|
+
borderTopLeftRadius: processUnitValue,
|
|
257
|
+
borderTopRightRadius: processUnitValue,
|
|
258
|
+
borderTopStyle: processNoopValue,
|
|
259
|
+
borderTopWidth: processUnitValue,
|
|
260
|
+
borderWidth: resolveBorderShorthand,
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
const handlers$a = {
|
|
264
|
+
backgroundColor: processColorValue,
|
|
265
|
+
color: processColorValue,
|
|
266
|
+
opacity: processNumberValue,
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
const handlers$9 = {
|
|
270
|
+
height: processUnitValue,
|
|
271
|
+
maxHeight: processUnitValue,
|
|
272
|
+
maxWidth: processUnitValue,
|
|
273
|
+
minHeight: processUnitValue,
|
|
274
|
+
minWidth: processUnitValue,
|
|
275
|
+
width: processUnitValue,
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
// https://developer.mozilla.org/en-US/docs/Web/CSS/flex#values
|
|
279
|
+
// TODO: change flex defaults to [0, 1, 'auto'] as in spec in next major release
|
|
280
|
+
const flexDefaults = [1, 1, 0];
|
|
15
281
|
const flexAuto = [1, 1, 'auto'];
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
282
|
+
const processFlexShorthand = (key, value, container) => {
|
|
283
|
+
let defaults = flexDefaults;
|
|
284
|
+
let matches = [];
|
|
285
|
+
if (value === 'auto') {
|
|
286
|
+
defaults = flexAuto;
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
matches = `${value}`.split(' ');
|
|
290
|
+
}
|
|
291
|
+
const flexGrow = transformUnit(container, matches[0] || defaults[0]);
|
|
292
|
+
const flexShrink = transformUnit(container, matches[1] || defaults[1]);
|
|
293
|
+
const flexBasis = transformUnit(container, matches[2] || defaults[2]);
|
|
294
|
+
return { flexGrow, flexShrink, flexBasis };
|
|
295
|
+
};
|
|
296
|
+
const handlers$8 = {
|
|
297
|
+
alignContent: processNoopValue,
|
|
298
|
+
alignItems: processNoopValue,
|
|
299
|
+
alignSelf: processNoopValue,
|
|
300
|
+
flex: processFlexShorthand,
|
|
301
|
+
flexBasis: processUnitValue,
|
|
302
|
+
flexDirection: processNoopValue,
|
|
303
|
+
flexFlow: processNoopValue,
|
|
304
|
+
flexGrow: processUnitValue,
|
|
305
|
+
flexShrink: processUnitValue,
|
|
306
|
+
flexWrap: processNoopValue,
|
|
307
|
+
justifyContent: processNoopValue,
|
|
308
|
+
justifySelf: processNoopValue,
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
const processGapShorthand = (key, value, container) => {
|
|
312
|
+
const match = `${value}`.split(' ');
|
|
313
|
+
const rowGap = transformUnit(container, match?.[0] || value);
|
|
314
|
+
const columnGap = transformUnit(container, match?.[1] || value);
|
|
315
|
+
return { rowGap, columnGap };
|
|
316
|
+
};
|
|
317
|
+
const handlers$7 = {
|
|
318
|
+
gap: processGapShorthand,
|
|
319
|
+
columnGap: processUnitValue,
|
|
320
|
+
rowGap: processUnitValue,
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
const handlers$6 = {
|
|
324
|
+
aspectRatio: processNumberValue,
|
|
325
|
+
bottom: processUnitValue,
|
|
326
|
+
display: processNoopValue,
|
|
327
|
+
left: processUnitValue,
|
|
328
|
+
position: processNoopValue,
|
|
329
|
+
right: processUnitValue,
|
|
330
|
+
top: processUnitValue,
|
|
331
|
+
overflow: processNoopValue,
|
|
332
|
+
zIndex: processNumberValue,
|
|
35
333
|
};
|
|
36
334
|
|
|
37
|
-
/* eslint-disable no-plusplus */
|
|
38
|
-
// This file is ran directly with Node - needs to have .js extension
|
|
39
|
-
// eslint-disable-next-line import/extensions
|
|
40
335
|
const BOX_MODEL_UNITS = 'px,in,mm,cm,pt,%,vw,vh';
|
|
41
336
|
const logError = (style, value) => {
|
|
42
|
-
|
|
337
|
+
const name = style.toString();
|
|
338
|
+
// eslint-disable-next-line no-console
|
|
339
|
+
console.error(`
|
|
43
340
|
@react-pdf/stylesheet parsing error:
|
|
44
|
-
|
|
45
|
-
${
|
|
46
|
-
${
|
|
47
|
-
Unsupported ${style} value format
|
|
341
|
+
${name}: ${value},
|
|
342
|
+
${' '.repeat(name.length + 2)}^
|
|
343
|
+
Unsupported ${name} value format
|
|
48
344
|
`);
|
|
49
345
|
};
|
|
50
|
-
|
|
51
346
|
/**
|
|
52
347
|
* @param {Object} options
|
|
53
348
|
* @param {Function} [options.expandsTo]
|
|
54
349
|
* @param {number} [options.maxValues]
|
|
55
350
|
* @param {boolean} [options.autoSupported]
|
|
56
351
|
*/
|
|
57
|
-
const expandBoxModel =
|
|
58
|
-
let {
|
|
59
|
-
expandsTo,
|
|
60
|
-
maxValues = 1,
|
|
61
|
-
autoSupported = false
|
|
62
|
-
} = _temp === void 0 ? {} : _temp;
|
|
63
|
-
return (model, value) => {
|
|
352
|
+
const expandBoxModel = ({ expandsTo, maxValues = 1, autoSupported = false, } = {}) => (model, value, container) => {
|
|
64
353
|
const nodes = parse$1(`${value}`);
|
|
65
354
|
const parts = [];
|
|
66
355
|
for (let i = 0; i < nodes.length; i++) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
return {};
|
|
74
|
-
}
|
|
75
|
-
if (node.type === 'word') {
|
|
76
|
-
if (node.value === 'auto' && autoSupported) {
|
|
77
|
-
parts.push(node.value);
|
|
78
|
-
} else {
|
|
79
|
-
const result = parseUnit(node.value);
|
|
80
|
-
|
|
81
|
-
// when unit isn't specified this condition is true
|
|
82
|
-
if (result && BOX_MODEL_UNITS.includes(result.unit)) {
|
|
83
|
-
parts.push(node.value);
|
|
84
|
-
} else {
|
|
356
|
+
const node = nodes[i];
|
|
357
|
+
// value contains `calc`, `url` or other css function
|
|
358
|
+
// `,`, `/` or strings that unsupported by margin and padding
|
|
359
|
+
if (node.type === 'function' ||
|
|
360
|
+
node.type === 'string' ||
|
|
361
|
+
node.type === 'div') {
|
|
85
362
|
logError(model, value);
|
|
86
363
|
return {};
|
|
87
|
-
}
|
|
88
364
|
}
|
|
89
|
-
|
|
365
|
+
if (node.type === 'word') {
|
|
366
|
+
if (node.value === 'auto' && autoSupported) {
|
|
367
|
+
parts.push(node.value);
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
const result = parseUnit(node.value);
|
|
371
|
+
// when unit isn't specified this condition is true
|
|
372
|
+
if (result && BOX_MODEL_UNITS.includes(result.unit)) {
|
|
373
|
+
parts.push(node.value);
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
logError(model, value);
|
|
377
|
+
return {};
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
90
381
|
}
|
|
91
|
-
|
|
92
382
|
// checks that we have enough parsed values
|
|
93
383
|
if (parts.length > maxValues) {
|
|
94
|
-
|
|
95
|
-
|
|
384
|
+
logError(model, value);
|
|
385
|
+
return {};
|
|
96
386
|
}
|
|
97
|
-
const first = parts[0];
|
|
387
|
+
const first = transformUnit(container, parts[0]);
|
|
98
388
|
if (expandsTo) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
first,
|
|
104
|
-
second,
|
|
105
|
-
third,
|
|
106
|
-
fourth
|
|
107
|
-
});
|
|
389
|
+
const second = transformUnit(container, parts[1] || parts[0]);
|
|
390
|
+
const third = transformUnit(container, parts[2] || parts[0]);
|
|
391
|
+
const fourth = transformUnit(container, parts[3] || parts[1] || parts[0]);
|
|
392
|
+
return expandsTo({ first, second, third, fourth });
|
|
108
393
|
}
|
|
109
394
|
return {
|
|
110
|
-
|
|
395
|
+
[model]: first,
|
|
111
396
|
};
|
|
112
|
-
};
|
|
113
397
|
};
|
|
114
398
|
|
|
115
399
|
const processMargin = expandBoxModel({
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
marginTop: first,
|
|
125
|
-
marginRight: second,
|
|
126
|
-
marginBottom: third,
|
|
127
|
-
marginLeft: fourth
|
|
128
|
-
};
|
|
129
|
-
},
|
|
130
|
-
maxValues: 4,
|
|
131
|
-
autoSupported: true
|
|
400
|
+
expandsTo: ({ first, second, third, fourth }) => ({
|
|
401
|
+
marginTop: first,
|
|
402
|
+
marginRight: second,
|
|
403
|
+
marginBottom: third,
|
|
404
|
+
marginLeft: fourth,
|
|
405
|
+
}),
|
|
406
|
+
maxValues: 4,
|
|
407
|
+
autoSupported: true,
|
|
132
408
|
});
|
|
133
409
|
const processMarginVertical = expandBoxModel({
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
marginTop: first,
|
|
141
|
-
marginBottom: second
|
|
142
|
-
};
|
|
143
|
-
},
|
|
144
|
-
maxValues: 2,
|
|
145
|
-
autoSupported: true
|
|
410
|
+
expandsTo: ({ first, second }) => ({
|
|
411
|
+
marginTop: first,
|
|
412
|
+
marginBottom: second,
|
|
413
|
+
}),
|
|
414
|
+
maxValues: 2,
|
|
415
|
+
autoSupported: true,
|
|
146
416
|
});
|
|
147
417
|
const processMarginHorizontal = expandBoxModel({
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
marginRight: first,
|
|
155
|
-
marginLeft: second
|
|
156
|
-
};
|
|
157
|
-
},
|
|
158
|
-
maxValues: 2,
|
|
159
|
-
autoSupported: true
|
|
418
|
+
expandsTo: ({ first, second }) => ({
|
|
419
|
+
marginRight: first,
|
|
420
|
+
marginLeft: second,
|
|
421
|
+
}),
|
|
422
|
+
maxValues: 2,
|
|
423
|
+
autoSupported: true,
|
|
160
424
|
});
|
|
161
425
|
const processMarginSingle = expandBoxModel({
|
|
162
|
-
|
|
426
|
+
autoSupported: true,
|
|
163
427
|
});
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
const width = match[1] || value;
|
|
173
|
-
if (key.match(/(Top|Right|Bottom|Left)$/)) {
|
|
174
|
-
return {
|
|
175
|
-
[`${key}Color`]: color,
|
|
176
|
-
[`${key}Style`]: style,
|
|
177
|
-
[`${key}Width`]: width
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
if (key.match(/Color$/)) {
|
|
181
|
-
return {
|
|
182
|
-
borderTopColor: color,
|
|
183
|
-
borderRightColor: color,
|
|
184
|
-
borderBottomColor: color,
|
|
185
|
-
borderLeftColor: color
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
if (key.match(/Style$/)) {
|
|
189
|
-
return {
|
|
190
|
-
borderTopStyle: style,
|
|
191
|
-
borderRightStyle: style,
|
|
192
|
-
borderBottomStyle: style,
|
|
193
|
-
borderLeftStyle: style
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
if (key.match(/Width$/)) {
|
|
197
|
-
return {
|
|
198
|
-
borderTopWidth: width,
|
|
199
|
-
borderRightWidth: width,
|
|
200
|
-
borderBottomWidth: width,
|
|
201
|
-
borderLeftWidth: width
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
if (key.match(/Radius$/)) {
|
|
205
|
-
return {
|
|
206
|
-
borderTopLeftRadius: value,
|
|
207
|
-
borderTopRightRadius: value,
|
|
208
|
-
borderBottomRightRadius: value,
|
|
209
|
-
borderBottomLeftRadius: value
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
return {
|
|
213
|
-
borderTopColor: color,
|
|
214
|
-
borderTopStyle: style,
|
|
215
|
-
borderTopWidth: width,
|
|
216
|
-
borderRightColor: color,
|
|
217
|
-
borderRightStyle: style,
|
|
218
|
-
borderRightWidth: width,
|
|
219
|
-
borderBottomColor: color,
|
|
220
|
-
borderBottomStyle: style,
|
|
221
|
-
borderBottomWidth: width,
|
|
222
|
-
borderLeftColor: color,
|
|
223
|
-
borderLeftStyle: style,
|
|
224
|
-
borderLeftWidth: width
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
return value;
|
|
428
|
+
const handlers$5 = {
|
|
429
|
+
margin: processMargin,
|
|
430
|
+
marginBottom: processMarginSingle,
|
|
431
|
+
marginHorizontal: processMarginHorizontal,
|
|
432
|
+
marginLeft: processMarginSingle,
|
|
433
|
+
marginRight: processMarginSingle,
|
|
434
|
+
marginTop: processMarginSingle,
|
|
435
|
+
marginVertical: processMarginVertical,
|
|
228
436
|
};
|
|
229
437
|
|
|
230
438
|
const processPadding = expandBoxModel({
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
return {
|
|
239
|
-
paddingTop: first,
|
|
240
|
-
paddingRight: second,
|
|
241
|
-
paddingBottom: third,
|
|
242
|
-
paddingLeft: fourth
|
|
243
|
-
};
|
|
244
|
-
},
|
|
245
|
-
maxValues: 4
|
|
439
|
+
expandsTo: ({ first, second, third, fourth }) => ({
|
|
440
|
+
paddingTop: first,
|
|
441
|
+
paddingRight: second,
|
|
442
|
+
paddingBottom: third,
|
|
443
|
+
paddingLeft: fourth,
|
|
444
|
+
}),
|
|
445
|
+
maxValues: 4,
|
|
246
446
|
});
|
|
247
447
|
const processPaddingVertical = expandBoxModel({
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
return {
|
|
254
|
-
paddingTop: first,
|
|
255
|
-
paddingBottom: second
|
|
256
|
-
};
|
|
257
|
-
},
|
|
258
|
-
maxValues: 2
|
|
448
|
+
expandsTo: ({ first, second }) => ({
|
|
449
|
+
paddingTop: first,
|
|
450
|
+
paddingBottom: second,
|
|
451
|
+
}),
|
|
452
|
+
maxValues: 2,
|
|
259
453
|
});
|
|
260
454
|
const processPaddingHorizontal = expandBoxModel({
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
return {
|
|
267
|
-
paddingRight: first,
|
|
268
|
-
paddingLeft: second
|
|
269
|
-
};
|
|
270
|
-
},
|
|
271
|
-
maxValues: 2
|
|
455
|
+
expandsTo: ({ first, second }) => ({
|
|
456
|
+
paddingRight: first,
|
|
457
|
+
paddingLeft: second,
|
|
458
|
+
}),
|
|
459
|
+
maxValues: 2,
|
|
272
460
|
});
|
|
273
461
|
const processPaddingSingle = expandBoxModel();
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
462
|
+
const handlers$4 = {
|
|
463
|
+
padding: processPadding,
|
|
464
|
+
paddingBottom: processPaddingSingle,
|
|
465
|
+
paddingHorizontal: processPaddingHorizontal,
|
|
466
|
+
paddingLeft: processPaddingSingle,
|
|
467
|
+
paddingRight: processPaddingSingle,
|
|
468
|
+
paddingTop: processPaddingSingle,
|
|
469
|
+
paddingVertical: processPaddingVertical,
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
const offsetKeyword = (value) => {
|
|
473
|
+
switch (value) {
|
|
474
|
+
case 'top':
|
|
475
|
+
case 'left':
|
|
476
|
+
return '0%';
|
|
477
|
+
case 'right':
|
|
478
|
+
case 'bottom':
|
|
479
|
+
return '100%';
|
|
480
|
+
case 'center':
|
|
481
|
+
return '50%';
|
|
482
|
+
default:
|
|
483
|
+
return value;
|
|
484
|
+
}
|
|
296
485
|
};
|
|
297
486
|
|
|
298
|
-
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
transformOriginX: pair[0],
|
|
304
|
-
transformOriginY: pair[1]
|
|
305
|
-
};
|
|
487
|
+
const processObjectPosition = (key, value, container) => {
|
|
488
|
+
const match = `${value}`.split(' ');
|
|
489
|
+
const objectPositionX = offsetKeyword(transformUnit(container, match?.[0] || value));
|
|
490
|
+
const objectPositionY = offsetKeyword(transformUnit(container, match?.[1] || value));
|
|
491
|
+
return { objectPositionX, objectPositionY };
|
|
306
492
|
};
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
493
|
+
const processObjectPositionValue = (key, value, container) => ({
|
|
494
|
+
[key]: offsetKeyword(transformUnit(container, value)),
|
|
495
|
+
});
|
|
496
|
+
const handlers$3 = {
|
|
497
|
+
objectPosition: processObjectPosition,
|
|
498
|
+
objectPositionX: processObjectPositionValue,
|
|
499
|
+
objectPositionY: processObjectPositionValue,
|
|
500
|
+
objectFit: processNoopValue,
|
|
314
501
|
};
|
|
315
502
|
|
|
316
|
-
const
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
marginHorizontal: processMarginHorizontal,
|
|
321
|
-
marginVertical: processMarginVertical,
|
|
322
|
-
marginTop: processMarginSingle,
|
|
323
|
-
marginRight: processMarginSingle,
|
|
324
|
-
marginBottom: processMarginSingle,
|
|
325
|
-
marginLeft: processMarginSingle,
|
|
326
|
-
padding: processPadding,
|
|
327
|
-
paddingHorizontal: processPaddingHorizontal,
|
|
328
|
-
paddingVertical: processPaddingVertical,
|
|
329
|
-
paddingTop: processPaddingSingle,
|
|
330
|
-
paddingRight: processPaddingSingle,
|
|
331
|
-
paddingBottom: processPaddingSingle,
|
|
332
|
-
paddingLeft: processPaddingSingle,
|
|
333
|
-
border: expandBorders,
|
|
334
|
-
borderTop: expandBorders,
|
|
335
|
-
borderRight: expandBorders,
|
|
336
|
-
borderBottom: expandBorders,
|
|
337
|
-
borderLeft: expandBorders,
|
|
338
|
-
borderColor: expandBorders,
|
|
339
|
-
borderRadius: expandBorders,
|
|
340
|
-
borderStyle: expandBorders,
|
|
341
|
-
borderWidth: expandBorders,
|
|
342
|
-
objectPosition: expandObjectPosition,
|
|
343
|
-
transformOrigin: expandTransformOrigin
|
|
503
|
+
const castInt = (value) => {
|
|
504
|
+
if (typeof value === 'number')
|
|
505
|
+
return value;
|
|
506
|
+
return parseInt(value, 10);
|
|
344
507
|
};
|
|
345
508
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
509
|
+
const FONT_WEIGHTS = {
|
|
510
|
+
thin: 100,
|
|
511
|
+
hairline: 100,
|
|
512
|
+
ultralight: 200,
|
|
513
|
+
extralight: 200,
|
|
514
|
+
light: 300,
|
|
515
|
+
normal: 400,
|
|
516
|
+
medium: 500,
|
|
517
|
+
semibold: 600,
|
|
518
|
+
demibold: 600,
|
|
519
|
+
bold: 700,
|
|
520
|
+
ultrabold: 800,
|
|
521
|
+
extrabold: 800,
|
|
522
|
+
heavy: 900,
|
|
523
|
+
black: 900,
|
|
524
|
+
};
|
|
525
|
+
const transformFontWeight = (value) => {
|
|
526
|
+
if (!value)
|
|
527
|
+
return FONT_WEIGHTS.normal;
|
|
528
|
+
if (typeof value === 'number')
|
|
529
|
+
return value;
|
|
530
|
+
const lv = value.toLowerCase();
|
|
531
|
+
if (FONT_WEIGHTS[lv])
|
|
532
|
+
return FONT_WEIGHTS[lv];
|
|
533
|
+
return castInt(value);
|
|
534
|
+
};
|
|
535
|
+
const processFontWeight = (key, value) => {
|
|
536
|
+
return { [key]: transformFontWeight(value) };
|
|
537
|
+
};
|
|
538
|
+
const transformLineHeight = (value, styles, container) => {
|
|
539
|
+
if (value === '')
|
|
540
|
+
return value;
|
|
541
|
+
const fontSize = transformUnit(container, styles.fontSize || 18);
|
|
542
|
+
const lineHeight = transformUnit(container, value);
|
|
543
|
+
// Percent values: use this number multiplied by the element's font size
|
|
544
|
+
const { percent } = matchPercent(lineHeight) || {};
|
|
545
|
+
if (percent)
|
|
546
|
+
return percent * fontSize;
|
|
547
|
+
// Unitless values: use this number multiplied by the element's font size
|
|
548
|
+
return isNaN(value) ? lineHeight : lineHeight * fontSize;
|
|
549
|
+
};
|
|
550
|
+
const processLineHeight = (key, value, container, styles) => {
|
|
551
|
+
return {
|
|
552
|
+
[key]: transformLineHeight(value, styles, container),
|
|
553
|
+
};
|
|
357
554
|
};
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
555
|
+
const handlers$2 = {
|
|
556
|
+
fontFamily: processNoopValue,
|
|
557
|
+
fontSize: processUnitValue,
|
|
558
|
+
fontStyle: processNoopValue,
|
|
559
|
+
fontWeight: processFontWeight,
|
|
560
|
+
letterSpacing: processUnitValue,
|
|
561
|
+
lineHeight: processLineHeight,
|
|
562
|
+
maxLines: processNumberValue,
|
|
563
|
+
textAlign: processNoopValue,
|
|
564
|
+
textDecoration: processNoopValue,
|
|
565
|
+
textDecorationColor: processColorValue,
|
|
566
|
+
textDecorationStyle: processNoopValue,
|
|
567
|
+
textIndent: processNoopValue,
|
|
568
|
+
textOverflow: processNoopValue,
|
|
569
|
+
textTransform: processNoopValue,
|
|
570
|
+
verticalAlign: processNoopValue,
|
|
571
|
+
};
|
|
572
|
+
|
|
573
|
+
const matchNumber = (value) => typeof value === 'string' && /^-?\d*\.?\d*$/.test(value);
|
|
574
|
+
const castFloat = (value) => {
|
|
575
|
+
if (typeof value !== 'string')
|
|
576
|
+
return value;
|
|
577
|
+
if (matchNumber(value))
|
|
578
|
+
return parseFloat(value);
|
|
579
|
+
return value;
|
|
580
|
+
};
|
|
581
|
+
|
|
582
|
+
const parse = (transformString) => {
|
|
583
|
+
const transforms = transformString.trim().split(/\)[ ,]|\)/);
|
|
584
|
+
// Handle "initial", "inherit", "unset".
|
|
585
|
+
if (transforms.length === 1) {
|
|
586
|
+
return [[transforms[0], true]];
|
|
378
587
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
* @returns {T[]} array without nils
|
|
389
|
-
*/
|
|
390
|
-
const compact = array => array.filter(Boolean);
|
|
391
|
-
|
|
392
|
-
/**
|
|
393
|
-
* Merges style objects array
|
|
394
|
-
*
|
|
395
|
-
* @param {Object[]} styles style objects array
|
|
396
|
-
* @returns {Object} merged style object
|
|
397
|
-
*/
|
|
398
|
-
const mergeStyles = styles => styles.reduce((acc, style) => {
|
|
399
|
-
const s = Array.isArray(style) ? flatten(style) : style;
|
|
400
|
-
Object.keys(s).forEach(key => {
|
|
401
|
-
if (s[key] !== null && s[key] !== undefined) {
|
|
402
|
-
acc[key] = s[key];
|
|
588
|
+
const parsed = [];
|
|
589
|
+
for (let i = 0; i < transforms.length; i += 1) {
|
|
590
|
+
const transform = transforms[i];
|
|
591
|
+
if (transform) {
|
|
592
|
+
const [name, rawValue] = transform.split('(');
|
|
593
|
+
const splitChar = rawValue.indexOf(',') >= 0 ? ',' : ' ';
|
|
594
|
+
const value = rawValue.split(splitChar).map((val) => val.trim());
|
|
595
|
+
parsed.push({ operation: name.trim(), value });
|
|
596
|
+
}
|
|
403
597
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
*
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
};
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
return scalar.value * cmFactor;
|
|
455
|
-
case 'vh':
|
|
456
|
-
return scalar.value * (container.height / 100);
|
|
457
|
-
case 'vw':
|
|
458
|
-
return scalar.value * (container.width / 100);
|
|
459
|
-
case 'px':
|
|
460
|
-
return Math.round(scalar.value * (outputDpi / inputDpi));
|
|
461
|
-
default:
|
|
462
|
-
return scalar.value;
|
|
463
|
-
}
|
|
464
|
-
};
|
|
465
|
-
|
|
466
|
-
const isRgb = value => /rgba?/g.test(value);
|
|
467
|
-
const isHsl = value => /hsla?/g.test(value);
|
|
468
|
-
|
|
469
|
-
/**
|
|
470
|
-
* Transform rgb color to hexa
|
|
471
|
-
*
|
|
472
|
-
* @param {string} value styles value
|
|
473
|
-
* @returns {Object} transformed value
|
|
474
|
-
*/
|
|
475
|
-
const parseRgb = value => {
|
|
476
|
-
const rgb = colorString.get.rgb(value);
|
|
477
|
-
return colorString.to.hex(rgb);
|
|
478
|
-
};
|
|
479
|
-
|
|
480
|
-
/**
|
|
481
|
-
* Transform Hsl color to hexa
|
|
482
|
-
*
|
|
483
|
-
* @param {string} value styles value
|
|
484
|
-
* @returns {Object} transformed value
|
|
485
|
-
*/
|
|
486
|
-
const parseHsl = value => {
|
|
487
|
-
const hsl = colorString.get.hsl(value).map(Math.round);
|
|
488
|
-
const hex = hlsToHex(...hsl);
|
|
489
|
-
return hex.toUpperCase();
|
|
490
|
-
};
|
|
491
|
-
|
|
492
|
-
/**
|
|
493
|
-
* Transform given color to hexa
|
|
494
|
-
*
|
|
495
|
-
* @param {string} value styles value
|
|
496
|
-
* @returns {Object} transformed value
|
|
497
|
-
*/
|
|
498
|
-
const transformColor = value => {
|
|
499
|
-
if (isRgb(value)) return parseRgb(value);
|
|
500
|
-
if (isHsl(value)) return parseHsl(value);
|
|
501
|
-
return value;
|
|
502
|
-
};
|
|
503
|
-
|
|
504
|
-
const parse = transformString => {
|
|
505
|
-
const transforms = transformString.trim().split(/\)[ ,]|\)/);
|
|
506
|
-
|
|
507
|
-
// Handle "initial", "inherit", "unset".
|
|
508
|
-
if (transforms.length === 1) {
|
|
509
|
-
return [[transforms[0], true]];
|
|
510
|
-
}
|
|
511
|
-
const parsed = [];
|
|
512
|
-
for (let i = 0; i < transforms.length; i += 1) {
|
|
513
|
-
const transform = transforms[i];
|
|
514
|
-
if (transform) {
|
|
515
|
-
const [name, rawValue] = transform.split('(');
|
|
516
|
-
const splitChar = rawValue.indexOf(',') >= 0 ? ',' : ' ';
|
|
517
|
-
const value = rawValue.split(splitChar).map(val => val.trim());
|
|
518
|
-
parsed.push({
|
|
519
|
-
operation: name.trim(),
|
|
520
|
-
value
|
|
521
|
-
});
|
|
598
|
+
return parsed;
|
|
599
|
+
};
|
|
600
|
+
const parseAngle = (value) => {
|
|
601
|
+
const unitsRegexp = /(-?\d*\.?\d*)(\w*)?/i;
|
|
602
|
+
const [, angle, unit] = unitsRegexp.exec(value);
|
|
603
|
+
const number = Number.parseFloat(angle);
|
|
604
|
+
return unit === 'rad' ? (number * 180) / Math.PI : number;
|
|
605
|
+
};
|
|
606
|
+
const normalizeTransformOperation = ({ operation, value }) => {
|
|
607
|
+
switch (operation) {
|
|
608
|
+
case 'scale': {
|
|
609
|
+
const [scaleX, scaleY = scaleX] = value.map((num) => Number.parseFloat(num));
|
|
610
|
+
return { operation: 'scale', value: [scaleX, scaleY] };
|
|
611
|
+
}
|
|
612
|
+
case 'scaleX': {
|
|
613
|
+
return { operation: 'scale', value: [Number.parseFloat(value), 1] };
|
|
614
|
+
}
|
|
615
|
+
case 'scaleY': {
|
|
616
|
+
return { operation: 'scale', value: [1, Number.parseFloat(value)] };
|
|
617
|
+
}
|
|
618
|
+
case 'rotate': {
|
|
619
|
+
return { operation: 'rotate', value: [parseAngle(value)] };
|
|
620
|
+
}
|
|
621
|
+
case 'translate': {
|
|
622
|
+
return {
|
|
623
|
+
operation: 'translate',
|
|
624
|
+
value: value.map((num) => Number.parseFloat(num)),
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
case 'translateX': {
|
|
628
|
+
return {
|
|
629
|
+
operation: 'translate',
|
|
630
|
+
value: [Number.parseFloat(value), 0],
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
case 'translateY': {
|
|
634
|
+
return { operation: 'translate', value: [0, Number.parseFloat(value)] };
|
|
635
|
+
}
|
|
636
|
+
case 'skew': {
|
|
637
|
+
return { operation: 'skew', value: value.map(parseAngle) };
|
|
638
|
+
}
|
|
639
|
+
case 'skewX': {
|
|
640
|
+
return { operation: 'skew', value: [parseAngle(value), 0] };
|
|
641
|
+
}
|
|
642
|
+
case 'skewY': {
|
|
643
|
+
return { operation: 'skew', value: [0, parseAngle(value)] };
|
|
644
|
+
}
|
|
645
|
+
default: {
|
|
646
|
+
return { operation, value: value.map((num) => Number.parseFloat(num)) };
|
|
647
|
+
}
|
|
522
648
|
}
|
|
523
|
-
}
|
|
524
|
-
return parsed;
|
|
525
|
-
};
|
|
526
|
-
const parseAngle = value => {
|
|
527
|
-
const unitsRegexp = /(-?\d*\.?\d*)(\w*)?/i;
|
|
528
|
-
const [, angle, unit] = unitsRegexp.exec(value);
|
|
529
|
-
const number = Number.parseFloat(angle);
|
|
530
|
-
return unit === 'rad' ? number * 180 / Math.PI : number;
|
|
531
|
-
};
|
|
532
|
-
const normalizeTransformOperation = _ref => {
|
|
533
|
-
let {
|
|
534
|
-
operation,
|
|
535
|
-
value
|
|
536
|
-
} = _ref;
|
|
537
|
-
switch (operation) {
|
|
538
|
-
case 'scale':
|
|
539
|
-
{
|
|
540
|
-
const [scaleX, scaleY = scaleX] = value.map(num => Number.parseFloat(num));
|
|
541
|
-
return {
|
|
542
|
-
operation: 'scale',
|
|
543
|
-
value: [scaleX, scaleY]
|
|
544
|
-
};
|
|
545
|
-
}
|
|
546
|
-
case 'scaleX':
|
|
547
|
-
{
|
|
548
|
-
return {
|
|
549
|
-
operation: 'scale',
|
|
550
|
-
value: [Number.parseFloat(value), 1]
|
|
551
|
-
};
|
|
552
|
-
}
|
|
553
|
-
case 'scaleY':
|
|
554
|
-
{
|
|
555
|
-
return {
|
|
556
|
-
operation: 'scale',
|
|
557
|
-
value: [1, Number.parseFloat(value)]
|
|
558
|
-
};
|
|
559
|
-
}
|
|
560
|
-
case 'rotate':
|
|
561
|
-
{
|
|
562
|
-
return {
|
|
563
|
-
operation: 'rotate',
|
|
564
|
-
value: [parseAngle(value)]
|
|
565
|
-
};
|
|
566
|
-
}
|
|
567
|
-
case 'translate':
|
|
568
|
-
{
|
|
569
|
-
return {
|
|
570
|
-
operation: 'translate',
|
|
571
|
-
value: value.map(num => Number.parseFloat(num))
|
|
572
|
-
};
|
|
573
|
-
}
|
|
574
|
-
case 'translateX':
|
|
575
|
-
{
|
|
576
|
-
return {
|
|
577
|
-
operation: 'translate',
|
|
578
|
-
value: [Number.parseFloat(value), 0]
|
|
579
|
-
};
|
|
580
|
-
}
|
|
581
|
-
case 'translateY':
|
|
582
|
-
{
|
|
583
|
-
return {
|
|
584
|
-
operation: 'translate',
|
|
585
|
-
value: [0, Number.parseFloat(value)]
|
|
586
|
-
};
|
|
587
|
-
}
|
|
588
|
-
case 'skew':
|
|
589
|
-
{
|
|
590
|
-
return {
|
|
591
|
-
operation: 'skew',
|
|
592
|
-
value: value.map(parseAngle)
|
|
593
|
-
};
|
|
594
|
-
}
|
|
595
|
-
case 'skewX':
|
|
596
|
-
{
|
|
597
|
-
return {
|
|
598
|
-
operation: 'skew',
|
|
599
|
-
value: [parseAngle(value), 0]
|
|
600
|
-
};
|
|
601
|
-
}
|
|
602
|
-
case 'skewY':
|
|
603
|
-
{
|
|
604
|
-
return {
|
|
605
|
-
operation: 'skew',
|
|
606
|
-
value: [0, parseAngle(value)]
|
|
607
|
-
};
|
|
608
|
-
}
|
|
609
|
-
default:
|
|
610
|
-
{
|
|
611
|
-
return {
|
|
612
|
-
operation,
|
|
613
|
-
value: value.map(num => Number.parseFloat(num))
|
|
614
|
-
};
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
649
|
};
|
|
618
|
-
const normalize = operations => {
|
|
619
|
-
|
|
650
|
+
const normalize = (operations) => {
|
|
651
|
+
return operations.map((operation) => normalizeTransformOperation(operation));
|
|
620
652
|
};
|
|
621
|
-
const processTransform = value => {
|
|
622
|
-
|
|
623
|
-
|
|
653
|
+
const processTransform = (key, value) => {
|
|
654
|
+
if (typeof value !== 'string')
|
|
655
|
+
return { [key]: value };
|
|
656
|
+
return { [key]: normalize(parse(value)) };
|
|
624
657
|
};
|
|
625
|
-
|
|
626
|
-
const
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
extrabold: 800,
|
|
639
|
-
heavy: 900,
|
|
640
|
-
black: 900
|
|
641
|
-
};
|
|
642
|
-
const processFontWeight = value => {
|
|
643
|
-
if (!value) return FONT_WEIGHTS.normal;
|
|
644
|
-
if (typeof value === 'number') return value;
|
|
645
|
-
const lv = value.toLowerCase();
|
|
646
|
-
if (FONT_WEIGHTS[lv]) return FONT_WEIGHTS[lv];
|
|
647
|
-
return value;
|
|
658
|
+
const Y_AXIS_SHORTHANDS = { top: true, bottom: true };
|
|
659
|
+
const sortTransformOriginPair = (a, b) => {
|
|
660
|
+
if (Y_AXIS_SHORTHANDS[a])
|
|
661
|
+
return 1;
|
|
662
|
+
if (Y_AXIS_SHORTHANDS[b])
|
|
663
|
+
return -1;
|
|
664
|
+
return 0;
|
|
665
|
+
};
|
|
666
|
+
const getTransformOriginPair = (values) => {
|
|
667
|
+
if (!values || values.length === 0)
|
|
668
|
+
return ['center', 'center'];
|
|
669
|
+
const pair = values.length === 1 ? [values[0], 'center'] : values;
|
|
670
|
+
return pair.sort(sortTransformOriginPair);
|
|
648
671
|
};
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
const
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
const {
|
|
660
|
-
percent
|
|
661
|
-
} = matchPercent(value) || {};
|
|
662
|
-
if (percent) return percent * fontSize;
|
|
663
|
-
|
|
664
|
-
// Unitless values: use this number multiplied by the element's font size
|
|
665
|
-
return isNaN(value) ? value : value * fontSize;
|
|
672
|
+
// Transforms shorthand transformOrigin values
|
|
673
|
+
const processTransformOriginShorthand = (key, value, container) => {
|
|
674
|
+
const match = `${value}`.split(' ');
|
|
675
|
+
const pair = getTransformOriginPair(match);
|
|
676
|
+
const transformOriginX = transformUnit(container, pair[0]);
|
|
677
|
+
const transformOriginY = transformUnit(container, pair[1]);
|
|
678
|
+
return {
|
|
679
|
+
transformOriginX: offsetKeyword(transformOriginX) || castFloat(transformOriginX),
|
|
680
|
+
transformOriginY: offsetKeyword(transformOriginY) || castFloat(transformOriginY),
|
|
681
|
+
};
|
|
666
682
|
};
|
|
667
|
-
|
|
668
|
-
const
|
|
669
|
-
|
|
670
|
-
if (typeof value !== 'string') return value;
|
|
671
|
-
if (matchNumber(value)) return parseFloat(value);
|
|
672
|
-
return value;
|
|
683
|
+
const processTransformOriginValue = (key, value, container) => {
|
|
684
|
+
const v = transformUnit(container, value);
|
|
685
|
+
return { [key]: offsetKeyword(v) || castFloat(v) };
|
|
673
686
|
};
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
return '0%';
|
|
680
|
-
case 'right':
|
|
681
|
-
case 'bottom':
|
|
682
|
-
return '100%';
|
|
683
|
-
case 'center':
|
|
684
|
-
return '50%';
|
|
685
|
-
default:
|
|
686
|
-
return null;
|
|
687
|
-
}
|
|
687
|
+
const handlers$1 = {
|
|
688
|
+
transform: processTransform,
|
|
689
|
+
transformOrigin: processTransformOriginShorthand,
|
|
690
|
+
transformOriginX: processTransformOriginValue,
|
|
691
|
+
transformOriginY: processTransformOriginValue,
|
|
688
692
|
};
|
|
689
693
|
|
|
690
|
-
const transformObjectPosition = value => offsetKeyword(value) || castFloat(value);
|
|
691
|
-
|
|
692
|
-
const transformTransformOrigin = value => offsetKeyword(value) || castFloat(value);
|
|
693
|
-
|
|
694
694
|
const handlers = {
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
695
|
+
fill: processColorValue,
|
|
696
|
+
stroke: processColorValue,
|
|
697
|
+
strokeDasharray: processNoopValue,
|
|
698
|
+
strokeWidth: processUnitValue,
|
|
699
|
+
fillOpacity: processNumberValue,
|
|
700
|
+
strokeOpacity: processNumberValue,
|
|
701
|
+
fillRule: processNoopValue,
|
|
702
|
+
textAnchor: processNoopValue,
|
|
703
|
+
strokeLinecap: processNoopValue,
|
|
704
|
+
strokeLinejoin: processNoopValue,
|
|
705
|
+
visibility: processNoopValue,
|
|
706
|
+
clipPath: processNoopValue,
|
|
707
|
+
dominantBaseline: processNoopValue,
|
|
706
708
|
};
|
|
707
709
|
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
if (!styles) return styles;
|
|
722
|
-
const propsArray = Object.keys(styles);
|
|
723
|
-
const resolvedStyle = {};
|
|
724
|
-
for (let i = 0; i < propsArray.length; i += 1) {
|
|
725
|
-
const key = propsArray[i];
|
|
726
|
-
const value = styles[key];
|
|
727
|
-
const transformed = transformStyle(key, value, styles, container);
|
|
728
|
-
resolvedStyle[key] = transformed;
|
|
729
|
-
}
|
|
730
|
-
return resolvedStyle;
|
|
710
|
+
const shorthands = {
|
|
711
|
+
...handlers$b,
|
|
712
|
+
...handlers$a,
|
|
713
|
+
...handlers$9,
|
|
714
|
+
...handlers$8,
|
|
715
|
+
...handlers$7,
|
|
716
|
+
...handlers$6,
|
|
717
|
+
...handlers$5,
|
|
718
|
+
...handlers$4,
|
|
719
|
+
...handlers$3,
|
|
720
|
+
...handlers$2,
|
|
721
|
+
...handlers$1,
|
|
722
|
+
...handlers,
|
|
731
723
|
};
|
|
732
|
-
|
|
733
724
|
/**
|
|
734
|
-
*
|
|
725
|
+
* Expand the shorthand properties.
|
|
735
726
|
*
|
|
736
|
-
* @param
|
|
737
|
-
* @
|
|
727
|
+
* @param style - Style object
|
|
728
|
+
* @returns Expanded style object
|
|
738
729
|
*/
|
|
739
|
-
const
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
730
|
+
const resolve = (container) => (style) => {
|
|
731
|
+
const propsArray = Object.keys(style);
|
|
732
|
+
const resolvedStyle = {};
|
|
733
|
+
for (let i = 0; i < propsArray.length; i += 1) {
|
|
734
|
+
const key = propsArray[i];
|
|
735
|
+
const value = style[key];
|
|
736
|
+
if (!shorthands[key]) {
|
|
737
|
+
resolvedStyle[key] = value;
|
|
738
|
+
continue;
|
|
739
|
+
}
|
|
740
|
+
const resolved = shorthands[key](key, value, container, style);
|
|
741
|
+
const keys = Object.keys(resolved);
|
|
742
|
+
for (let j = 0; j < keys.length; j += 1) {
|
|
743
|
+
const propName = keys[j];
|
|
744
|
+
const propValue = resolved[propName];
|
|
745
|
+
resolvedStyle[propName] = propValue;
|
|
746
|
+
}
|
|
748
747
|
}
|
|
749
|
-
return
|
|
750
|
-
...acc,
|
|
751
|
-
[key]: styles[key]
|
|
752
|
-
};
|
|
753
|
-
}, {});
|
|
748
|
+
return resolvedStyle;
|
|
754
749
|
};
|
|
755
750
|
|
|
756
751
|
/**
|
|
757
752
|
* Resolves styles
|
|
758
753
|
*
|
|
759
|
-
* @param
|
|
760
|
-
* @param
|
|
761
|
-
* @returns
|
|
754
|
+
* @param container
|
|
755
|
+
* @param style - Style
|
|
756
|
+
* @returns Resolved style
|
|
762
757
|
*/
|
|
763
758
|
const resolveStyles = (container, style) => {
|
|
764
|
-
|
|
765
|
-
|
|
759
|
+
const computeMediaQueries = (value) => resolveMediaQueries(container, value);
|
|
760
|
+
return compose(resolve(container), computeMediaQueries, flatten)(style);
|
|
766
761
|
};
|
|
767
762
|
|
|
768
|
-
export { resolveStyles as default, flatten,
|
|
763
|
+
export { resolveStyles as default, flatten, transformColor };
|