11import React from 'react'
22import { ReactNode , ReactElement } from 'react'
3+ import hoistNonReactStatic from 'hoist-non-react-statics'
4+ import getDisplayName from 'react-display-name'
35
46const { values, keys, assign } = Object
57
@@ -25,14 +27,14 @@ const isFn = (val: any): boolean => Boolean(val) && typeof val === 'function'
2527const isValidRenderProp = ( prop : ReactNode | ChildrenFn < any > ) : boolean =>
2628 React . isValidElement ( prop ) || isFn ( prop )
2729
28- export declare type RPC < RP , P = { } > = React . SFC <
30+ export declare type RPC < RP , P = { } > = React . ComponentType <
2931 P & {
3032 children ?: ChildrenFn < RP >
3133 render ?: ChildrenFn < RP >
3234 }
3335>
3436
35- export declare type MapperComponent < RP , P > = React . SFC <
37+ export declare type MapperComponent < RP , P > = React . ComponentType <
3638 RP &
3739 P & {
3840 render ?: ChildrenFn < any >
@@ -63,40 +65,53 @@ export function adopt<RP = any, P = any>(
6365 ? render ( rest )
6466 : children && isFn ( children ) && children ( rest )
6567
66- const reducer = ( Component : RPC < RP > , key : string , idx : number ) : RPC < RP > => ( {
67- render : pRender ,
68- children,
69- ...rest
70- } ) => (
71- < Component { ...rest } >
72- { props => {
73- const element = prop ( key , mapper )
74- const propsWithoutRest = omit < RP > ( keys ( rest ) , props )
75- const isLast = idx === mapperKeys . length - 1
76- const render = pRender && isFn ( pRender ) ? pRender : children
77-
78- const renderFn : ChildrenFn < RP > = cProps => {
79- const renderProps = assign ( { } , propsWithoutRest , {
80- [ key ] : cProps ,
81- } )
82-
83- const propsToPass =
84- mapProps && isFn ( mapProps ) && isLast
85- ? mapProps ( renderProps )
86- : renderProps
87-
88- return render && isFn ( render ) ? render ( propsToPass ) : null
89- }
90-
91- return isFn ( element )
92- ? React . createElement (
93- element ,
94- assign ( { } , rest , props , { render : renderFn } )
95- )
96- : React . cloneElement ( element , { } , renderFn )
97- } }
98- </ Component >
99- )
68+ Children . displayName = 'Adopt'
69+
70+ const reducer = ( Component : RPC < RP > , key : string , idx : number ) : RPC < RP > => {
71+ const element = prop ( key , mapper )
72+ const displayName = getDisplayName ( Component )
73+ const nextDisplayName = getDisplayName ( element )
74+ const isLast = idx === mapperKeys . length - 1
75+
76+ const NewComponent : RPC < RP > = ( {
77+ render : pRender ,
78+ children,
79+ ...rest
80+ } : any ) => (
81+ < Component { ...rest } >
82+ { props => {
83+ const propsWithoutRest = omit < RP > ( keys ( rest ) , props )
84+ const render = pRender && isFn ( pRender ) ? pRender : children
85+
86+ const renderFn : ChildrenFn < RP > = cProps => {
87+ const renderProps = assign ( { } , propsWithoutRest , {
88+ [ key ] : cProps ,
89+ } )
90+
91+ const propsToPass =
92+ mapProps && isFn ( mapProps ) && isLast
93+ ? mapProps ( renderProps )
94+ : renderProps
95+
96+ return render && isFn ( render ) ? render ( propsToPass ) : null
97+ }
98+
99+ return isFn ( element )
100+ ? React . createElement (
101+ element ,
102+ assign ( { } , rest , props , { render : renderFn } )
103+ )
104+ : React . cloneElement ( element , { } , renderFn )
105+ } }
106+ </ Component >
107+ )
108+
109+ NewComponent . displayName = `${ displayName } (${ nextDisplayName } )`
110+
111+ return isFn ( element )
112+ ? hoistNonReactStatic ( NewComponent , element )
113+ : NewComponent
114+ }
100115
101116 return mapperKeys . reduce ( reducer , Children )
102117}
0 commit comments