UNPKG

reshow-build

Version:
166 lines (158 loc) 4.42 kB
// @ts-check import { OBJ_SIZE, STRING, FUNCTION, T_NULL, T_TRUE, TYPE_ERROR, T_UNDEFINED, IS_ARRAY } from "reshow-constant"; import { removeEmpty } from "array.merge"; import * as React from "react"; import { jsx as _jsx } from "react/jsx-runtime"; var { isValidElement, cloneElement, createElement, Children, Fragment } = React; /** * @typedef {React.ComponentType|React.ReactNode|Function} Component */ /** * @typedef {import('./mergeRef').RefType} RefType */ /** * @typedef {object} BuildProps */ /** * @typedef {object} ComponentOption * @property {Component} [altWrap] This will only be used when the original component is not a valid element. * @property {boolean} [doCallFunction] */ /** * @param {function} component * @param {BuildProps} props * @param {Component|Component[]} child * @param {ComponentOption} componentOption * @returns {React.ReactElement?} */ var buildFunc = function buildFunc(component, props, child, componentOption) { // anonymous function will call directly var { altWrap, doCallFunction } = componentOption || {}; if (FUNCTION === typeof component && (!component.name || "children" === component.name) || doCallFunction) { try { if (child != T_NULL) { props.children = /** @type React.ReactElement*/child; } var el = component(props); if (isValidElement(el)) { var elKey = el.key || props.key; return null != elKey ? _buildReact(el, { key: elKey }) : el; } else { return altWrap ? _buildReact(altWrap, props, el) : _buildReact(el, props); } } catch (e) { if (e.name === TYPE_ERROR) { return _buildReact(component, props, child); } else { throw e; } } } else { return _buildReact(component, props, child); } }; /** * @param {Component} component * @param {BuildProps} props * @param {Component|Component[]} child * @returns {React.ReactElement?} */ var _buildReact = function buildReact(component, props, child) { if (props === void 0) { props = {}; } if (child === void 0) { child = T_UNDEFINED; } if (T_NULL == component) { return T_NULL; } var isValidComp = isValidElement(component); if (isValidComp && !OBJ_SIZE(props) && null == child) { return component; } var params = [component, props]; if (child != T_NULL) { params.push(child); } if (!component || T_TRUE === component || STRING === typeof component && component !== /**@type string*/component.replace(/[^a-z1-6]/g, "")) { if (null != props.children) { throw new TypeError("String component should not have child"); } else { return _buildReact(/*#__PURE__*/_jsx("span", { children: (/**@type string*/component) }), props); } } else { return (isValidComp ? cloneElement : createElement).apply(T_NULL, params); } }; /** * @param {Component|Component[]} [component] * @param {ComponentOption} componentOption */ var build = function build(component, componentOption) { if (componentOption === void 0) { componentOption = {}; } return ( /** * @param {BuildProps} props * @param {Component|Component[]} child * @returns {React.ReactElement?} */ function (props, child) { if (props === void 0) { props = {}; } if (child === void 0) { child = T_UNDEFINED; } if (T_NULL == component) { return T_NULL; } var { altWrap } = componentOption || {}; if (altWrap) { if (FUNCTION !== typeof component && !isValidElement(component)) { child = component; component = altWrap; } } /** * @param {Component} comp */ var run = function run(comp) { props = removeEmpty(props, T_TRUE); return (isValidElement(comp) ? _buildReact : buildFunc)(/**@type any*/comp, props, child, componentOption); }; if (IS_ARRAY(component)) { var key = props.key; props.key = T_UNDEFINED; return /*#__PURE__*/_jsx(Fragment, { children: Children.map(component.map(function (comp) { return run(comp); }), function (c) { return c; }) }, key); } else { return run(component); } } ); }; export default build; export { mergeRef } from "./mergeRef.mjs";