Skip to content

Instantly share code, notes, and snippets.

@alevosia
Last active June 27, 2020 10:34
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 alevosia/d0679162f11abc4f5790354591b7c24c to your computer and use it in GitHub Desktop.
Save alevosia/d0679162f11abc4f5790354591b7c24c to your computer and use it in GitHub Desktop.
My components to implement a Flexbox Grid like those of Bootstrap
import styled from 'styled-components'
import { Breakpoints } from '../constants'
const TOTAL_COLUMNS = 12
// TYPES ===================================================================
type MediaQueryKey = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
type MediaQuery = {
[K in MediaQueryKey]: (styles: string) => string
}
interface ContainerProps {
fluid?: boolean | MediaQueryKey
}
interface ColumnProps {
size?: number
xs?: number
sm?: number
md?: number
lg?: number
xl?: number
collapse?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'
}
// MEDIA QUERIES ==============================================================
const mediaQueries: MediaQuery = {
xs: (styles: string): string => `
@media only screen and (max-width: ${Breakpoints.PHONE - 1}px) {
${styles}
}
`,
sm: (styles: string): string => `
@media only screen and (min-width: ${Breakpoints.PHONE}px) {
${styles}
}
`,
md: (styles: string): string => `
@media only screen and (min-width: ${Breakpoints.TABLET}px) {
${styles}
}
`,
lg: (styles: string): string => `
@media only screen and (min-width: ${Breakpoints.DESKTOP}px) {
${styles}
}
`,
xl: (styles: string): string => `
@media only screen and (min-width: ${Breakpoints.WIDE_DESKTOP}px) {
${styles}
}
`
}
// COLUMN STYLES ==============================================================
function getColumnStyles(columns: number) {
columns = columns > TOTAL_COLUMNS ? TOTAL_COLUMNS : columns < 1 ? 1 : columns
return `flex: 0 0 ${(columns / TOTAL_COLUMNS) * 100}%; max-width: ${
(columns / TOTAL_COLUMNS) * 100
}%`
}
// COMPONENTS ==================================================================
export const Container = styled.div<ContainerProps>`
border: 1px solid black;
width: 100%;
padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto;
${mediaQueries['sm'](`max-width: ${Breakpoints.PHONE - 30}px`)}
${mediaQueries['md'](`max-width: ${Breakpoints.TABLET - 48}px`)}
${mediaQueries['lg'](`max-width: ${Breakpoints.DESKTOP - 32}px`)}
${mediaQueries['xl'](`max-width: ${Breakpoints.WIDE_DESKTOP - 40}px`)}
${({ fluid }) => {
if (!fluid) return null
if (fluid === true) {
return 'max-width: none !important;'
}
if (mediaQueries[fluid]) {
return mediaQueries[fluid](`'max-width: none !important;'`)
}
return null
}}
`
export const Row = styled.div`
display: flex;
flex-wrap: wrap;
margin-left: -15px;
margin-right: -15px;
`
export const Column = styled.div<ColumnProps>`
position: relative;
max-width: 100%;
flex: ${({ size }) => size || 1};
padding-left: 15px;
padding-right: 15px;
border: 1px dashed gray;
${({ xs }) => xs && mediaQueries['xs'](getColumnStyles(xs))};
${({ sm }) => sm && mediaQueries['sm'](getColumnStyles(sm))};
${({ md }) => md && mediaQueries['md'](getColumnStyles(md))};
${({ lg }) => lg && mediaQueries['lg'](getColumnStyles(lg))};
${({ xl }) => xl && mediaQueries['xl'](getColumnStyles(xl))};
${({ collapse }) => collapse && mediaQueries[collapse](`display: none;`)}
`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment