UNPKG

semantic-ui-react

Version:
133 lines (110 loc) 4.99 kB
import _extends from 'babel-runtime/helpers/extends'; import _isFunction from 'lodash/isFunction'; import _isArray from 'lodash/isArray'; import _isPlainObject from 'lodash/isPlainObject'; import _isNumber from 'lodash/isNumber'; import _isString from 'lodash/isString'; import cx from 'classnames'; import React, { cloneElement, isValidElement } from 'react'; // ============================================================ // Factories // ============================================================ /** * 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|function} [defaultProps={}] Default props object or function (called with regular props). * @param {boolean} [generateKey=false] Whether or not to generate a child key, useful for collections. * @returns {object|null} */ export function createShorthand(Component, mapValueToProps, val) { var defaultProps = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; var generateKey = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; if (typeof Component !== 'function' && typeof Component !== 'string') { throw new Error('createShorthandFactory() Component must be a string or function.'); } // short circuit for disabling shorthand if (val === null) return null; var valIsString = _isString(val); var valIsNumber = _isNumber(val); var isReactElement = isValidElement(val); var isPropsObject = _isPlainObject(val); var isPrimitiveValue = valIsString || valIsNumber || _isArray(val); // ---------------------------------------- // Build up props // ---------------------------------------- // User's props var usersProps = isReactElement && val.props || isPropsObject && val || isPrimitiveValue && mapValueToProps(val); // Default props defaultProps = _isFunction(defaultProps) ? defaultProps(usersProps) : defaultProps; // Merge props /* eslint-disable react/prop-types */ var props = _extends({}, defaultProps, usersProps); // Merge className if (usersProps.className && defaultProps.className) { props.className = cx(defaultProps.className, usersProps.className); } // Merge style if (usersProps.style && defaultProps.style) { props.style = _extends({}, defaultProps.style, usersProps.style); } // ---------------------------------------- // Get key // ---------------------------------------- // Use key, childKey, or generate key if (!props.key) { var childKey = props.childKey; if (childKey) { // apply and consume the childKey props.key = typeof childKey === 'function' ? childKey(props) : childKey; delete props.childKey; } else if (generateKey && (valIsString || valIsNumber)) { // use string/number shorthand values as the key props.key = val; } } /* eslint-enable react/prop-types */ // ---------------------------------------- // Create Element // ---------------------------------------- // Clone ReactElements if (isReactElement) return cloneElement(val, props); // Create ReactElements from built up props if (isPrimitiveValue || isPropsObject) return React.createElement(Component, props); // Otherwise null return null; } // ============================================================ // Factory Creators // ============================================================ /** * Creates a `createShorthand` function that is waiting for a value and defaultProps. * * @param {function|string} Component A ReactClass or string * @param {function} mapValueToProps A function that maps a primitive value to the Component props * @param {boolean} [generateKey] Whether or not to generate a child key, useful for collections. * @returns {function} A shorthand factory function waiting for `val` and `defaultProps`. */ createShorthand.handledProps = []; export function createShorthandFactory(Component, mapValueToProps, generateKey) { if (typeof Component !== 'function' && typeof Component !== 'string') { throw new Error('createShorthandFactory() Component must be a string or function.'); } return function (val, defaultProps) { return createShorthand(Component, mapValueToProps, val, defaultProps, generateKey); }; } // ============================================================ // HTML Factories // ============================================================ export var createHTMLImage = createShorthandFactory('img', function (value) { return { src: value }; }); export var createHTMLInput = createShorthandFactory('input', function (value) { return { type: value }; }); export var createHTMLLabel = createShorthandFactory('label', function (value) { return { children: value }; });