UNPKG

react-element

Version:
94 lines (74 loc) 2.55 kB
import cx from 'classnames'; import PropTypes from 'prop-types'; import { createElement, isValidElement, cloneElement, Children } from 'react'; function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } var reEvent = /^on\w+$/; var isFunction = function isFunction(f) { return typeof f === 'function'; }; // 属性后定义后覆盖(除了 class 始终拼接起来),处理函数先定义先执行 var mergeProps = function mergeProps(destProps, srcProps) { var className = cx(srcProps.className, destProps.className); var resultProps = Object.assign({}, destProps, srcProps, className && { className: className }); // keep event handlers Object.keys(destProps).forEach(function (key) { var destHandler = destProps[key]; var srcHandler = srcProps[key]; if (isFunction(destHandler) && isFunction(srcHandler) && reEvent.test(key)) { resultProps[key] = function () { destHandler.apply(this, arguments); srcHandler.apply(this, arguments); }; } }); return resultProps; }; /** * 元素替换 * * // 标签替换 * <Element component='span'>text</Element> * // 构造函数替换 * <Element component={Header}>text</Element> * // 实例替换 * <Element component={<Link to='/' />}>text</Element> */ var Element = function Element(_ref) { var component = _ref.component, children = _ref.children, ownProps = _objectWithoutPropertiesLoose(_ref, ["component", "children"]); var type = typeof component; if (type === 'string') { if (ownProps.onRef) { ownProps.ref = ownProps.onRef; delete ownProps.onRef; } return createElement(component, ownProps, children); } else if (type === 'function') { return createElement(component, ownProps, children); } else if (isValidElement(component)) { var childProps = mergeProps(component.props, ownProps); if (children) { return cloneElement(component, childProps, children); } return cloneElement(component, childProps); } return children ? Children.only(children) : null; }; Element.propTypes = { onRef: PropTypes.func, children: PropTypes.node, component: PropTypes.oneOfType([PropTypes.element, PropTypes.string, PropTypes.func]) }; export default Element;