yintai-company-home/src/components/layout/BottomTabsSection/BottomTabs.tsx

66 lines
2.3 KiB
TypeScript

import { useLayoutEffect, useRef, useState } from "react";
import styles from "./index.module.css";
type TabItems = {
tabName: string;
[key: string]: any;
}[]
export default function BottomTabs({ tabItems, activeIndex, setActiveIndex }: { tabItems: TabItems, activeIndex: number, setActiveIndex: (index: number) => void }) {
const tabsRef = useRef<HTMLDivElement>(null);
const tabItemRefs = useRef<(HTMLDivElement | null)[]>([]);
const [tabIndicator, setTabIndicator] = useState({ x: 0, width: 0 });
useLayoutEffect(() => {
if (!tabItems?.length) return;
const root = tabsRef.current;
if (!root) return;
const updateIndicator = () => {
const tab = tabItemRefs.current[activeIndex];
if (!tab) return;
const rootRect = root.getBoundingClientRect();
const tabRect = tab.getBoundingClientRect();
setTabIndicator({
x: tabRect.left - rootRect.left,
width: tabRect.width,
});
};
updateIndicator();
const ro = new ResizeObserver(updateIndicator);
ro.observe(root);
window.addEventListener("resize", updateIndicator);
return () => {
ro.disconnect();
window.removeEventListener("resize", updateIndicator);
};
}, [activeIndex, tabItems]);
return (
<div ref={tabsRef} className={styles.bottomTabsSectionTabsWrap}>
<div
className={styles.bottomTabsSectionTabIndicator}
style={{
transform: `translateX(${tabIndicator.x}px)`,
width: tabIndicator.width,
opacity: tabIndicator.width > 0 ? 1 : 0,
}}
/>
<div className={styles.bottomTabsSectionContentTabs}>
{tabItems.map((item, i) => (
<div
key={i}
ref={(el) => {
tabItemRefs.current[i] = el;
}}
className={styles.bottomTabsSectionContentTab}
onClick={() => setActiveIndex(i)}
>
<span>{item.tabName}</span>
</div>
))}
</div>
</div>
)
}