Skip to content

Instantly share code, notes, and snippets.

@bsgreenb
Created July 5, 2020 19:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bsgreenb/8478cf235ac994d69cc33e6224fb2354 to your computer and use it in GitHub Desktop.
Save bsgreenb/8478cf235ac994d69cc33e6224fb2354 to your computer and use it in GitHub Desktop.
GlowyStuff Grid V1
import React, { ReactNode } from "react";
import {
SpacerSizeProp,
spacerSizeBaseEm,
spacerSizeEm,
} from "../../styles/layout";
import {
DirectionProp,
JustifyProp,
AlignContentProp,
AlignItemsProp,
WrapProp,
} from "./flex";
// Inspired by Material UI Grid component https://material-ui.com/components/grid/
// https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/Grid/Grid.js
type GridProps = {
children: ReactNode;
direction?: DirectionProp;
justify?: JustifyProp;
alignContent?: AlignContentProp;
alignItems?: AlignItemsProp;
wrap?: WrapProp;
gap?: SpacerSizeProp;
};
const Grid = ({
children,
direction = "row",
justify = "flex-start",
alignItems = "stretch",
alignContent = "stretch",
wrap = "wrap",
gap = "md",
}: GridProps) => {
const gapHackOffset = spacerSizeBaseEm[gap] / 2;
return (
<div className="grid">
{children}
<style jsx>
{`
.grid {
display: flex;
box-sizing: border-box;
width: 100%;
}
`}
</style>
<style jsx>{`
.grid {
flex-flow: ${direction} ${wrap};
justify-content: ${justify};
align-items: ${alignItems};
align-content: ${alignContent};
margin: ${-1 * gapHackOffset}em;
width: calc(100% + ${spacerSizeEm[gap]});
:global(.grid-item) {
padding: ${gapHackOffset}em;
}
}
`}</style>
</div>
);
};
export default Grid;
/// GridItem.tsx:
import React, { ReactNode } from "react";
import css from "styled-jsx/css";
import { breakPointPx } from "../../styles/layout";
type ColumnsProp = number | "auto" | boolean;
const NUM_COLUMNS = 12;
type GridItemProps = {
children: ReactNode;
xs?: ColumnsProp;
sm?: ColumnsProp;
md?: ColumnsProp;
lg?: ColumnsProp;
xl?: ColumnsProp;
};
// See https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/Grid/Grid.js#L21
const getGridItemCss = (
columns: ColumnsProp,
bp: keyof typeof breakPointPx
) => {
const breakPoint = breakPointPx[bp];
if (columns === false) {
return { className: "", styles: "" };
} else if (columns === true) {
return css.resolve`
.grid-item {
@media (min-width: ${breakPoint}) {
flex: 1 1 0;
max-width: 100%;
}
}
`;
} else if (columns === "auto") {
return css.resolve`
.grid-item {
@media (min-width: ${breakPoint}) {
flex: 0 1 auto;
max-width: none;
}
}
`;
} else {
const width = `${Math.round((columns / NUM_COLUMNS) * 10e7) / 10e5}%`;
return css.resolve`
.grid-item {
@media (min-width: ${breakPoint}) {
flex: 1 1 ${width};
max-width: ${width};
}
}
`;
}
};
// Future: extract repeats here.
const GridItem = ({
children,
xs = false,
sm = false,
md = false,
lg = false,
xl = false,
}: GridItemProps) => {
const xsStyles = getGridItemCss(xs, "xs");
const smStyles = getGridItemCss(sm, "sm");
const mdStyles = getGridItemCss(md, "md");
const lgStyles = getGridItemCss(lg, "lg");
const xlStyles = getGridItemCss(xl, "xl");
return (
<div
className={`grid-item ${xsStyles.className} ${smStyles.className} ${mdStyles.className} ${lgStyles.className} ${xlStyles.className}`}
>
{children}
<style jsx>
{`
.grid-item {
box-sizing: border-box;
}
`}
</style>
{xsStyles.styles}
{smStyles.styles}
{mdStyles.styles}
{lgStyles.styles}
{xlStyles.styles}
</div>
);
};
export default GridItem;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment