Skip to content

Instantly share code, notes, and snippets.

@sutter
Last active June 2, 2020 08:50
Show Gist options
  • Save sutter/0f40fa5a73c0ae92668101272364cad6 to your computer and use it in GitHub Desktop.
Save sutter/0f40fa5a73c0ae92668101272364cad6 to your computer and use it in GitHub Desktop.
import { rem } from 'polished';
import PropTypes from 'prop-types';
import React from 'react';
import styled from 'styled-components';
import { breakpoint, mediaQueryMin, spacer } from '../../../styles/theme';
const size = width => ` flex-basis: ${width}%; max-width: ${width}%;`;
/**
* GridCol
*
* @param {object} props
* @param {object} props.style
* @param {React.ReactNode} props.children
* @param {number} props.widthSmartphone
* @param {number} props.widthTablet
* @param {number} props.widthDesktop
* @param {number} props.order
* @param {number} props.grow
* @param {string} props.basis
* @param {Array<['auto', 'flex-start', 'flex-end', 'center', 'baseline', 'stretch']>} props.alignSelf
* @returns {React.ReactNode}
*/
export const GridColEl = styled.div`
flex-grow: ${props => props.grow};
flex-shrink: ${props => props.shrink};
flex-basis: 100%;
max-width: 100%;
align-self: ${props => props.alignSelf};
order: ${props => props.order};
${props => props.widthSmartphone && size(props.widthSmartphone)}
${props =>
props.widthTablet &&
`${mediaQueryMin(breakpoint.smartphone)} { ${size(props.widthTablet)}}`}
${props =>
props.widthDesktop &&
`${mediaQueryMin(breakpoint.desktop)} { ${size(props.widthDesktop)}}`};
> * {
height: 100%;
}
`;
export const GridCol = ({
style,
children,
widthSmartphone,
widthTablet,
widthDesktop,
order,
grow,
shrink,
alignSelf,
}) => (
<GridColEl
widthSmartphone={widthSmartphone}
widthTablet={widthTablet}
widthDesktop={widthDesktop}
order={order}
grow={grow}
shrink={shrink}
alignSelf={alignSelf}
style={style}
>
{children}
</GridColEl>
);
GridCol.defaultProps = {
style: null,
children: null,
widthSmartphone: 100,
widthTablet: 100,
widthDesktop: 100,
order: 0,
grow: 1,
shrink: 1,
alignSelf: 'auto',
};
GridCol.propTypes = {
style: PropTypes.shape({}),
children: PropTypes.node,
widthSmartphone: PropTypes.number,
widthTablet: PropTypes.number,
widthDesktop: PropTypes.number,
order: PropTypes.number,
grow: PropTypes.number,
shrink: PropTypes.number,
alignSelf: PropTypes.oneOf([
'auto',
'flex-start',
'flex-end',
'center',
'baseline',
'stretch',
]),
};
/**
* Grid
*
* @param {object} props
* @param {object} props.style
* @param {React.ReactNode} props.children
* @param {string} props.spacerXSize
* @param {string} props.spacerYSize
* @param {Array<[ 'row', 'row-reverse', 'column', 'column-reverse']>} props.direction
* @param {Array<['flex-start','flex-end','center','space-between','space-around','space-evenly']>} props.justifyContent
* @param {Array<['flex-start','flex-end','center','space-between','space-around','stretch']>} props.alignContent
* @param {Array<['auto', 'flex-start', 'flex-end', 'center', 'baseline']>} props.alignItems
* @returns {React.ReactNode}
*/
const GridEl = styled.div`
display: flex;
flex-wrap: wrap;
flex-direction: ${props => props.direction};
justify-content: ${props => props.justifyContent};
align-items: ${props => props.alignItems};
align-content: ${props => props.alignContent};
margin: ${props =>
`-${rem(props.spacerYSize / 2)} -${rem(props.spacerXSize / 2)}`};
${GridColEl} {
padding: ${props =>
`${rem(props.spacerYSize / 2)} ${rem(props.spacerXSize / 2)}`};
}
`;
export const Grid = ({
style,
children,
spacerXSize,
spacerYSize,
direction,
justifyContent,
alignItems,
alignContent,
}) => (
<GridEl
spacerXSize={spacerXSize}
spacerYSize={spacerYSize}
direction={direction}
justifyContent={justifyContent}
alignItems={alignItems}
alignContent={alignContent}
style={style}
>
{children}
</GridEl>
);
Grid.defaultProps = {
style: null,
children: null,
spacerXSize: spacer.s,
spacerYSize: spacer.m,
direction: 'row',
justifyContent: 'flex-start',
alignItems: 'stretch',
alignContent: 'flex-start',
};
Grid.propTypes = {
style: PropTypes.shape({}),
children: PropTypes.node,
spacerXSize: PropTypes.string,
spacerYSize: PropTypes.string,
direction: PropTypes.oneOf([
'row',
'row-reverse',
'column',
'column-reverse',
]),
justifyContent: PropTypes.oneOf([
'flex-start',
'flex-end',
'center',
'space-between',
'space-around',
'space-evenly',
]),
alignItems: PropTypes.oneOf([
'auto',
'flex-start',
'flex-end',
'center',
'baseline',
'stretch',
]),
alignContent: PropTypes.oneOf([
'flex-start',
'flex-end',
'center',
'space-between',
'space-around',
]),
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment