Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
kettanaito committed Jan 7, 2019
1 parent cc4b847 commit b5ecc96
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 199 deletions.
3 changes: 3 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
"es6": true,
"jest": true
},
"globals": {
"__PROD__": true
},
"rules": {
"no-undef": "error",
"no-unused-vars": [
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.0.1",
"babel-loader": "7.1.5",
"babel-minify-webpack-plugin": "^0.3.1",
"babel-plugin-transform-export-extensions": "^6.22.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-env": "^1.7.0",
Expand Down
1 change: 0 additions & 1 deletion src/components/Composition.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from 'react'
import styled from 'styled-components'
import parseTemplates from '../utils/templates/parseTemplates'
import applyStyles from '../utils/styles/applyStyles'
Expand Down
32 changes: 31 additions & 1 deletion src/utils/templates/generateComponents/generateComponents.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const createAreaComponent = (areaName: string): TAreaComponent => styled(Box)`
* in the given template definitions.
*/
export default function generateComponents({ areas, templates }: AreasList) {
return areas.reduce((components, areaName) => {
const componentsMap = areas.reduce((components, areaName) => {
const areaParams = getAreaBreakpoints(areaName, templates)
const shouldAlwaysRender =
areaParams.length === 1 &&
Expand All @@ -75,4 +75,34 @@ export default function generateComponents({ areas, templates }: AreasList) {
[capitalizedAreaName]: WrappedComponent,
}
}, {})

return new Proxy(componentsMap, {
get(components, areaName) {
if (areaName in components || typeof areaName === 'symbol') {
return components[areaName]
}

if (!__PROD__) {
console.warn(
'Prevented the render of area "%s", which is not found in the template definition. Please render one of the existing areas ("%s"), or modify the template to include "%s".',
areaName,
areas
/* Filter out "." placeholder from the list of areas */
.filter((singleAreaName) => /\w+/.test(singleAreaName))
/* Sort areas alphabetically for easier eye navigation */
.sort()
/* Capitalize areas to correspond to area components */
.map(capitalize)
.join('", "'),
areaName.toLowerCase(),
)
}

/**
* Replace non-existing area component reference with
* the dummy functional component that renders nothing.
*/
return () => null
},
})
}
97 changes: 72 additions & 25 deletions stories/PeriodExample.jsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,93 @@
import React from 'react'
import { Composition } from '../'

const template = `
header header header
main main main
. . .
secondary secondary secondary
footer footer footer
const templateBox = `
thumbnail
heading
channelName
meta
`

const nextTemplate = `
header footer
main secondary
const templateRow = `
thumbnail heading heading
thumbnail channelName meta
thumbnail description description
`

const Video = ({ isBox, title, channelName, views, description }) => (
<Composition
template={isBox ? templateBox : templateRow}
templateCols={!isBox && '200px auto 1fr'}
templateRows={!isBox && 'auto auto 1fr'}
gutter={10}
>
{({ Thumbnail, Heading, ChannelName, Meta, Description }) => (
<React.Fragment>
<Thumbnail>
<img src="https://satyr.io/300x225" style={{ maxWidth: '100%' }} />
</Thumbnail>
<Heading>
<h3 style={{ margin: 0 }}>{title}</h3>
</Heading>
<ChannelName as="span">{channelName}</ChannelName>
<Meta as="span">{views}</Meta>
<Description as="span">{description}</Description>
</React.Fragment>
)}
</Composition>
)

export default class PeriodExample extends React.Component {
constructor() {
super()
this.state = {
template,
hasDefaultTemplate: true,
}
}

render() {
const { template } = this.state
const { hasDefaultTemplate } = this.state

return (
<React.Fragment>
<Composition template={template}>
{({ Header, Main, Secondary, Footer }) => (
<React.Fragment>
<Header>Header</Header>
<Main>Main</Main>
<p>something</p>
<Secondary>Secondary</Secondary>
<Footer>Footer</Footer>
</React.Fragment>
)}
</Composition>
<button
onClick={() =>
this.setState(({ hasDefaultTemplate }) => ({
hasDefaultTemplate: !hasDefaultTemplate,
}))
}
>
Toggle layout
</button>
<br />
<br />

<span onClick={() => this.setState({ template: nextTemplate })}>
Change template
</span>
<Composition
templateCols={hasDefaultTemplate && 'repeat(auto-fit, 250px)'}
gutter={10}
>
<Video
isBox={hasDefaultTemplate}
title="React for beginners"
channelName="Udemy"
views="851 views"
description="Lorem ipsum dolor sit amet"
/>
<Video
isBox={hasDefaultTemplate}
title="React for beginners"
channelName="Udemy"
views="851 views"
description="Lorem ipsum dolor sit amet"
/>
<Video
isBox={hasDefaultTemplate}
title="React for beginners"
channelName="Udemy"
views="851 views"
description="Lorem ipsum dolor sit amet"
/>
</Composition>
</React.Fragment>
)
}
Expand Down
3 changes: 2 additions & 1 deletion stories/Playground/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default class Playground extends React.Component {
templateSmUp={templateTablet}
gutter={1}
>
{({ Header, Content, Footer }) => (
{({ Header, Content, Footer, Abc }) => (
<React.Fragment>
<Header>
<Square />
Expand All @@ -42,6 +42,7 @@ export default class Playground extends React.Component {
<Footer>
<Square />
</Footer>
<Abc>Hey!</Abc>
</React.Fragment>
)}
</Composition>
Expand Down
12 changes: 11 additions & 1 deletion webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
const path = require('path')
const webpack = require('webpack')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
.BundleAnalyzerPlugin

const nodeEnv = process.env.NODE_ENV || 'production'
const PRODUCTION = nodeEnv === 'production'

module.exports = {
mode: nodeEnv,
Expand All @@ -15,7 +20,7 @@ module.exports = {
libraryTarget: 'umd',
umdNamedDefine: true,
/**
* UMD modules refer to "window", which breaks SSR.
* @quickfix UMD modules refer to "window", which breaks SSR.
* @see https://github.com/webpack/webpack/issues/6522
*/
globalObject: `typeof self !== 'undefined' ? self : this`,
Expand All @@ -30,6 +35,11 @@ module.exports = {
},
],
},
plugins: [
new webpack.DefinePlugin({
__PROD__: JSON.stringify(PRODUCTION ? 'true' : ''),
}),
],
optimization: {
minimize: false,
},
Expand Down

0 comments on commit b5ecc96

Please sign in to comment.