Make this typesafe pls

const FeaturesMobile: React.FC = () => {
let [activeIndex, setActiveIndex] = useState(0);
let slideContainerRef = useRef<any>(null);
let slideRefs = useRef<any>([]);

useEffect(() => {
if (!slideContainerRef.current) {
return;
}

let observer = new window.IntersectionObserver(
(entries: IntersectionObserverEntry[]) => {
let activeSlide = entries.find((entry) => entry.isIntersecting);
if (activeSlide) {
setActiveIndex(
slideRefs.current.indexOf(activeSlide.target as HTMLInputElement)
);
}
},
{
root: slideContainerRef.current,
threshold: 0.6,
}
);

for (let slide of slideRefs.current) {
if (slide) {
observer.observe(slide);
}
}

return () => {
observer.disconnect();
};
}, [slideContainerRef, slideRefs]);

return (
<>
<div
ref={slideContainerRef}
className="-mb-4 flex snap-x snap-mandatory -space-x-4 overflow-x-auto overscroll-x-contain scroll-smooth pb-4 [scrollbar-width:none] sm:-space-x-6 [&::-webkit-scrollbar]:hidden"
>
{features.map((feature, featureIndex) => (
<div
key={featureIndex}
ref={(ref) => (slideRefs.current[featureIndex] = ref)}
className="w-full flex-none snap-center px-4 sm:px-6"
>
<div className="relative transform overflow-hidden rounded-2xl bg-neutral-800 px-5 py-6">
<div className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2">
<CircleBackground
color="#13B5C8"
className={featureIndex % 2 === 1 ? "rotate-180" : undefined}
/>
</div>
<PhoneFrame className="relative mx-auto w-full max-w-[366px]">
<feature.screen />
</PhoneFrame>
<div className="absolute inset-x-0 bottom-0 bg-neutral-800/95 p-6 backdrop-blur sm:p-10">
<feature.icon className="h-8 w-8" />
<h3 className="mt-6 text-sm font-semibold text-neutral-50 sm:text-lg">
{feature.name}
</h3>
<p className="mt-2 text-sm text-neutral-400">
{feature.description}
</p>
</div>
</div>
</div>
))}
</div>
<div className="mt-6 flex justify-center gap-3">
{features.map((_, featureIndex) => (
<button
type="button"
key={featureIndex}
className={clsx(
"relative h-0.5 w-4 rounded-full",
featureIndex === activeIndex ? "bg-neutral-300" : "bg-neutral-500"
)}
aria-label={`Go to slide ${featureIndex + 1}`}
onClick={() => {
slideRefs.current[featureIndex].scrollIntoView({
block: "nearest",
inline: "nearest",
});
}}
>
<span className="absolute -inset-x-1.5 -inset-y-3" />
</button>
))}
</div>
</>
);
};
const FeaturesMobile: React.FC = () => {
let [activeIndex, setActiveIndex] = useState(0);
let slideContainerRef = useRef<any>(null);
let slideRefs = useRef<any>([]);

useEffect(() => {
if (!slideContainerRef.current) {
return;
}

let observer = new window.IntersectionObserver(
(entries: IntersectionObserverEntry[]) => {
let activeSlide = entries.find((entry) => entry.isIntersecting);
if (activeSlide) {
setActiveIndex(
slideRefs.current.indexOf(activeSlide.target as HTMLInputElement)
);
}
},
{
root: slideContainerRef.current,
threshold: 0.6,
}
);

for (let slide of slideRefs.current) {
if (slide) {
observer.observe(slide);
}
}

return () => {
observer.disconnect();
};
}, [slideContainerRef, slideRefs]);

return (
<>
<div
ref={slideContainerRef}
className="-mb-4 flex snap-x snap-mandatory -space-x-4 overflow-x-auto overscroll-x-contain scroll-smooth pb-4 [scrollbar-width:none] sm:-space-x-6 [&::-webkit-scrollbar]:hidden"
>
{features.map((feature, featureIndex) => (
<div
key={featureIndex}
ref={(ref) => (slideRefs.current[featureIndex] = ref)}
className="w-full flex-none snap-center px-4 sm:px-6"
>
<div className="relative transform overflow-hidden rounded-2xl bg-neutral-800 px-5 py-6">
<div className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2">
<CircleBackground
color="#13B5C8"
className={featureIndex % 2 === 1 ? "rotate-180" : undefined}
/>
</div>
<PhoneFrame className="relative mx-auto w-full max-w-[366px]">
<feature.screen />
</PhoneFrame>
<div className="absolute inset-x-0 bottom-0 bg-neutral-800/95 p-6 backdrop-blur sm:p-10">
<feature.icon className="h-8 w-8" />
<h3 className="mt-6 text-sm font-semibold text-neutral-50 sm:text-lg">
{feature.name}
</h3>
<p className="mt-2 text-sm text-neutral-400">
{feature.description}
</p>
</div>
</div>
</div>
))}
</div>
<div className="mt-6 flex justify-center gap-3">
{features.map((_, featureIndex) => (
<button
type="button"
key={featureIndex}
className={clsx(
"relative h-0.5 w-4 rounded-full",
featureIndex === activeIndex ? "bg-neutral-300" : "bg-neutral-500"
)}
aria-label={`Go to slide ${featureIndex + 1}`}
onClick={() => {
slideRefs.current[featureIndex].scrollIntoView({
block: "nearest",
inline: "nearest",
});
}}
>
<span className="absolute -inset-x-1.5 -inset-y-3" />
</button>
))}
</div>
</>
);
};
4 Replies
mac
macOP2y ago
line 3 and 4 btw
jdsl
jdsl2y ago
I'll take a shot
let slideContainerRef = useRef<HTMLDivElement | null>(null);
let slideRefs = useRef<HTMLDivElement[]>([]);
let slideContainerRef = useRef<HTMLDivElement | null>(null);
let slideRefs = useRef<HTMLDivElement[]>([]);
then for line 80
ref={(ref) => (slideRefs.current[featureIndex] = ref as HTMLDivElement)}
ref={(ref) => (slideRefs.current[featureIndex] = ref as HTMLDivElement)}
mac
macOP2y ago
Already tried that - it wants to make it an ‘unknown’ type
jdsl
jdsl2y ago
Which line are you seeing the unknown type?
Want results from more Discord servers?
Add your server