Skip to content

Instantly share code, notes, and snippets.

@smashercosmo
Last active May 29, 2019 12:09
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 smashercosmo/d376b5386fec785ba5f9c7c1d297f23d to your computer and use it in GitHub Desktop.
Save smashercosmo/d376b5386fec785ba5f9c7c1d297f23d to your computer and use it in GitHub Desktop.
tailwind
:global {
@tailwind utilities;
.flex-wrap-wrap {
flex-wrap: wrap;
}
.flex-wrap-nowrap {
flex-wrap: nowrap;
}
@responsive {
.display-flex {
display: flex;
}
.display-block {
display: block;
}
.display-inline {
display: inline;
}
.align-items-flex-start {
align-items: flex-start;
}
.align-items-flex-end {
align-items: flex-end;
}
.align-items-center {
align-items: center;
}
.align-items-baseline {
align-items: baseline;
}
.justify-content-flex-start {
justify-content: flex-start;
}
.justify-content-flex-end {
justify-content: flex-end;
}
.justify-content-center {
justify-content: center;
}
.justify-content-space-around {
justify-content: space-around;
}
.justify-content-space-between {
justify-content: space-between;
}
}
}
import React from 'react'
type ResponsiveType<T> =
| T
| [T]
| [T, T]
| [T, T, T]
| [T, T, T, T]
| [T, T, T, T, T]
type SpacingType = 0 | 5 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50
type MarginSpacingType = SpacingType | 'auto'
type DisplayType = 'flex' | 'block' | 'inline'
type AlignItemsType = 'flex-start' | 'flex-end' | 'center' | 'baseline'
type FlexWrapType = 'wrap' | 'nowrap'
type BgType =
| 'white'
| 'red'
| 'pink'
| 'green'
| 'grey'
| 'grey-dark'
| 'grey-light'
| 'grey-x-light'
| 'blue'
| 'blue-dark'
| 'blue-x-dark'
type JustifyContentType =
| 'flex-start'
| 'flex-end'
| 'center'
| 'space-around'
| 'space-between'
type ResponsiveSpacingType = ResponsiveType<SpacingType>
type ResponsiveMarginType = ResponsiveType<MarginSpacingType>
type ResponsiveDisplayType = ResponsiveType<DisplayType>
type ResponsiveAlignItemsType = ResponsiveType<AlignItemsType>
type ResponsiveJustifyContentType = ResponsiveType<JustifyContentType>
export type BoxProps = {
children: React.ReactNode
text?: 12 | 14 | 16 | 18 | 24 | 32
display?: ResponsiveDisplayType
'align-items'?: ResponsiveAlignItemsType
'justify-content'?: ResponsiveJustifyContentType
'flex-wrap'?: FlexWrapType
bg?: BgType
m?: ResponsiveMarginType
mx?: ResponsiveMarginType
my?: ResponsiveMarginType
ml?: ResponsiveMarginType
mr?: ResponsiveMarginType
mt?: ResponsiveMarginType
mb?: ResponsiveMarginType
p?: ResponsiveSpacingType
px?: ResponsiveSpacingType
py?: ResponsiveSpacingType
pl?: ResponsiveSpacingType
pr?: ResponsiveSpacingType
pt?: ResponsiveSpacingType
pb?: ResponsiveSpacingType
}
type ResponsivePropName = keyof Omit<BoxProps, 'children' | 'className'>
const breakpointsPrefixes = ['' /* xs */, 'sm-', 'md-', 'lg-', 'xl-']
const responsivePropNames: ResponsivePropName[] = [
'display',
'align-items',
'justify-content',
'flex-wrap',
'text',
'bg',
'm',
'my',
'mx',
'ml',
'mr',
'mt',
'mb',
'p',
'py',
'px',
'pl',
'pr',
'pt',
'pb',
]
function generateResponsiveClassNamesForProp(
responsivePropValues: any[],
responsivePropName: ResponsivePropName,
): string {
return responsivePropValues.reduce(
(classesString, responsivePropValue, i) => {
const responsivePropValueStr = String(responsivePropValue)
const breakpointPrefix = breakpointsPrefixes[i]
const responsiveClassName = `${breakpointPrefix}${responsivePropName}-${responsivePropValueStr}`
return classesString
? `${classesString} ${responsiveClassName}`
: responsiveClassName
},
'',
)
}
function generateResponsiveClassNamesForProps(props: BoxProps) {
return responsivePropNames.reduce(
(classesFinalString, responsivePropName: ResponsivePropName) => {
const responsivePropValue = props[responsivePropName]
if (!responsivePropValue && responsivePropValue !== 0) {
return classesFinalString
}
const responsivePropValues = Array.isArray(responsivePropValue)
? responsivePropValue
: [responsivePropValue]
const responsiveClassNames = generateResponsiveClassNamesForProp(
responsivePropValues,
responsivePropName,
)
return classesFinalString
? `${classesFinalString} ${responsiveClassNames}`
: responsiveClassNames
},
'',
)
}
function Box(props: BoxProps) {
const { children } = props
const classes = generateResponsiveClassNamesForProps(props)
return <div className={classes}>{children}</div>
}
export { Box }
import React from 'react'
import { Box } from '../Box/Box'
function SomeComponent() {
return (
<Box
display="flex"
align-items="center"
flex-wrap="wrap"
pt={45}
pb={15}
px={30}>
Hello
</Box>
)
}
export { SomeComponent }
const { sm, md, lg, xl } = require('./media-breakpoints')
module.exports = {
prefix: '',
important: false,
separator: '-',
theme: {
screens: {
sm,
md,
lg,
xl,
},
colors: {
white: 'white',
green: 'var(--green-color)',
blue: 'var(--blue-color)',
'blue-dark': 'var(--blue-dark-color)',
'blue-x-dark': 'var(--blue-xdark-color)',
red: 'var(--red-color)',
'grey-light': 'var(--grey-light-color)',
'grey-x-light': 'var(--grey-xlight-color)',
grey: 'var(--grey-color)',
'grey-dark': 'var(--grey-dark-color)',
pink: 'var(--pink-color)',
},
spacing: {
0: '0',
5: '5px',
10: '10px',
15: '15px',
20: '20px',
25: '25px',
30: '30px',
35: '35px',
40: '40px',
45: '45px',
50: '50px',
},
fontSize: {
12: '12px',
14: '14px',
16: '16px',
18: '18px',
24: '24px',
32: '32px',
},
margin: theme => ({
auto: 'auto',
...theme('spacing'),
}),
padding: theme => ({
...theme('spacing'),
}),
backgroundColor: theme => theme('colors'),
},
variants: {
backgroundColor: [],
},
corePlugins: ['fontSize', 'margin', 'padding', 'backgroundColor'],
plugins: [],
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment