import React from 'react'; import { reject } from 'rambda'; const computeBoxStyle = ( { // Maybe rhythm props. margin, marginVertical = margin, marginHorizontal = margin, marginTop = marginVertical, marginBottom = marginVertical, marginLeft = marginHorizontal, marginRight = marginHorizontal, padding, paddingVertical = padding, paddingHorizontal = padding, paddingTop = paddingVertical, paddingBottom = paddingVertical, paddingLeft = paddingHorizontal, paddingRight = paddingHorizontal, height, maxHeight, maxWidth, minHeight, minWidth, width, bottom, left, right, top, flex, backgroundColor, color, cursor, textAlign, fontSize, // Border props. borderColor, // We can't use borderColor as default because some component in React Native, // for example Image, doesn't support that. borderBottomColor, borderLeftColor, borderRightColor, borderTopColor, borderRadius, borderBottomLeftRadius = borderRadius, borderBottomRightRadius = borderRadius, borderTopLeftRadius = borderRadius, borderTopRightRadius = borderRadius, borderWidth, borderBottomWidth = borderWidth, borderLeftWidth = borderWidth, borderRightWidth = borderWidth, borderTopWidth = borderWidth, borderStyle, boxShadow, // Just value props. alignContent, alignItems, alignSelf, flexBasis, flexDirection, flexGrow, flexShrink, flexWrap, justifyContent, opacity, overflow, overflowX, overflowY, pointerEvents, position, textOverflow, whiteSpace, zIndex, ...props }, ) => { let style = { position: 'relative', flexDirection: 'column', display: 'flex', }; if (typeof flex === 'number') { style.flexBasis = 'auto'; style.flexGrow = flex; style.flexShrink = 1; } const justValueProps = { margin, marginVertical, marginHorizontal, marginTop, marginBottom, marginLeft, marginRight, padding, paddingVertical, paddingHorizontal, paddingTop, paddingBottom, paddingLeft, paddingRight, height, maxHeight, maxWidth, minHeight, minWidth, width, bottom, left, right, top, flex, backgroundColor, color, cursor, textAlign, fontSize, // Border props. borderColor, // We can't use borderColor as default because some component in React Native, // for example Image, doesn't support that. borderBottomColor, borderLeftColor, borderRightColor, borderTopColor, borderRadius, borderBottomLeftRadius, borderBottomRightRadius, borderTopLeftRadius, borderTopRightRadius, borderWidth, borderBottomWidth, borderLeftWidth, borderRightWidth, borderTopWidth, borderStyle, boxShadow, // Just value props. alignContent, alignItems, alignSelf, flexBasis, flexDirection, flexGrow, flexShrink, flexWrap, justifyContent, opacity, overflow, overflowX, overflowY, pointerEvents, position, textOverflow, whiteSpace, zIndex, }; Object.keys(justValueProps) .filter(prop => { const value = justValueProps[prop]; const isDefined = typeof value === 'number' || value; return isDefined; }) .forEach(prop => { const value = justValueProps[prop]; style[prop] = value; }); return [style, props]; }; class Box extends React.PureComponent { render() { const { as = 'div', className, style, nativeRef, ...props } = this.props; const [boxStyle, restProps] = computeBoxStyle(props); let combinedStyles = { ...boxStyle, ...style, }; combinedStyles = reject(val => Number.isNaN(val), combinedStyles); const styles = { style: combinedStyles, className }; return React.createElement(as, { ...restProps, ...styles, ref: nativeRef }); } } export default Box;