-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
100 lines (79 loc) · 2.52 KB
/
index.js
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
const postcss = require('postcss');
const PLUGIN_NAME = 'postcss-transition';
const pi = (o) => parseInt(o, 10);
const pf = (o) => parseFloat(o);
module.exports = (opts = {}) => {
return {
postcssPlugin: PLUGIN_NAME,
Once(root) {
const $opts = Object.assign(
{
min: '320px',
max: '1200px',
functionName: 'fluid',
},
opts
);
const regex = new RegExp(`${$opts.functionName}\\(([^)]+)\\)`, 'gi');
const mediaMin = [];
const mediaMax = [];
root.walkDecls((decl) => {
if (decl.value.indexOf(`${$opts.functionName}(`) === -1) {
return;
}
let min = decl.value.replace(regex, (_, values) => values.split(',').map((a) => a.trim())[0]);
let max = decl.value.replace(regex, (_, values) => values.split(',').map((a) => a.trim())[1]);
decl.value = decl.value.replace(regex, (_, values /*, index*/) => {
const { minVal, maxVal } = parseValues(values);
// TODO: Rem
// return `calc(${minValue} + ${maxValueInt} * (1px + ((100vw - ${$opts.min}) / (${p($opts.max)} - ${p($opts.min)})) - 1px))`;
// Px
return `calc(${minVal} + ${pf(maxVal) - pf(minVal)} * (100vw - ${$opts.min}) / ${pi($opts.max) - pi($opts.min)})`;
});
mediaMin.push({
selector: decl.parent.selector,
prop: decl.prop,
value: min,
});
mediaMax.push({
selector: decl.parent.selector,
prop: decl.prop,
value: max,
});
});
if (mediaMin.length) {
addMediaRule(root, `(max-width: ${$opts.min})`, mediaMin);
}
if (mediaMax.length) {
addMediaRule(root, `(min-width: ${$opts.max})`, mediaMax);
}
}
}
}
function addMediaRule(root, params, children) {
const m = postcss.atRule({ name: 'media', params });
let selectors = {};
for (let ch of children) {
if (!selectors[ch.selector]) {
selectors[ch.selector] = [{ prop: ch.prop, value: ch.value }];
} else {
selectors[ch.selector].push({ prop: ch.prop, value: ch.value });
}
}
for (let selector in selectors) {
const r = postcss.rule({ selector: selector });
for (let i of selectors[selector]) {
const v = postcss.decl({ prop: i.prop, value: i.value });
r.append(v);
}
m.append(r);
}
root.append(m);
}
function parseValues(values) {
const $values = values.split(',').map((a) => a.trim());
return {
minVal: $values[0],
maxVal: $values[1],
};
}