-
Notifications
You must be signed in to change notification settings - Fork 12
/
index.js
68 lines (60 loc) · 2.31 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
import translate from './translate.js';
import defaultTheme, { globals } from './theme.js';
import merge from './util/merge.js';
import normalize from './util/normalize.js';
import { css } from './vendor/otion.js';
// For server side rendering with client hydration
export { setup, hydrate } from './vendor/otion.js';
// Provide link to file and line number with warnings
const warn = (theme) => (message) => {
const msg = [message, new Error().stack.split('at ').pop()].join(' ');
if (theme.strict) throw msg;
console.warn(msg);
};
export const process = (theme) => (strings, values) => {
// Normalize rules into an array
const rules = normalize(strings, values);
// Keep track of processed rules this rule set
const seen = {};
// Go through each rule in the array and translate to css
const styles = rules.map((rule) => {
// Warn about any duplicate rule declarations
if (seen[rule]) warn(theme)(`Duplicate declaration of "${rule}"`);
// Mark rule as seen
seen[rule] = true;
// Split the rule into parts
rule = rule.split(':');
// Seperate out directive from variants
let directive = rule.pop();
let variants = rule;
// Lookup translation for directive
let translation = translate(theme)(directive);
// Warn if there was no translation for the given directive
if (!Object.keys(translation)[0] || !Object.values(translation)[0]) {
warn(theme)(`No translation for "${directive}"`);
}
// Apply variants to the translation
variants.reverse().forEach((variant) => {
let size = theme.screens[variant];
if (size) {
translation = {
'@media': { [`(min-width: ${size})`]: translation },
};
} else translation = { [`:${variant}`]: translation };
});
// Return translation with variants applied
return translation;
});
// Deep merge all translations
return merge(...styles);
};
// Utility for merging a provided theme with the default theme
export const configure = (theme) =>
merge(defaultTheme(merge(globals, theme)), theme);
// Return process primed with a provided theme
export const themed = (theme = {}) => {
const processWithTheme = process(configure(theme));
return (strings, ...values) => css(processWithTheme(strings, values));
};
// Return process primed with the default theme
export default themed();