Skip to content

Instantly share code, notes, and snippets.

@tkh44
Last active August 16, 2022 16:28
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save tkh44/4a71f6ab1e60a0b717cae03c378b4686 to your computer and use it in GitHub Desktop.
Save tkh44/4a71f6ab1e60a0b717cae03c378b4686 to your computer and use it in GitHub Desktop.
emotion with styled-system.
import React from 'react'
import styled from 'emotion/react'
import { omit } from 'emotion/lib/utils'
import { space, width, fontSize, color, responsiveStyle } from 'styled-system'
import { baseCss } from './ui'
const defaultExcludedProps = [
'm',
'mt',
'mr',
'mb',
'ml',
'mx',
'my',
'p',
'pt',
'pr',
'pb',
'pl',
'px',
'py',
'fontSize'
]
export const flex = responsiveStyle('flex')
export const order = responsiveStyle('order')
const wrap = responsiveStyle('flex-wrap', 'wrap', 'wrap')
const direction = responsiveStyle('flex-direction', 'direction')
const align = props => responsiveStyle('align-items', 'align')
const justify = props => responsiveStyle('justify-content', 'justify')
const column = props => props.column ? `flex-direction:column;` : null
export default (tag, omitProps = []) => styled(props =>
React.createElement(tag, omit(props, defaultExcludedProps.concat(omitProps)))
)`
${space};
${width};
${fontSize};
${color};
${flex};
${order};
${wrap};
${column};
${direction};
${align};
${justify};
${baseCss};
`
import base from './base'
export default base('div')
import React from 'react'
import styled from 'emotion/react'
import base from '../base'
import Box from '../box'
import { linkCss } from '../ui'
import theme from '../theme'
const Base = styled(base('div'))`
display: flex;
flex-direction: column;
align-items: center;
position: relative;
border-radius: 6px;
background: ${theme.colors.white};
`
const Name = base('h3')
const Hr = styled(base('hr'))`
height: 1px;
width: 85%;
margin: 0 auto;
border: none;
background-color: ${theme.colors.gray[4]}
`
const Link = styled(base('a'))`
color: ${theme.colors.gray[6]};
text-decoration: none;
&:hover {
color: ${theme.colors.green[5]};
}
`
export default function ({ data }) {
return (
<Base pt={[1, 1, 2, 2]} pb={[1, 1, 2, 2]}>
<Name color={theme.colors.gray[8]} fontSize={theme.fontSizes[5]}>
{data.name}
</Name>
<Hr />
<Box row justify='space-between' p={theme.scale[1]}>
{Object.keys(data.links).map(type =>
<Link href={data.links[type]} p={[1, 1, 2, 2]}>
{type
.split('-')
.map(t => `${t.charAt(0).toUpperCase()}${t.slice(1)}`)
.join(' ')}
</Link>
)}
</Box>
</Base>
)
}
import React from 'react'
import styled from 'emotion/react'
import base from '../base'
import theme from '../theme'
export default styled(base('input'))`
position: relative;
display: block;
width: 100%;
border: none;
border-radius: 0;
background: ${theme.colors.gray[0]};
font-weight: bold;
-webkit-appearance: none;
border: none;
border-bottom: 1px solid ${theme.colors.green[5]};
outline: none;
`
import React from 'react'
import { render } from 'react-dom'
import styled, { css, fontFace, keyframes, injectGlobal } from 'emotion/react'
import theme from './theme'
import base from './base'
import Input from './input'
import Card from './card'
import data from '../boulder.json'
injectGlobal`
html, body {
font-family: -apple-system,
BlinkMacSystemFont,
"Segoe UI",
"Roboto",
"Roboto Light",
"Oxygen",
"Ubuntu",
"Cantarell",
"Fira Sans",
"Droid Sans",
"Helvetica Neue",
sans-serif,
"Apple Color Emoji",
"Segoe UI Emoji",
"Segoe UI Symbol";
color: #495057;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
}
#app {
display: flex;
flex-direction: column;
flex: 1;
}
`
fontFace`
font-family: 'Oxygen';
font-style: normal;
font-weight: 400;
src: local('Oxygen Regular'), local('Oxygen-Regular'), url(https://fonts.gstatic.com/s/oxygen/v6/qBSyz106i5ud7wkBU-FrPevvDin1pK8aKteLpeZ5c0A.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
`
const PlaygroundWrapper = styled(base('div'))`
flex:1;
background: ${theme.colors.white};
& .inner {
margin: 0 auto;
width: calc(100% - 32px);
max-width: 960px;
@media (min-width: 960px) {
width: 100%;
}
}
`
const Header = styled(base('header'))`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
`
const List = styled(base('pre'))`
flex: 1;
`
class App extends React.Component {
createCard = (d, i) => {
console.log(d)
return <Card data={d} key={d.id} />
}
render () {
return (
<PlaygroundWrapper>
<div className='inner'>
<Header p={[1, 2, 3, 4]} pt={64}>
<Input
type='text'
placeholder='Search'
p={[2, 2, 4, 4]}
fontSize={[3, 3, 4, 4]}
/>
</Header>
<List p={[2, 2, 2, 2]}>
{data.map(this.createCard)}
</List>
</div>
</PlaygroundWrapper>
)
}
}
render(<App />, document.getElementById('app'))
import colors from 'open-color'
import { constants } from 'styled-system'
const { breakpoints, scale, fontSizes } = constants
export default {
bp: breakpoints,
colors,
fontSizes,
scale
}
import { css } from 'emotion/react'
import theme from './theme'
export const baseCss = css`
color: ${theme.colors.gray[8]};
font-family: 'Oxygen', sans-serif;
box-sizing: border-box;
`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment