import React, { forwardRef, Ref, ReactNode } from "react"; import { StyledProps } from "../_type"; import { useConfig } from "./config-context"; export interface RocketProps extends StyledProps { /** * 组件内容 */ children?: ReactNode; } /** * 快速创建 DOM 容器组件 * @param displayName 组件名称 * @param paths 组件的容器路径,如 div.tea-card__body * * tea 类名前缀请使用 `@{prefix}` 代替 */ export const createRocket =

( displayName: string, ...paths: string[] ) => { const parentOf = (classPrefix: string) => ( children: React.ReactNode, path: string ) => { const [tag, ...classNames] = path.split("."); return React.createElement( tag, { className: classNames .map(c => c.replace(/^(@{prefix}-)/, `${classPrefix}-`)) .join(" "), }, children ); }; const Rocket = forwardRef((props: P, ref: Ref) => { const { children, className, ...restProps } = props; const { classPrefix } = useConfig(); const element = paths.reduceRight( parentOf(classPrefix), children as any ); if (className) { const { props: elementProps } = element; return React.cloneElement(element, { ref, className: [elementProps.className, className] .filter(Boolean) .join(" "), ...restProps, }); } return React.cloneElement(element, { ref, ...restProps, }); }); Rocket.displayName = displayName; return Rocket; };