A simple React component for implementing responsive grid-based layouts, without any dependencies. It uses the native CSS Grid Layout properties to align elements into columns and rows. It is written in TypeScript as a Styled-Component for React or React Native projects.
/*
* Entry point for React grid system
* React implementation of CSS grid layout written in TypeScript as a styled-component
* Licensed under MIT - (C) Alicia Sykes 2020 <https://aliciasykes.com>
*/
// FILE 1 - layout/index.ts
import Grid from './Grid';
import Cell from './Cell';
export { Grid, Cell };
// FILE 2 - layout/cell.ts
import styled from 'styled-components';
import { maxWidth } from '@styles/media-queries';
interface CellProps {
left?: number; // The horizontal starting position
width?: number; // How many cells to span, horizontally
top?: number; // The vertical starting position
height?: number; // How many cells to span, vertically
className?: string; // So Cell can optionally be used as a styled container
}
const Cell = styled.div<CellProps>`
${props => {
const { left, width, top, height } = props;
return `
grid-column-start: ${left || 'unset'};
grid-column-end: ${width ? `span ${width}` : 'unset'};
grid-row-start: ${top || 'unset'};
grid-row-end: ${height ? `span ${height}` : 'unset'};
overflow-x: hidden;
overflow-wrap: break-word;
word-wrap: break-word;
${maxWidth.tablet(`
// For tablet and above
grid-column-start: unset;
grid-row-start: unset;
`)};
`;
}}
`;
export default Cell;
// FILE 3 - layout/grid.ts
import React from 'react';
import styled from 'styled-components';
import { gridValues } from '@styles/sizes';
import { minWidth } from '@styles/media-queries';
const GridWrapper = styled.div<{ columns?: number; gutterOutside?: boolean }>`
${({ columns, gutterOutside }) => {
const { maxGridWidth, gutter, minRowHeight, minColWidth, numCols } = gridValues(columns);
const desktop = gridValues(columns, 8, 4);
return `
max-width: ${maxGridWidth};
margin: 0 auto;
display: grid;
grid-gap: ${gutter};
padding: 0 ${gutterOutside ? gutter : 0}
grid-auto-rows: minmax(${minRowHeight}, auto);
grid-template-columns: repeat(auto-fit, minmax(${minColWidth}, 1fr));
// For tablet and above
${minWidth.tablet(`
grid-template-columns: repeat(${numCols}, 1fr);
`)};
// For desktop and above
${minWidth.desktop(`
max-width: ${desktop.maxGridWidth};
grid-gap: ${desktop.gutter};
`)}
`;
}}
`;
const Grid: React.FC<{ className?: string; columns?: number; gutterOutside?: boolean }> = ({
className,
columns,
children,
gutterOutside,
}) => (
<GridWrapper className={className} columns={columns} gutterOutside={gutterOutside}>
{children}
</GridWrapper>
);
export default Grid;
// FILE 4 - layout/grid-dimensions.ts
expoert const gridValues = (columns = 12, colWidth = 8, gutterWidth = 2) => ({
maxGridWidth: sizeUnit(columns * colWidth + (columns - 1) * gutterWidth),
gutter: sizeUnit(gutterWidth),
minRowHeight: sizeUnit(5),
minColWidth: sizeUnit(colWidth),
numCols: columns,
});