Reputation: 97
I have part of the following component:
export const Carousel = ({ children }: ICarousel) => {
// ... code omitted for brevity
const [childWidth, setChildWidth] = useState(0);
const childRef = useRef<HTMLDivElement | null>(null);
useEffect(() => {
if (childRef.current) {
setChildWidth(childRef.current.getBoundingClientRect().width);
}
}, [children]);
return (
<div
className="flex transition-transform duration-500 ease-in-out"
style={{ transform: `translateX(-${currentIndex * 100}%)` }}
>
{React.Children.map(children, (child, index) => (
<div
key={index}
ref={index === 0 ? childRef : null} // assign ref only to first child
className="flex w-full flex-shrink-0 justify-center"
aria-hidden={index !== currentIndex}
style={{ width: `${childWidth}px` }}
>
{child}
</div>
))}
</div>
);
};
Currently I am getting the width of the containing <div>
that wraps the {child}
elements, however I want to get the width of the first item passed into {child}
.
Is this possible? If so, help would appreciated, thanks!
Upvotes: 0
Views: 27
Reputation: 228
Instead of assigning the ref to the outer wrapper , you should assign it to the actual first child inside your JSX.
import React, { useState, useEffect, useRef } from "react";
export const Carousel = ({ children }: ICarousel) => {
const [childWidth, setChildWidth] = useState(0);
const childRef = useRef<HTMLDivElement | null>(null);
useEffect(() => {
if (childRef.current) {
setChildWidth(childRef.current.getBoundingClientRect().width);
}
}, [children]);
return (
<div
className="flex transition-transform duration-500 ease-in-out"
style={{ transform: `translateX(-${currentIndex * 100}%)` }}
>
{React.Children.map(children, (child, index) => {
const isFirstChild = index === 0;
return (
<div
key={index}
className="flex w-full flex-shrink-0 justify-center"
aria-hidden={index !== currentIndex}
style={{ width: `${childWidth}px` }}
>
{React.cloneElement(child as React.ReactElement, {
ref: isFirstChild ? childRef : null,
})}
</div>
);
})}
</div>
);
};
Upvotes: 0