Skip to content

Commit

Permalink
refactor(factories): create reusable shorthand factory
Browse files Browse the repository at this point in the history
  • Loading branch information
levithomason committed Sep 23, 2016
1 parent acfdd0d commit 0b01f0b
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 88 deletions.
64 changes: 64 additions & 0 deletions src/factories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import _ from 'lodash'
import cx from 'classnames'
import React, { isValidElement } from 'react'

import Icon from './elements/Icon/Icon'
import Image from './elements/Image/Image'
import Label from './elements/Label/Label'

/**
* Merges props and classNames.
*
* @param {object} props A props object
* @param {object} extraProps A props object
* @returns {object} A new props object
*/
const mergePropsAndClassName = (props, extraProps) => {
let className
if (_.has(props, 'className') || _.has(extraProps.className)) {
className = cx(props.className, extraProps.className) // eslint-disable-line react/prop-types
}
return { ...props, ...extraProps, className }
}

/**
* A more robust React.createElement.
* It can create elements from primitive values.
*
* @param {function|string} Component A ReactClass or string
* @param {function} mapValueToProps A function that maps a primitive value to the Component props
* @param {string|object|function} val The value to create a ReactElement from
* @param {object} extraProps Additional props to add to the final ReactElement
* @returns {function|null}
*/
export function createShorthand(Component, mapValueToProps, val, extraProps = {}) {
// Clone ReactElements
if (isValidElement(val)) {
return React.cloneElement(val, mergePropsAndClassName(val.props, extraProps))
}

// Create ReactElements from props objects
if (_.isPlainObject(val)) {
return <Component {...mergePropsAndClassName(val, extraProps)} />
}

// Map values to props and create a ReactElement
if (!_.isNil(val)) {
return <Component {...mergePropsAndClassName(mapValueToProps(val), extraProps)} />
}

// React requires ReactElements or null be returned
return null
}

function createShorthandFactory(Component, mapValueToProps) {
return _.partial(createShorthand, Component, mapValueToProps)
}

// ----------------------------------------
// Factories
// ----------------------------------------
export const createIcon = createShorthandFactory(Icon, value => ({ name: value }))
export const createImage = createShorthandFactory(Image, value => ({ src: value }))
export const createImg = createShorthandFactory('img', value => ({ src: value }))
export const createLabel = createShorthandFactory(Label, value => ({ content: value }))
47 changes: 0 additions & 47 deletions src/factories/createFactory.js

This file was deleted.

41 changes: 0 additions & 41 deletions src/factories/index.js

This file was deleted.

0 comments on commit 0b01f0b

Please sign in to comment.