-
Notifications
You must be signed in to change notification settings - Fork 0
/
style.ts
68 lines (61 loc) · 2.15 KB
/
style.ts
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 { BREAKPOINTS_BASE_VALUE_KEY } from './constants';
import { createBreakpointStyles } from './createBreakpointStyles';
import { StyleOptions, Styles, WithTheme } from './types';
const DEFAULT_ARRAY_RESOLVER = (value: Array<string | number>) =>
value.join(' ');
export function style<P, T extends {} = never, B extends {} = never>({
cssProp,
prop,
themeProp,
arrayResolver = DEFAULT_ARRAY_RESOLVER,
}: StyleOptions<P, T>) {
let breakpointKeys: string[];
return function styleImplementation(
props: WithTheme<P, T, B>,
): Styles | undefined {
const propValue = props[prop];
if (propValue === undefined || propValue === null) {
return undefined;
}
const themeValue =
themeProp && props.theme
? (props.theme[themeProp] as { [index: string]: any })
: undefined;
const finalValue =
themeValue &&
(typeof propValue === 'string' || typeof propValue === 'number') &&
Object(themeValue) === themeValue
? themeValue[propValue] || propValue
: Array.isArray(propValue)
? arrayResolver(propValue, themeValue as any)
: propValue;
if (typeof finalValue === 'string' || typeof finalValue === 'number') {
return {
[cssProp]: finalValue,
};
} else if (!props.theme || !props.theme.breakpoints) {
return undefined;
}
const { breakpoints } = props.theme;
// We rely on the fact that `Object.keys` enumerates keys in the way
// they are added to an object. This should be consistent across engines.
// In case that a bug is discovered we will have to switch to an implicit
// ordering passed in by the consumer.
// This also prevents dynamic theme changes. If we want to support this
// in the future we have to store `theme` as well and do an equality check
// to determine when to re-generate breakpoint keys;
const bpkeys =
breakpointKeys ||
(breakpointKeys = [BREAKPOINTS_BASE_VALUE_KEY].concat(
Object.keys(breakpoints),
));
return createBreakpointStyles(
props.theme,
bpkeys,
finalValue,
themeValue,
cssProp,
arrayResolver,
);
};
}