import type { ReactElement } from 'react' ; import type { Fiber } from 'react-reconciler' ; import React , { useEffect , useRef } from 'react' ; import { Parent } from './Parent' ; import { ParentFiber } from './parentFiber' ; import { invariant } from '../invariant' ; import { warning } from '../warning' ; /**
 * Create a reparentable Space. Only <Reparentables>s belonging to the same
 * Space can send children to each other.
 */ export function createReparentableSpace ( ) { /** Reparentable map. */ const ReparentableMap = new Map < string , ParentFiber > ( ) ; param fromParentId param toParentId param childSelector param position param skipUpdate returns function sendReparentableChild ( fromParentId , toParentId , childSelector , position , skipUpdate ? ) { const fromParent = ReparentableMap . get ( fromParentId ) ; const toParent = ReparentableMap . get ( toParentId ) ; if ( __DEV__ ) { if ( fromParent === undefined ) { warning ( `Cannot find a <Reparentable> with the id: '${ fromParentId }'.` ) ; } if ( toParent === undefined ) { warning ( `Cannot find a <Reparentable> with the id: '${ toParentId }'.` ) ; } } if ( fromParent === undefined || toParent === undefined ) { return - 1 ; } return fromParent . sendChild ( toParent , childSelector , position , skipUpdate ) ; } /**
     * This component generate internally a ParentFiber instance
     * and allow to access it through a global provided map.
     * This component must be the parent of the children to reparent
     * (it is possible to get around this by providing a findFiber method).
     */ function Reparentable ( { id , children , findFiber } ) { const parentRef = useRef < ParentFiber > ( null ) ; useEffect ( ( ) => { invariant ( typeof id === 'string' , 'You must provide an id to the <Reparentable> component.' ) ; if ( __DEV__ ) { if ( ReparentableMap . has ( id ) ) { warning ( `It seems that a new <Reparentable> has been mounted with the id: '${ id }', ` + `while there is another <Reparentable> with that id.` ) ; } } invariant ( parentRef . current !== null ) ; ReparentableMap . set ( id , parentRef . current ) ; return ( ) => { ReparentableMap . delete ( id ) ; } ; } , [ ] ) ; return ( < Parent parentRef = { parentRef } findFiber = { findFiber } > { children } < /Parent>); } return { Reparentable , sendReparentableChild , ReparentableMap } ; } export interface ReparentableProps { /** The reparentable id. */ id : string ; /** The children. */ children : ReactElement [ ] | ReactElement | null ; /** Find fiber. */ findFiber ? : ( fiber : Fiber ) => Fiber ; } export interface ReparentableSpace { ReparentableMap : Map < string , ParentFiber > ; Reparentable : ( { id , children , findFiber } : ReparentableProps ) => JSX . Element ; sendReparentableChild : ( fromParentId : string , toParentId : string , childSelector : string | number , position : string | number , skipUpdate ? : boolean | undefined ) => number ; }