-
Notifications
You must be signed in to change notification settings - Fork 461
/
styleHelper.js
130 lines (115 loc) · 3.89 KB
/
styleHelper.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import React, { Component, cloneElement, isValidElement } from 'react';
export function parseDimension(value) {
if (typeof value === 'number') {
return value + 'px';
} else if (value.match(/^[0-9]+$/)) {
return value + 'px';
}
return value;
}
export function applyDefaultProps(props, context, defaultProps) {
let finalProps = { ...props };
for (let prop in defaultProps) {
if (defaultProps.hasOwnProperty(prop)) {
if (!props[prop]) {
if (context[prop]) {
finalProps[prop] = context[prop];
} else {
finalProps[prop] = defaultProps[prop];
}
} else if (props[prop] && typeof props[prop] === 'boolean' && typeof defaultProps[prop] !== 'boolean') {
if (context.color) {
finalProps[prop] = context[prop];
} else {
finalProps[prop] = defaultProps[prop];
}
}
}
}
return finalProps;
}
export function hasProps(props, proptypes) {
if (!proptypes) return false;
for (let prop in props) {
if (props.hasOwnProperty(prop)) {
if (proptypes[prop] !== undefined) {
return true;
}
}
}
return false;
}
export function extractProps(props, proptypes) {
if (!proptypes) return [{}, {}];
let finalProps = {};
let extractedProps = {};
for (let prop in props) {
if (props.hasOwnProperty(prop)) {
if (proptypes[prop] !== undefined) {
extractedProps[prop] = props[prop];
} else {
finalProps[prop] = props[prop];
}
}
}
return [finalProps, extractedProps];
}
export function mapStyle(prevStyles, nextStyles, defaultStyles, styleCallback, stylesCallback, props) {
let finalStyles = { ...prevStyles };
if (defaultStyles) {
for (let key in defaultStyles) {
if (defaultStyles.hasOwnProperty(key)) {
finalStyles[key] = defaultStyles[key];
}
}
}
for (let key in nextStyles) {
if (nextStyles.hasOwnProperty(key)) {
if (styleCallback) {
const result = styleCallback(key, nextStyles[key], props);
if (result) {
finalStyles[result[0]] = result[1];
}
} else finalStyles[key] = nextStyles[key];
}
}
if (typeof stylesCallback === 'function') return stylesCallback(finalStyles, props);
return finalStyles;
}
export default function styleHelper(options, propTypes, mapStyleCallback, mapStylesCallback, mapProps) {
if (!mapProps || typeof mapProps !== 'function') {
mapProps = props => props;
}
function doStyleHelper(WrappedComponent) {
const [element, elementProps, defaultStyles] = options;
if (isValidElement(element)) {
if (hasProps(elementProps, propTypes) || hasProps(defaultStyles, propTypes)) {
const styles = extractProps(elementProps, propTypes)[1];
const props = element.props ? { ...element.props } : {};
props.style = mapStyle(props.style, styles, defaultStyles, mapStyleCallback, mapStylesCallback, elementProps);
return cloneElement(element, mapProps(props, element.props, true));
}
return cloneElement(element, mapProps(element.props, element.props, false));
} else {
let defaultStyles;
if (options && Object.prototype.toString.call(options) === '[object Array]') {
defaultStyles = options[0];
}
return class extends Component {
render() {
if (hasProps(this.props, propTypes) || hasProps(defaultStyles, propTypes)) {
let [props, styles] = extractProps(this.props, propTypes);
if (!props) props = {};
props.style = mapStyle(props.style, styles, defaultStyles, mapStyleCallback, mapStylesCallback, this.props);
return <WrappedComponent {...mapProps(props, this.props, true)}/>;
}
return <WrappedComponent {...mapProps(this.props, this.props, false)}/>
}
}
}
}
if (options[0] && isValidElement(options[0])) {
return doStyleHelper();
}
return doStyleHelper;
}