Supachai's post in Grid item view in React.js was marked as the answer
@Rodrigo Thanks for the references. I found the reparenting example might be the one I can follow. And now this is my version of reparenting.
'use client';
import { useEffect, useRef } from 'react';
import { Flip, gsap } from '@/lib/gsap';
import { useGSAP } from '@gsap/react';
const keys = [
'2b332ab5-f515-4155-b018-c4508e56dbfa',
'59e8855a-7bfe-4b8a-aa78-a0b7ec01da0a',
'bafec336-11fc-49f3-9b01-b5650b34ec18',
];
export default function Page() {
const containerRef = useRef<HTMLDivElement>(null!);
const childRef = useRef<HTMLDivElement>(null!);
const { contextSafe } = useGSAP({ scope: containerRef.current });
useEffect(() => {
const parents = gsap.utils.toArray<HTMLDivElement>('.parent');
const parent = parents[0];
if (!parent) return;
parent.appendChild(childRef.current);
}, []);
const handleClicked = contextSafe((k: string) => {
const state = Flip.getState(childRef.current);
const parents = gsap.utils.toArray<HTMLDivElement>('.parent');
const parent = parents.find((p) => p.dataset.key === k);
if (!parent) return;
parent.appendChild(childRef.current);
Flip.from(state, {
duration: 1,
targets: [childRef.current],
ease: 'power3.inOut',
absolute: true,
});
});
return (
<div
ref={containerRef}
className="flex flex-row items-center justify-center w-full h-full gap-3"
>
{/* Parents inside the group */}
<div className="flex flex-col items-center justify-center w-full h-full gap-5">
{keys.map((k, i) => (
<div
key={k}
data-key={k}
onClick={() => handleClicked(k)}
className="parent relative flex flex-col items-center justify-center w-52 h-36 border-2 border-white rounded-xl"
>
{/* <div className="guide invisible">Guide-{i}</div> */}
</div>
))}
</div>
{/* Parent outside the group */}
<div
data-key="parent-outside-the-group"
onClick={() => handleClicked('parent-outside-the-group')}
className="parent relative w-1/2 h-96 border-2 border-white rounded-xl"
></div>
{/* Child */}
<div
ref={childRef}
className="absolute top-0 right-0 w-full h-full bg-blue-500/50 rounded-xl"
/>
</div>
);
}