Repository URL to install this package:
|
Version:
1.2.19 ▾
|
import React from 'react'
import PropTypes from 'prop-types'
import { fromArgumentsToArray } from 'chain-able-boost'
import { isPureObj } from 'exotic'
// import { hoistNonReactStatics } from 'src/bootstrapper/connectData/deps'
import hoistNonReactStatics from 'hoist-non-react-statics'
import { toComponentName } from '../identifier'
import { exoticPropTypes } from './propTypesTypes/'
import { renderSchemaMethod } from './deps'
// https://github.com/acdlite/recompose/blob/master/src/packages/recompose/branch.js
// https://github.com/acdlite/recompose/blob/master/src/packages/recompose/renameProps.js
// https://github.com/acdlite/recompose/blob/master/src/packages/recompose/toClass.js
// could check if we already have the instance,
// or could decorate any instances with static properties...
// const ViewRegistry = new WeakMap()
function withWrapper(elementToWrapWith) {
return function(Target) {
class Wrapped extends Target {
render() {
// or super.render
return React.createElement(
elementToWrapWith,
Target.prototype.render.call(this, this)
)
}
}
hoistNonReactStatics(Wrapped)
return Wrapped
}
}
/**
* if arg = class, extend it
* if arg = obj, use to build class
* if obj.keys.length = 1, take key as tagName
*
* @param {Class | Object} [options]
*/
function View(options = undefined) {
if (arguments.length === 0) {
return View
} else if (isPureObj(options)) {
return viewFrom(options)
} else if (options !== undefined && options.isBuilder === true) {
return View.bind(options, options)
} else {
// handleView(options)
return View
}
}
// View.lazyLoad = function() {
// throw new Error('@TODO')
// }
// View.withName = function(name) {}
// View.withCustomizable = withCustomizable
// View.withStyles = withStyles
// View.connectToData = function() {
// throw new Error('@TODO when michael has factory')
// }
// should be the last thing called
View.react = setPrototypeOfReact
// alias
// View.classNames = View.class = View.className = View.withClassName = withClassName
View.tagName = View.withTag
View.tag = View.withTag
View.displayName = View.withName
View.named = View.displayName
View.from = viewFrom
function setPrototypeOfReact(OptionalTarget = undefined) {
let Parent = React.PureComponent
function decorator(Target) {
return Object.setPrototypeOf(Target, Parent)
}
if (arguments.length === 1) {
if (OptionalTarget === React.PureComponent) {
Parent = OptionalTarget
} else if (OptionalTarget === React.Component) {
Parent = React.Component
}
return decorator(OptionalTarget)
// else if (OptionalTarget.prototype)
} else {
return decorator
}
}
// @TODO recompose prob does better already, but if more perf
// function addToContext() {
// return class {
// // now we can pick up, expose, and change any of the things we want customizable
// // and provide it transparently
// getChildContext() {
// return customizable
// }
// }
// }
function createElementWithBoundTagName(displayName, tagName, attributes) {
// let factory = React.createFactory(tagName)
// factory = factory.bind(factory, props)
return function(runtimeProps = {}) {
console.log('rendering...')
// return React.createElement(tagName, attributes)
// return <tagName {...attributes} />
return React.createElement(tagName, { ...attributes, ...runtimeProps })
}
// let factory = React.createElement.bind(
// React.createElement,
// tagName,
// attributes
// )
// factory.displayName = displayName
// return factory
}
function renderStylesMethod(styles) {
// transpile
return React.createElement('style', styles)
}
function decorateTarget(Data, Target) {
// console.dir({ Data, Target })
const { schema, wrapper, styles } = Data
let tag = Data.tag || Data.tagName
let className =
Data.className || Data.class || Data.classNames || Data.classes
const displayName = toComponentName(Target)
const render = Target.prototype ? Target.prototype.render : undefined
if (render === undefined) {
const element = createElementWithBoundTagName(displayName, tag, {
className,
schema,
})
// if (styles !== undefined) {
// return [renderStylesMethod.bind(null, styles), element]
// }
return element
// if (wrapper !== undefined) {
// return React.createElement.bind(React.createElement, wrapper, element)
// }
}
// .types
exoticPropTypes(Target)
// Target.prototype.renderSchema = renderSchemaMethod
Target.prototype.renderStyles = renderStylesMethod.bind(this, styles)
Target.prototype.render = function() {
let rendered = render.apply(this, arguments)
// or React.isValidElement(wrapper)
if (wrapper !== undefined) {
rendered = React.createElement(wrapper, rendered)
}
if (styles !== undefined) {
const siblings = [rendered]
// @TODO like autoWrap setting...
// if (schema !== undefined) {
// siblings.unshift(renderSchemaMethod.call(this))
// }
siblings.unshift(this.renderStylesMethod())
return siblings
}
return rendered
}
return Target
}
function viewFromKeys(objConfig, Target) {
let TargetAsReducedComposed = Target
Object.keys(objConfig).forEach(key => {
const arg = objConfig[key]
const staticMethod = View[key]
TargetAsReducedComposed = staticMethod(arg)
})
return TargetAsReducedComposed
}
// what is in structured-ui, lift up .types & such
// like any chain .from, calls all methods and allows obj config
function viewFrom(options = false) {
// if (arguments.length !== 1) {
// throw new Error('not supported yet, feel free to add')
// }
function decoratorFrom(Target) {
if (isPureObj(options)) {
return decorateTarget(options, Target)
} else {
return decorateTarget(Target, Target)
}
}
// if we have no options
if (options === false) {
return decoratorFrom
} else if (arguments.length === 1 && isPureObj(options)) {
if (options.name !== undefined) {
return decoratorFrom(options, options)
}
return decoratorFrom
} else {
return decoratorFrom(options)
}
}
// div, div
// function createElementFromParentChildClassNames() {}
function tagd(tagName) {
return function(Target) {
Target.tag = tagName
return Target
}
}
function classNamed(className) {
return function(Target) {
Target.className = className
return Target
}
}
export {
withWrapper,
viewFrom,
setPrototypeOfReact,
View,
View as view,
View as withView,
createElementWithBoundTagName,
classNamed as className,
tagd as tag,
}