-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
86 lines (67 loc) · 1.89 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
import React from 'react';
const OBSS_ID = '_obss';
const ctx = this || {};
let cache = {
c: 0
};
const getSheet = target => {
let sheet = target ? target.querySelector('#' + OBSS_ID) : self[OBSS_ID];
if (!sheet) {
let _target = target || document.head;
sheet = _target.appendChild(document.createElement('style'));
sheet.innerHTML = ' ';
sheet.id = OBSS_ID;
}
return sheet.firstChild;
};
const updateSheet = (css, sheet, append) => {
if (sheet.data.indexOf(css) < 0) {
sheet.data += css;
}
};
const toHash = str =>
'.obss' + str.split('').reduce((out, i) => (out + i.charCodeAt(0)) | 8, 4);
const toRule = (styles, className) => `${className} { ${styles} }`;
const createStyles = (styles, props) => {
if (typeof styles !== 'object') {
console.error('Please provide an object');
return '';
}
return Object.keys(styles)
.map(
key =>
`${key}: ${
typeof styles[key] === 'function' ? styles[key](props) : styles[key]
};`
)
.join('');
};
const hashStyles = ({props = {}, sheet, styles}) => {
// look up or generate and cache hash
const styleStr = createStyles(styles, props);
const cacheId = JSON.stringify(styleStr);
const className = cache[cacheId] || (cache[cacheId] = toHash(cacheId));
// look up or create rule
const rule =
cache[className] || (cache[className] = toRule(styleStr, className));
// update sheet with rule
updateSheet(rule, sheet);
// return classname without .
return className.slice(1);
};
export const css = styleObject =>
hashStyles({
sheet: getSheet(ctx.target),
styles: styleObject
});
export const styled = (tag, styleObject) => {
return function Obss(props = {}) {
const _props = {...props};
_props.className = hashStyles({
props,
sheet: getSheet(ctx.target),
styles: styleObject
});
return React.createElement(tag, _props);
};
};