UNPKG

native-base

Version:

Essential cross-platform UI components for React Native

178 lines (161 loc) 6.45 kB
/* eslint-disable */ //@ts-nocheck // This functions is taken from react native web import normalizeValueWithProperty from './normalizeValueWithProperty'; const canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); /** * The browser implements the CSS cascade, where the order of properties is a * factor in determining which styles to paint. React Native is different. It * gives giving precedence to the more specific style property. For example, * the value of `paddingTop` takes precedence over that of `padding`. * * This module creates mutally exclusive style declarations by expanding all of * React Native's supported shortform properties (e.g. `padding`) to their * longfrom equivalents. */ const emptyObject = {}; const supportsCSS3TextDecoration = !canUseDOM || window.CSS != null && window.CSS.supports != null && (window.CSS.supports('text-decoration-line', 'none') || window.CSS.supports('-webkit-text-decoration-line', 'none')); const ignoredProps = { elevation: true, overlayColor: true, resizeMode: true, tintColor: true }; const MONOSPACE_FONT_STACK = 'monospace,monospace'; const SYSTEM_FONT_STACK = '-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif'; const STYLE_SHORT_FORM_EXPANSIONS = { borderColor: ['borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor'], borderRadius: ['borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomRightRadius', 'borderBottomLeftRadius'], borderStyle: ['borderTopStyle', 'borderRightStyle', 'borderBottomStyle', 'borderLeftStyle'], borderWidth: ['borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth'], marginHorizontal: ['marginRight', 'marginLeft'], marginVertical: ['marginTop', 'marginBottom'], overflow: ['overflowX', 'overflowY'], overscrollBehavior: ['overscrollBehaviorX', 'overscrollBehaviorY'], paddingHorizontal: ['paddingRight', 'paddingLeft'], paddingVertical: ['paddingTop', 'paddingBottom'] }; /** * Transform */ // { scale: 2 } => 'scale(2)' // { translateX: 20 } => 'translateX(20px)' // { matrix: [1,2,3,4,5,6] } => 'matrix(1,2,3,4,5,6)' const mapTransform = transform => { const type = Object.keys(transform)[0]; //@ts-ignore const value = transform[type]; if (type === 'matrix' || type === 'matrix3d') { return "".concat(type, "(").concat(value.join(','), ")"); } else { const normalizedValue = normalizeValueWithProperty(value, type); return "".concat(type, "(").concat(normalizedValue, ")"); } }; export const createTransformValue = style => { let transform = style.transform; if (Array.isArray(style.transform)) { transform = style.transform.map(mapTransform).join(' '); } return transform; }; /** * Reducer */ const createReactDOMStyle = (style, isInline) => { if (!style) { return emptyObject; } const resolvedStyle = {}; for (const prop in style) { const value = style[prop]; if ( // Ignore everything with a null value value == null || // Ignore some React Native styles //@ts-ignore ignoredProps[prop]) { continue; } if (prop === 'aspectRatio') { resolvedStyle[prop] = value.toString(); } else if (prop === 'backgroundClip') { // TODO: remove once this issue is fixed // https://github.com/rofrischmann/inline-style-prefixer/issues/159 if (value === 'text') { resolvedStyle.backgroundClip = value; resolvedStyle.WebkitBackgroundClip = value; } } else if (prop === 'flex') { if (value === -1) { resolvedStyle.flexGrow = 0; resolvedStyle.flexShrink = 1; resolvedStyle.flexBasis = 'auto'; } else { resolvedStyle.flex = value; } } else if (prop === 'font') { resolvedStyle[prop] = value.replace('System', SYSTEM_FONT_STACK); } else if (prop === 'fontFamily') { if (value.indexOf('System') > -1) { const stack = value.split(/,\s*/); stack[stack.indexOf('System')] = SYSTEM_FONT_STACK; resolvedStyle[prop] = stack.join(','); } else if (value === 'monospace') { resolvedStyle[prop] = MONOSPACE_FONT_STACK; } else { resolvedStyle[prop] = value; } } else if (prop === 'fontVariant') { if (Array.isArray(value) && value.length > 0) { resolvedStyle.fontVariant = value.join(' '); } } else if (prop === 'textAlignVertical') { resolvedStyle.verticalAlign = value === 'center' ? 'middle' : value; } else if (prop === 'textDecorationLine') { // use 'text-decoration' for browsers that only support CSS2 // text-decoration (e.g., IE, Edge) if (!supportsCSS3TextDecoration) { resolvedStyle.textDecoration = value; } else { resolvedStyle.textDecorationLine = value; } } else if (prop === 'transform' || prop === 'transformMatrix') { resolvedStyle.transform = createTransformValue(style); } else if (prop === 'writingDirection') { resolvedStyle.direction = value; } else { const value = normalizeValueWithProperty(style[prop], prop); const longFormProperties = STYLE_SHORT_FORM_EXPANSIONS[prop]; if (isInline && prop === 'margin') { if (style.marginHorizontal == null) { resolvedStyle.marginLeft = value; resolvedStyle.marginRight = value; } if (style.marginVertical == null) { resolvedStyle.marginTop = value; resolvedStyle.marginBottom = value; } } else if (isInline && prop === 'padding') { if (style.paddingHorizontal == null) { resolvedStyle.paddingLeft = value; resolvedStyle.paddingRight = value; } if (style.paddingVertical == null) { resolvedStyle.paddingTop = value; resolvedStyle.paddingBottom = value; } } else if (longFormProperties) { longFormProperties.forEach((longForm, _i) => { // The value of any longform property in the original styles takes // precedence over the shortform's value. if (style[longForm] == null) { resolvedStyle[longForm] = value; } }); } else { resolvedStyle[prop] = Array.isArray(value) ? value.join(',') : value; } } } return resolvedStyle; }; export default createReactDOMStyle; //# sourceMappingURL=createReactDOMStyle.js.map