-
Notifications
You must be signed in to change notification settings - Fork 19
/
index.js
67 lines (57 loc) · 1.76 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
/* eslint-disable no-param-reassign */
export default function(breakpoints, { literal, overlap } = {}) {
const mq = literal ? breakpoints : ['&'].concat(breakpoints)
function flatten(obj) {
if (typeof obj !== 'object' || obj == null) {
return []
}
if (Array.isArray(obj)) {
return obj.map(flatten)
}
const slots = {}
const objects = {}
const props = {}
Object.keys(obj).forEach(key => {
// Check if value is an array, but skip if it looks like a selector.
// key.indexOf('&') === 0
let item = obj[key]
if (!Array.isArray(item) && literal) item = [item]
if ((literal || Array.isArray(item)) && key.charCodeAt(0) !== 38) {
let prior
item.forEach((v, index) => {
// Optimize by removing duplicated media query entries
// when they are explicitly known to overlap.
if (overlap && prior === v) {
return
}
if (v == null) {
// Do not create entries for undefined values as this will
// generate empty media media quries
return
}
prior = v
if (index === 0 && !literal) {
props[key] = v
} else if (slots[mq[index]] === undefined) {
slots[mq[index]] = { [key]: v }
} else {
slots[mq[index]][key] = v
}
})
} else if (typeof item === 'object') {
objects[key] = flatten(item)
} else {
props[key] = item
}
})
// Ensure that all slots and then child objects are pushed to the end
mq.forEach(el => {
if (slots[el]) {
props[el] = slots[el];
}
})
Object.assign(props, objects)
return props
}
return (...values) => values.map(flatten)
}