UNPKG

react-native-unistyles

Version:
237 lines (229 loc) 6.68 kB
import { normalizeColor } from '../normalizer'; import { isUnistylesMq, isValidMq, parseMq } from './mqParser'; import { generateReactNativeWebId } from './generateId'; export const createMediaQueryForStyles = (styles, runtime) => { const withMediaQueries = Object.entries(styles).filter(([, value]) => typeof value === 'object').reduce((acc, [prop, value]) => { const objectKeys = Object.keys(value); const mediaQueries = objectKeys.filter(key => isUnistylesMq(key)); const breakpoints = objectKeys.filter(key => runtime.breakpoints[key]); if (mediaQueries.length === 0 && breakpoints.length === 0) { return acc; } const className = generateReactNativeWebId(prop, '""'); const breakpointsStyles = getBreakpointsStyles(prop, value, runtime, className); const mediaQueriesStyles = getMediaQueriesFromMQ(prop, value, className); return { ...acc, [prop]: ` ${breakpointsStyles} ${mediaQueriesStyles} `.trim() }; }, {}); return { ...styles, ...withMediaQueries }; }; const getMaxWidthMediaQuery = width => { if (!width) { return ''; } if (width.to === Infinity) { return ''; } return `and (max-width: ${width.to}px)`; }; const getMaxHeightMediaQuery = height => { if (!height) { return ''; } if (height.to === Infinity) { return ''; } return `and (max-height: ${height.to}px)`; }; const getMediaQueriesFromMQ = (prop, value, className) => Object.entries(value).reduce((acc, [key, value]) => { const result = parseMq(key); if (!isValidMq(result)) { return acc; } if (result.width && result.height) { return `${acc} @media screen and (min-width: ${result.width.from}px) and (min-height: ${result.height.from}px) ${getMaxWidthMediaQuery(result.width)} ${getMaxHeightMediaQuery(result.height)} { .${className} { ${normalizePropName(prop)}: ${normalizeWebValue(prop, value)}; } } `; } if (result.width) { return `${acc} @media screen and (min-width: ${result.width.from}px) ${getMaxWidthMediaQuery(result.width)} { .${className} { ${normalizePropName(prop)}: ${normalizeWebValue(prop, value)}; } } `; } if (result.height) { return `${acc} @media screen and (min-height: ${result.height.from}px) ${getMaxHeightMediaQuery(result.height)} { .${className} { ${normalizePropName(prop)}: ${normalizeWebValue(prop, value)}; } } `; } return acc; }, ''); const getBreakpointsStyles = (prop, value, runtime, className) => Object.entries(value).reduce((acc, [key, value]) => { const breakpoint = runtime.breakpoints[key]; if (breakpoint === undefined) { return acc; } return `${acc} @media screen and (min-width: ${breakpoint}px) { .${className} { ${normalizePropName(prop)}: ${normalizeWebValue(prop, value)}; } } `; }, ''); const normalizePropName = prop => prop.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); const normalizeWebValue = (prop, value) => { if (value === undefined) { return 'unset'; } switch (prop) { // colors case 'color': case 'backgroundColor': case 'borderColor': case 'borderBottomColor': case 'borderLeftColor': case 'borderRightColor': case 'borderTopColor': case 'borderBlockColor': case 'borderBlockEndColor': case 'borderBlockStartColor': case 'textDecorationColor': return normalizeColor(value); // dimensions case 'width': case 'height': case 'minWidth': case 'minHeight': case 'maxWidth': case 'maxHeight': case 'borderRadius': case 'borderWidth': case 'borderBottomLeftRadius': case 'borderBottomRightRadius': case 'borderEndEndRadius': case 'borderEndStartRadius': case 'borderStartEndRadius': case 'borderStartStartRadius': case 'borderTopLeftRadius': case 'borderTopRightRadius': case 'borderBottomWidth': case 'borderLeftWidth': case 'borderRightWidth': case 'borderTopWidth': case 'bottom': case 'left': case 'right': case 'top': case 'marginTop': case 'marginBottom': case 'marginLeft': case 'marginRight': case 'paddingTop': case 'paddingBottom': case 'paddingLeft': case 'paddingRight': case 'flexBasis': case 'rowGap': case 'columnGap': case 'gap': case 'margin': case 'padding': case 'fontSize': case 'letterSpacing': return `${value}px`; // without unit case 'borderStyle': case 'pointerEvents': case 'backfaceVisibility': case 'alignContent': case 'alignItems': case 'alignSelf': case 'flexDirection': case 'flexWrap': case 'flex': case 'aspectRatio': case 'opacity': case 'direction': case 'zIndex': case 'justifyContent': case 'overflow': case 'display': case 'position': case 'flexGrow': case 'flexShrink': case 'fontFamily': case 'fontStyle': case 'textDecorationLine': case 'textAlign': case 'textDecorationStyle': case 'lineHeight': case 'textTransform': case 'fontVariant': case 'verticalAlign': case 'objectFit': return value; // to be transformed for now // not supported case 'marginHorizontal': case 'paddingHorizontal': case 'marginVertical': case 'paddingVertical': case 'shadowColor': case 'shadowOffset': case 'shadowOpacity': case 'shadowRadius': case 'transform': case 'transformMatrix': case 'fontWeight': case 'textShadowOffset': case 'textShadowRadius': case 'textShadowColor': return ''; // unsupported case 'borderStartColor': case 'borderEndColor': case 'borderEndWidth': case 'borderBottomEndRadius': case 'borderBottomStartRadius': case 'borderCurve': case 'elevation': case 'borderTopEndRadius': case 'borderTopStartRadius': case 'borderStartWidth': case 'start': case 'end': case 'margin-end': case 'margin-start': case 'padding-end': case 'padding-start': case 'writingDirection': case 'textAlignVertical': case 'includeFontPadding': case 'resizeMode': case 'overlayColor': case 'tintColor': default: return ''; } }; //# sourceMappingURL=cssMediaQuery.js.map