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.