All files / util component-types.js

92.86% Statements 26/28
81.25% Branches 26/32
100% Functions 13/13
92.86% Lines 26/28
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97                          30x   22101x   22101x                   9362x       22101x   22101x         2512x   2512x   5164x           69x   69x   157x           2008x 119x 1x 118x 12x 106x     106x               1974x 2007x 2007x 2007x           1974x         928x           2944x    
import React from 'react';
import _ from 'lodash';
 
// creates a React component
export function createClass(definition={}) {
	const {
		_isPrivate = false,
		statics = {},
		components = {},
		reducers = {},
		selectors = {},
		propName = null,
		propTypes = {},
		render = () => null,
		...restDefinition,
	} = definition;
 
	const newDefinition = {
		...restDefinition,
		statics: {
			...statics,
			...components,
			_isPrivate,
			reducers,
			selectors,
			propName,
		},
		propTypes: _.assign({}, propTypes, _.mapValues(definition.components, () => React.PropTypes.any)),
		render,
	};
 
	newDefinition.statics.definition = newDefinition;
 
	return React.createClass(newDefinition);
}
 
// return all elements matching the specified types
export function filterTypes(children, types=[]) {
	types = [].concat(types); // coerce to Array
 
	return _.filter(
		React.Children.toArray(children),
		(element) => (React.isValidElement(element) && _.includes(types, element.type))
	);
}
 
// return all elements not matching the specified types
export function rejectTypes(children, types=[]) {
	types = [].concat(types); // coerce to Array
 
	return _.reject(
		React.Children.toArray(children),
		(element) => (React.isValidElement(element) && _.includes(types, element.type))
	);
}
 
// return an array of elements (of the given type) for each of the values
export function createElements(type, values=[]) {
	return _.reduce([].concat(values), (elements, typeValue) => {
		if (React.isValidElement(typeValue) && typeValue.type === type) {
			return elements.concat(typeValue);
		} else if (_.isPlainObject(typeValue) && !React.isValidElement(typeValue)) {
			return elements.concat(React.createElement(type, typeValue));
		} else Iif (_.isUndefined(typeValue)) {
			return elements;
		} else {
			return elements.concat(React.createElement(type, null, typeValue));
		}
	}, []);
}
 
// return all elements found in props and children of the specified types
export function findTypes(props, types=[]) {
	// get elements from props (using type.propName)
	const elementsFromProps = _.reduce(_.castArray(types), (acc, type) => {
		Eif (!_.isUndefined(type.propName)) {
			const propMatches = _.flatten(_.values(_.pick(props, type.propName)));
			return acc.concat(createElements(type, propMatches));
		}
		return acc;
	}, []);
 
	// return elements from props and elements from children
	return elementsFromProps.concat(filterTypes(props.children, types));
}
 
// return the first element found in props and children of the specificed type(s)
export function getFirst(props, types, defaultValue) {
	return _.first(findTypes(props, types)) || defaultValue;
}
 
// omit props defined in propTypes of the given type
// and any extra keys given in third argument
export function omitProps(props, type, keys = []) {
	return _.omit(props, _.keys(type.propTypes).concat(keys).concat(['initialState']));
}