blob: b39608715601dfc3b7d0332dc239fcd714796bee (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
import { unitless } from '../units';
import type { JSONValue } from '../types';
import isSerializable from './isSerializable';
import isBoxedPrimitive from './isBoxedPrimitive';
const hyphenate = (s: string) => {
if (s.startsWith('--')) {
// It's a custom property which is already well formatted.
return s;
}
return (
s
// Hyphenate CSS property names from camelCase version from JS string
.replace(/([A-Z])/g, (match, p1) => `-${p1.toLowerCase()}`)
// Special case for `-ms` because in JS it starts with `ms` unlike `Webkit`
.replace(/^ms-/, '-ms-')
);
};
// Some tools such as polished.js output JS objects
// To support them transparently, we convert JS objects to CSS strings
export default function toCSS(o: JSONValue): string {
if (Array.isArray(o)) {
return o.map(toCSS).join('\n');
}
if (isBoxedPrimitive(o)) {
return o.valueOf().toString();
}
return Object.entries(o)
.filter(
([, value]) =>
// Ignore all falsy values except numbers
typeof value === 'number' || value
)
.map(([key, value]) => {
if (isSerializable(value)) {
return `${key} { ${toCSS(value)} }`;
}
return `${hyphenate(key)}: ${
typeof value === 'number' &&
value !== 0 &&
// Strip vendor prefixes when checking if the value is unitless
!(
key.replace(
/^(Webkit|Moz|O|ms)([A-Z])(.+)$/,
(match, p1, p2, p3) => `${p2.toLowerCase()}${p3}`
) in unitless
)
? `${value}px`
: value
};`;
})
.join(' ');
}
|