| 
1 | 1 | import Layout from '@src/Layout'  | 
2 |  | -import { BreakpointBehavior } from '@const/defaultOptions'  | 
3 |  | -import propAliases from '@const/propAliases'  | 
 | 2 | +import { BreakpointBehavior, Breakpoint } from '@const/defaultOptions'  | 
 | 3 | +import propAliases, { PropAliasDeclaration } from '@const/propAliases'  | 
4 | 4 | import parsePropName, { Props } from '@utils/strings/parsePropName'  | 
5 | 5 | import isset from '@utils/functions/isset'  | 
6 | 6 | import createMediaQuery from '../createMediaQuery'  | 
@@ -28,37 +28,76 @@ const createStyleString = (  | 
28 | 28 |     : styleProps  | 
29 | 29 | }  | 
30 | 30 | 
 
  | 
 | 31 | +interface PropAliasGroup {  | 
 | 32 | +  propAlias: PropAliasDeclaration  | 
 | 33 | +  records: Array<{  | 
 | 34 | +    propValue: any  | 
 | 35 | +    breakpoint: Breakpoint  | 
 | 36 | +    behavior: BreakpointBehavior  | 
 | 37 | +  }>  | 
 | 38 | +}  | 
 | 39 | + | 
31 | 40 | /**  | 
32 | 41 |  * Produces a CSS string based on the given component props.  | 
33 | 42 |  * Takes only known prop aliases, ignores all the other props.  | 
34 | 43 |  */  | 
35 | 44 | export default function applyStyles(pristineProps: Props): string {  | 
36 |  | -  return Object.entries(pristineProps)  | 
37 |  | -    .reduce<string[]>((css, [pristinePropName, pristinePropValue]) => {  | 
38 |  | -      const { purePropName, breakpoint, behavior } = parsePropName(  | 
39 |  | -        pristinePropName,  | 
40 |  | -      )  | 
41 |  | -      const propAlias = propAliases[purePropName]  | 
 | 45 | +  // First, split pritstine component's props into prop alias groups.  | 
 | 46 | +  // This allows to operate with each prop alias with all its records at once.  | 
 | 47 | +  const propAliasGroups = Object.entries(pristineProps)  | 
 | 48 | +    // Filter out props with "undefined" or "null" as a value.  | 
 | 49 | +    .filter(([_, propValue]) => isset(propValue))  | 
 | 50 | +    .reduce<Record<string, PropAliasGroup>>(  | 
 | 51 | +      (groups, [pristinePropName, pristinePropValue]) => {  | 
 | 52 | +        const { purePropName, breakpoint, behavior } = parsePropName(  | 
 | 53 | +          pristinePropName,  | 
 | 54 | +        )  | 
 | 55 | +        const propAlias = propAliases[purePropName]  | 
 | 56 | + | 
 | 57 | +        // Filter out props that are not in the known prop aliases.  | 
 | 58 | +        if (!propAlias) {  | 
 | 59 | +          return groups  | 
 | 60 | +        }  | 
 | 61 | + | 
 | 62 | +        const prevRecords = groups[purePropName]  | 
 | 63 | +          ? groups[purePropName].records  | 
 | 64 | +          : []  | 
 | 65 | +        const nextRecords = prevRecords.concat({  | 
 | 66 | +          breakpoint,  | 
 | 67 | +          behavior,  | 
 | 68 | +          propValue: pristinePropValue,  | 
 | 69 | +        })  | 
 | 70 | +        const groupItem: PropAliasGroup = {  | 
 | 71 | +          propAlias,  | 
 | 72 | +          records: nextRecords,  | 
 | 73 | +        }  | 
42 | 74 | 
 
  | 
43 |  | -      // Filter out props with "undefined" or "null" as a value.  | 
44 |  | -      // Filter out props that are not in the known prop aliases.  | 
45 |  | -      if (!isset(pristineProps[pristinePropName]) || !propAlias) {  | 
46 |  | -        return css  | 
47 |  | -      }  | 
 | 75 | +        return {  | 
 | 76 | +          ...groups,  | 
 | 77 | +          [purePropName]: groupItem,  | 
 | 78 | +        }  | 
 | 79 | +      },  | 
 | 80 | +      {},  | 
 | 81 | +    )  | 
48 | 82 | 
 
  | 
 | 83 | +  return Object.entries(propAliasGroups)  | 
 | 84 | +    .reduce<string[]>((css, [_, propAliasGroup]) => {  | 
 | 85 | +      const { propAlias, records } = propAliasGroup  | 
49 | 86 |       const { props, transformValue } = propAlias  | 
50 |  | -      const propValue = transformValue  | 
51 |  | -        ? transformValue(pristinePropValue)  | 
52 |  | -        : pristinePropValue  | 
53 | 87 | 
 
  | 
54 |  | -      const styleString = createStyleString(  | 
55 |  | -        props,  | 
56 |  | -        propValue,  | 
57 |  | -        breakpoint,  | 
58 |  | -        behavior,  | 
59 |  | -      )  | 
 | 88 | +      const styles = records.map(({ breakpoint, behavior, propValue }) => {  | 
 | 89 | +        const transformedPropValue = transformValue  | 
 | 90 | +          ? transformValue(propValue)  | 
 | 91 | +          : propValue  | 
 | 92 | +        return createStyleString(  | 
 | 93 | +          props,  | 
 | 94 | +          transformedPropValue,  | 
 | 95 | +          breakpoint,  | 
 | 96 | +          behavior,  | 
 | 97 | +        )  | 
 | 98 | +      })  | 
60 | 99 | 
 
  | 
61 |  | -      return css.concat(styleString)  | 
 | 100 | +      return css.concat(styles)  | 
62 | 101 |     }, [])  | 
63 | 102 |     .join(' ')  | 
64 | 103 | }  | 
0 commit comments