diff --git a/app/routes/home/components/BannerCarousel.tsx b/app/routes/home/components/BannerCarousel.tsx index 416328b..68dd739 100644 --- a/app/routes/home/components/BannerCarousel.tsx +++ b/app/routes/home/components/BannerCarousel.tsx @@ -26,7 +26,11 @@ const fashionBanners: BannerItem[] = [ { src: bannerFashion3, alt: "패션 배너 3" }, ]; -export default function BannerCarousel({ category }: { category: CategoryKey }) { +export default function BannerCarousel({ + category, +}: { + category: CategoryKey; +}) { const banners = category === "beauty" ? beautyBanners : fashionBanners; const [current, setCurrent] = useState(0); @@ -51,7 +55,7 @@ export default function BannerCarousel({ category }: { category: CategoryKey }) }, [start, stop]); return ( -
+
void; }) { - const tabs: { key: CategoryKey; label: string }[] = [ - { key: "beauty", label: "뷰티" }, - { key: "fashion", label: "패션" }, - ]; + const tabs = useMemo( + () => + [ + { key: "beauty" as const, label: "뷰티" }, + { key: "fashion" as const, label: "패션" }, + ] satisfies { key: CategoryKey; label: string }[], + [], + ); + + const wrapRef = useRef(null); + const [wrapWidth, setWrapWidth] = useState(0); + + useLayoutEffect(() => { + const el = wrapRef.current; + if (!el) return; + + const measure = () => setWrapWidth(el.clientWidth); + measure(); + + const ro = new ResizeObserver(() => measure()); + ro.observe(el); + + return () => ro.disconnect(); + }, []); + + const activeIndex = Math.max( + 0, + tabs.findIndex((t) => t.key === value), + ); + + const pxToRem = (px: number) => { + if (typeof window === "undefined") return `${px / 16}rem`; + const root = window.getComputedStyle(document.documentElement).fontSize; + const base = Number.parseFloat(root) || 16; + return `${px / base}rem`; + }; + + const trackWidth = Math.max(0, wrapWidth - SIDE_MARGIN_PX * 2); + const indicatorWidth = trackWidth / tabs.length; + const indicatorX = SIDE_MARGIN_PX + indicatorWidth * activeIndex; return ( -
+
{tabs.map((t) => { const active = t.key === value; @@ -37,15 +78,13 @@ export default function CategoryTabs({
-
-
-
+
); }