@compositor/gen
Version:
Compositor JSX static site generator
118 lines (95 loc) • 2.75 kB
JavaScript
const system = require('styled-system')
const styled = require('styled-components').default
const glamorous = require('glamorous').default
const babel = require('babel-standalone')
const transformJSX = require('babel-plugin-transform-react-jsx')
const { toComponent } = require('./jsx')
const componentCreators = {
'styled-components': ({
name,
type,
style,
props,
system = [],
}, lib) => {
const tag = lib[type] || type
const funcs = getFunctions(system)
const Comp = styled(tag)([], style, ...funcs)
Comp.defaultProps = props
Comp.displayName = name
return Comp
},
glamorous: ({
name,
type,
style,
props,
system = [],
}, lib) => {
// todo: DRY up
const tag = lib[type] || type
const funcs = getFunctions(system)
const Comp = glamorous(tag)(style, ...funcs)
Comp.defaultProps = props
Comp.displayName = name
return Comp
}
}
componentCreators.default = componentCreators['styled-components']
const createScope = (imports, lib) => imports
.map(key => ({
key,
value: lib[key]
}))
.reduce((a, b) => Object.assign(a, {
[b.key]: b.value
}), {})
const createComposite = (comp, lib) => {
// todo npm/local modules scope
const scope = createScope(comp.imports, lib)
const Comp = toComponent(comp.jsx, scope)
return Comp
}
const defaultFuncs = [
'space',
'fontSize',
'width',
'color'
]
const getFunctions = funcs => [
...defaultFuncs,
...funcs
].map(key => system[key])
.filter(func => typeof func === 'function')
const isBase = ({ type }) => type && /[a-z]/.test(type)
const isExtension = ({ type }) => type && /[A-Z]/.test(type)
const isComposite = ({ type, imports, jsx }) => !type && imports && jsx
const isExternal = ({ external }) => external
const mergeComponents = create => (a, comp) =>
Object.assign(a, {
[comp.name]: create(comp, a)
}, {})
const createComponent = opts => (comp, lib) => {
if (isExternal(comp)) return null
if (isComposite(comp)) return createComposite(comp, lib)
if (!comp.name || !comp.type || !comp.style) return null
const library = opts.library || 'styled-components'
const sx = componentCreators[library] || componentCreators.default
return sx(comp, lib)
}
const createComponents = (config = [], opts = {}) => {
const base = config.filter(isBase)
const extensions = config.filter(isExtension)
const composites = config.filter(isComposite)
const externals = config.filter(isExternal)
const sorted = [
...base,
...extensions,
...composites,
...externals
]
const create = createComponent(opts)
const components = sorted.reduce(mergeComponents(create), {})
return components
}
module.exports = createComponents