2020-03-31 13:47:59 +08:00

348 lines
7.9 KiB
JavaScript

// import { prefix } from 'inline-style-prefixer';
import { filterUndefinedValue, stripObject } from './util';
const getPadding = padding => {
if (!Array.isArray(padding)) {
return {
padding,
};
}
const attrs = [
'paddingTop',
'paddingRight',
'paddingBottom',
'paddingLeft',
];
const paddings = {};
let value;
attrs.forEach((attr, index) => {
switch (padding.length) {
case 1:
value = padding[0] || 0;
break;
case 2:
value = padding[index] || padding[index - 2] || 0;
break;
case 3:
value =
index === 2
? padding[2]
: padding[index] || padding[index - 2] || 0;
break;
case 4:
default:
value = padding[index] || 0;
break;
}
paddings[attr] = value;
});
return paddings;
};
const getMargin = (
size,
{ isNegative, half } = { isNegative: false, half: false }
) => {
if (!size) {
return {};
}
const attrs = ['marginTop', 'marginRight', 'marginBottom', 'marginLeft'];
const margins = {};
const param = 1 * (isNegative ? -1 : 1) * (half ? 0.5 : 1);
let value;
attrs.forEach((attr, index) => {
if (!Array.isArray(size)) {
value = param * size;
} else {
switch (size.length) {
case 1:
value = param * (size[0] || 0);
break;
case 2:
value = param * (size[index] || size[index - 2] || 0);
break;
case 3:
value =
param *
(index === 2
? size[2]
: size[index] || size[index - 2] || 0);
break;
case 4:
default:
value = param * (size[index] || 0);
break;
}
}
margins[attr] = value;
});
return margins;
};
const getChildMargin = spacing => {
return getMargin(spacing, { half: true });
};
const getSpacingMargin = spacing => {
return getMargin(spacing, { half: true });
};
const getSpacingHelperMargin = spacing => {
return getMargin(spacing, { isNegative: true, half: true });
};
const getFlexs = flex => {
if (!Array.isArray(flex)) {
return {
flex,
};
}
const attrs = ['flexGrow', 'flexShrink', 'flexBasis'];
const flexs = {};
flex.forEach((val, index) => {
flexs[attrs[index]] = val;
});
return flexs;
};
const getGridGap = gap => {
if (!Array.isArray(gap)) {
return {
gap,
};
}
const attrs = ['rowGap', 'columnGap'];
const gaps = {};
gap.forEach((val, index) => {
gaps[attrs[index]] = val;
});
return gaps;
};
const getTemplateCount = counts => {
if (!isNaN(counts)) {
return `repeat(${counts}, minmax(0,1fr))`;
}
return counts;
};
// const outerProps = ['alignSelf', 'flexGrow', 'flexShrink', 'flexBasis', 'backgroundColor', 'boxShadow', 'borderRadius', 'borderWidth', 'borderStyle', 'borderColor', 'padding', 'paddingTop', 'paddingLeft', 'paddingRight', 'paddingBottom'];
const helperProps = [
'margin',
'marginTop',
'marginLeft',
'marginRight',
'marginBottom',
];
const innerProps = [
'flexDirection',
'flexWrap',
'justifyContent',
'alignContent',
'alignItems',
'display',
];
const filterOuterStyle = style => {
const props = {};
[...innerProps].forEach(key => {
props[key] = style[key];
});
return filterUndefinedValue(stripObject(style, props));
};
const filterHelperStyle = style => {
const props = {};
helperProps.forEach(key => {
props[key] = style[key];
});
return filterUndefinedValue({
...props,
overflow: 'hidden',
});
};
const filterInnerStyle = style => {
const props = {};
innerProps.forEach(key => {
props[key] = style[key];
});
return filterUndefinedValue(props);
};
const getGridChildProps = (props, device) => {
const {
row = 'initial',
col = 'initial',
rowSpan = 1,
colSpan = 1,
// justifySelf,
// alignSelf,
} = props;
let newColSpan =
typeof colSpan === 'object' && 'desktop' in colSpan
? colSpan.desktop
: colSpan;
['tablet', 'phone'].forEach(deviceKey => {
if (deviceKey === device) {
if (typeof colSpan === 'object' && device in colSpan) {
newColSpan = colSpan[device];
} else {
switch (deviceKey) {
case 'tablet':
newColSpan = colSpan > 5 ? 8 : colSpan > 2 ? 4 : 2;
break;
case 'phone':
newColSpan = colSpan > 2 ? 4 : 2;
break;
}
}
}
});
return filterUndefinedValue({
gridRowStart: row,
gridRowEnd: `span ${rowSpan}`,
gridColumnStart: col,
gridColumnEnd: `span ${newColSpan}`,
// gridRow: `${row} / span ${rowSpan}`,
// gridColumn: `${col} / span ${colSpan}`,
// justifySelf,
// alignSelf,
});
};
const getBoxChildProps = props => {
const { alignSelf, flex } = props;
return filterUndefinedValue({
alignSelf,
...getFlexs(flex),
});
};
export default ({
device,
display,
gap,
direction,
dense,
rowSpan,
colSpan,
row,
col,
rows,
columns,
justify,
// justifySelf,
align,
alignSelf,
wrap,
flex,
padding,
margin,
}) => {
let style = {
...getPadding(padding),
};
let deviceColumns = 'auto';
switch (device) {
case 'phone':
deviceColumns = 4;
break;
case 'tablet':
deviceColumns = 8;
break;
case 'desktop':
deviceColumns = 12;
break;
default:
break;
}
const newColumns = !isNaN(columns) ? columns : deviceColumns;
switch (display) {
case 'grid':
style = {
// parent
...getGridGap(gap),
gridTemplateRows: getTemplateCount(rows),
gridTemplateColumns: getTemplateCount(newColumns),
gridAutoFlow: `${direction}${dense && ` dense`}`,
// justifyItems: justify,
// alignItems: align,
// child
...getGridChildProps(
{
row,
rowSpan,
col,
colSpan,
// justifySelf,
// alignSelf,
},
device
),
...style,
};
break;
case 'flex':
style = {
// parent
flexDirection: direction,
flexWrap: wrap ? 'wrap' : 'nowrap',
justifyContent: justify,
alignItems: align,
...getMargin(margin),
// child
...getBoxChildProps({
alignSelf,
flex,
}),
...style,
};
break;
default:
break;
}
// return prefix(style);
return filterUndefinedValue(style);
};
export {
getMargin,
getChildMargin,
getSpacingMargin,
getSpacingHelperMargin,
filterInnerStyle,
filterOuterStyle,
filterHelperStyle,
getGridChildProps,
// getBoxChildProps,
};