UNPKG

@baransu/react-styled-flexboxgrid

Version:

Grid system based on styled-components and flexbox for React

112 lines (97 loc) 2.27 kB
import PropTypes from "prop-types"; import styled from "@emotion/styled"; import { css } from "@emotion/core"; import isInteger from "lodash.isinteger"; import config, { DIMENSION_NAMES } from "../config"; const ModificatorType = PropTypes.oneOfType([PropTypes.number, PropTypes.bool]); const offsetProps = DIMENSION_NAMES.map(d => d + "Offset"); const DimensionPropTypes = DIMENSION_NAMES.reduce((propTypes, dimension) => { propTypes[dimension] = ModificatorType; propTypes[dimension + "Offset"] = PropTypes.number; return propTypes; }, {}); const content = (p, k) => { const grid = ` ${(100 / config(p).gridSize) * p[k]}% `; return ` ${ isInteger(p[k]) ? // Integer value ` flex-basis: ${grid}; max-width: ${grid}; display: block; ` : // Boolean p[k] ? // Auto-width ` flex-grow: 1; flex-basis: 0; max-width: 100%; display: block; ` : // Hide element ` display: none; ` } `; }; const col = (p, k) => { return ` @media ${config(p).media[k]} { ${content(p, k)} } `; }; let column = p => css` ${Object.keys(p) .filter(k => ~DIMENSION_NAMES.indexOf(k)) .sort( (k1, k2) => DIMENSION_NAMES.indexOf(k1) - DIMENSION_NAMES.indexOf(k2) ) .map(k => col(p, k)) .join("\n")} `; const reverse = p => p.reverse ? css` flex-direction: column-reverse; ` : css``; const margin = p => css` ${Object.keys(p) .filter(k => ~offsetProps.indexOf(k)) .map(k => { return ` @media ${config(p).media[k.replace(/Offset$/, "")]} { margin-left: ${(100 / config(p).gridSize) * p[k]}%; } `; }) .join("\n")} `; const padding = p => css` ${config(p).gutterWidth / 2}rem; `; const Col = styled.div` box-sizing: border-box; flex: 0 0 auto; padding-right: ${padding} padding-left: ${padding} ${column} ${reverse} ${margin} `; Col.displayName = "Col"; Col.propTypes = { ...DimensionPropTypes, reverse: PropTypes.bool, children: PropTypes.node }; export default Col;