Hello,
I want to create a tab bar similar to this sandbox example.
I have two components: the <Tabs/>
and another one which is actually a <SliceZone />
. When scrolling through the text section, the corresponding tab should be marked as active. Conversely, when a tab is clicked, the text section should scroll into the viewport.
To achieve this, I am using useRef()
to get references to the <section>
elements inside SliceZone
, so I can determine if a section
element is visible in the viewport.
I created a common parent component for the two parts (Tabs and Texts).
Parent comp:
'use client';
import ....
type ParentProps={
...
}
export default function Parent (){
const sectionRefs = useRef<(HTMLElement | null)[]>([]);
function handleClick(index: number) {
/* ...when click at the tab, corresponding text will be displayed,
then `setActiveIndex(index)`
*/
}
useEffect(()=>{
...
// call IntersectionObserver()
// if the section is detected as visible, then setActiveIndex() to the index of entry
},[])
return <>
<Tabs handleClick={...} activeIndex={...} />
/*Texts*/
<SliceZone slices={...}
components={...}
context={{sectionRefs:sectionRefs}} />
</>
}
export type PageProps = SliceComponentProps<Content.CvSlice>;
export type AllProps = CvProps & {
context:{sectionRefs: MutableRefObject<(HTMLElement | null)[]>}
}
const Page = (({ slice, context, index }:AllProps):JSX.Element =>{
return (<section
...
ref={(el: HTMLElement | null) =>
(context.sectionRefs.current[index] = el)}
>
{slice.variation==="text1" &&
<article>
...
</article>
}
{slice.variation==="text2"
<article >
...
</article>
}
{slice.variation==="text3"&&
<article>
...
</article>
}
</section>
);
});
export default Page;
Could someone provide some guidance on how to resolve this issue?
Thank you!
-----edit ------
I got the ref inside <SliceZone />
by passing context={ref}
and created a callback function inside <SliceZone />
. The code has been corrected in this version.