/ shared / components / src / components / Shelf / utils / getGridVars.ts
getGridVars.ts
 1  // eslint-disable-next-line import/no-extraneous-dependencies
 2  import type { ShelfConfigOptions } from '@amp/web-app-components/config/components/shelf';
 3  import { ShelfConfig } from '@amp/web-app-components/config/components/shelf';
 4  import {
 5      GRID_COLUMN_GAP_DEFAULT,
 6      GRID_COLUMN_GAP_DEFAULT_XSMALL,
 7      GRID_ROW_GAP_DEFAULT,
 8      // eslint-disable-next-line import/no-extraneous-dependencies
 9  } from '@amp/web-app-components/src/components/Shelf/constants';
10  import type { GridType } from '@amp/web-app-components/src/components/Shelf/types';
11  import type { Sizes, Size } from '@amp/web-app-components/src/types';
12  
13  const generateGridColSizeVars = (
14      viewport: Size,
15      gridValues: ShelfConfigOptions['GRID_VALUES'][string],
16      maxContents: ShelfConfigOptions['GRID_MAX_CONTENT'][string],
17  ): string[] => {
18      const value = gridValues[viewport];
19      const maxContent = maxContents[viewport];
20      const gridVars = [];
21  
22      if (maxContent) {
23          // create CSS variable for px values in grid
24          gridVars.push(`--grid-max-content-${viewport}: ${maxContent};`);
25      } else if (value) {
26          // create CSS variable for grid unit
27          gridVars.push(`--grid-${viewport}: ${value};`);
28      }
29  
30      return gridVars;
31  };
32  
33  const generateGridGapSizeVars = (
34      viewport: Size,
35      gridColumnGap: Partial<ShelfConfigOptions['GRID_COL_GAP'][string]>,
36      gridRowGap: Partial<ShelfConfigOptions['GRID_ROW_GAP'][string]>,
37  ): string[] => {
38      const gridVars = [];
39      const defaultColGap =
40          viewport === 'xsmall'
41              ? GRID_COLUMN_GAP_DEFAULT_XSMALL
42              : GRID_COLUMN_GAP_DEFAULT;
43  
44      // check if gap override for certain viewport
45      gridVars.push(
46          `--grid-column-gap-${viewport}: ${
47              gridColumnGap[viewport] ?? defaultColGap
48          }px;`,
49      );
50      gridVars.push(
51          `--grid-row-gap-${viewport}: ${
52              gridRowGap[viewport] ?? GRID_ROW_GAP_DEFAULT
53          }px;`,
54      );
55  
56      return gridVars;
57  };
58  
59  /**
60   * converts the JS configs to CSS variables.
61   *
62   * variables created:
63   * --grid-{viewport} - grid value to use for columns widths
64   * --grid-max-content-{viewport} - px value to use for column width
65   * --grid-column-gap-{viewport} - grid gap size // default is 20px
66   * */
67  
68  // eslint-disable-next-line import/prefer-default-export
69  export const getGridVars = (type: GridType): string => {
70      const { GRID_VALUES, GRID_MAX_CONTENT, GRID_COL_GAP, GRID_ROW_GAP } =
71          ShelfConfig.get();
72  
73      const gridValues = GRID_VALUES[type];
74      const maxContent = GRID_MAX_CONTENT[type];
75      const gridRowGap = GRID_ROW_GAP[type] || {};
76      const gridColumnGap = GRID_COL_GAP[type] || {};
77      const gridKeys = Object.keys(gridValues) as unknown as Sizes;
78  
79      let gridVars: string[] = [];
80  
81      gridKeys.forEach((viewport) => {
82          // generate variables for each viewport
83          const gridColumnSizeVars = generateGridColSizeVars(
84              viewport,
85              gridValues,
86              maxContent,
87          );
88          const gridGapSizeVars = generateGridGapSizeVars(
89              viewport,
90              gridColumnGap,
91              gridRowGap,
92          );
93  
94          gridVars = [...gridVars, ...gridColumnSizeVars, ...gridGapSizeVars];
95      });
96  
97      return gridVars.join(' ');
98  };