import { css } from '@emotion/react'; import { breakpoints, componentGrids, pageGrid, } from '../../../../src/style/variables'; import { GumComponentGridGenerator, GumGeneratedGrids, GumGridConfigGenerated, GumGridGapGenerator, GumGridGenerator, GumTemplateGenerator, } from '../models'; /** * Generates CSS fragments for grid row and column gap, depending on the config * @param gap Gap object with row and column property */ const getGridGap: GumGridGapGenerator = (gap) => { if (!gap) return ''; const { column, row } = gap; if (!column && !row) { return ''; } if (column && !row) { return css` grid-column-gap: ${column}px; `; } if (row && !column) { return css` grid-row-gap: ${row}px; `; } return css` grid-gap: ${row}px ${column}px; `; }; /** * Generates grid template based either on the cols property (just columns) * or grid and row properties of template object * @param param0 */ const getGridTemplate: GumTemplateGenerator = ({ cols, template }) => { if (cols) { return css` grid-template-columns: repeat(${cols}, 1fr); `; } if (template) { const { column, row } = template; if (column && !row) { return css` grid-template-columns: ${column}; `; } if (row && !column) { return css` grid-template-rows: ${row}; `; } return css` grid-template-columns: ${column}; grid-template-rows: ${row}; `; } return ''; }; /** * Generates grid config utils based on variables.ts config * @param gridConfig */ export const generateGridConfig: GumGridGenerator = (gridConfig = pageGrid) => { const configFragment = gridConfig.map( ({ mediaMinWidth, cols, template, gap }, index) => { const gridConfig = css` ${getGridTemplate({ cols, template })} ${getGridGap(gap)} `; /** * If grid starts on a specific media query */ if (index === 0 && mediaMinWidth) { return css` @media ${breakpoints[mediaMinWidth]} { display: grid; ${gridConfig} } `; } /** * Grid config on a specific breakpoint */ if (mediaMinWidth) { return css` @media ${breakpoints[mediaMinWidth]} { ${gridConfig} } `; } /** * Grid config for non-media query */ return css` display: grid; ${gridConfig}; `; }, ); /** * Combine individual fragments into a single fragment */ return css` ${configFragment.map((config) => config)} `; }; /** * Generates additional user-defined grid CSS fragments */ export const generateAdditionalGridConfig: GumComponentGridGenerator = () => { const additionalConfig = {} as GumGridConfigGenerated; for (const key in componentGrids) { if (componentGrids.hasOwnProperty(key)) { additionalConfig[key] = generateGridConfig(componentGrids[key]); } } return additionalConfig; }; /** * Generates CSS fragment utils for grid columns and rows */ export const generateGridRowsAndColumns = () => { const gridRowsAndColumns = { template: { colsNone: css` grid-template-columns: none; `, rowsNone: css` grid-template-rows: none; `, }, colSpan: {}, colStart: {}, colEnd: {}, rowSpan: {}, rowStart: {}, rowEnd: {}, } as any; for (let c = 1; c <= 12; c++) { if (c <= 6) { gridRowsAndColumns.template[`rows${c}`] = css` grid-template-rows: repeat(${c}, minmax(0, 1fr)); `; gridRowsAndColumns.rowSpan[`r${c}`] = css` grid-row: span ${c} / span ${c}; `; gridRowsAndColumns.rowStart[`r${c}`] = css` grid-row-start: ${c}; `; gridRowsAndColumns.rowEnd[`r${c}`] = css` grid-row-end: ${c}; `; } gridRowsAndColumns.template[`cols${c}`] = css` grid-template-columns: repeat(${c}, minmax(0, 1fr)); `; gridRowsAndColumns.colSpan[`c${c}`] = css` grid-column: span ${c} / span ${c}; `; gridRowsAndColumns.colStart[`c${c}`] = css` grid-column-start: ${c}; `; gridRowsAndColumns.colEnd[`c${c}`] = css` grid-column-end: ${c}; `; } return gridRowsAndColumns as GumGeneratedGrids; };