메인 베너너
This commit is contained in:
@@ -16,6 +16,7 @@ export function AppHeader() {
|
||||
const navRefs = React.useRef<Record<string, HTMLAnchorElement | null>>({});
|
||||
const panelRef = React.useRef<HTMLDivElement | null>(null);
|
||||
const blockRefs = React.useRef<Record<string, HTMLDivElement | null>>({});
|
||||
const navItemRefs = React.useRef<Record<string, HTMLDivElement | null>>({});
|
||||
const [leftPositions, setLeftPositions] = React.useState<Record<string, number>>({});
|
||||
const [panelHeight, setPanelHeight] = React.useState<number>(0);
|
||||
const [blockWidths, setBlockWidths] = React.useState<Record<string, number>>({});
|
||||
@@ -95,29 +96,15 @@ export function AppHeader() {
|
||||
if (!container) return;
|
||||
const containerRect = container.getBoundingClientRect();
|
||||
const nextPositions: Record<string, number> = {};
|
||||
const nextWidths: Record<string, number> = {};
|
||||
categories.forEach((cat) => {
|
||||
const a = navRefs.current[cat.slug];
|
||||
if (a) {
|
||||
const r = a.getBoundingClientRect();
|
||||
nextPositions[cat.slug] = Math.max(0, r.left - containerRect.left);
|
||||
}
|
||||
const itemEl = navItemRefs.current[cat.slug];
|
||||
if (!itemEl) return;
|
||||
const r = itemEl.getBoundingClientRect();
|
||||
nextPositions[cat.slug] = Math.max(0, r.left - containerRect.left);
|
||||
nextWidths[cat.slug] = r.width; // 각 네비 항목의 실제 폭을 사용
|
||||
});
|
||||
setLeftPositions(nextPositions);
|
||||
|
||||
// 각 블록의 가로 폭 = 다음 항목의 left까지 남은 거리
|
||||
// 마지막 항목은 컨테이너 끝까지 확장되지 않도록 width를 지정하지 않음
|
||||
const nextWidths: Record<string, number> = {};
|
||||
const ordered = categories
|
||||
.filter((c) => typeof nextPositions[c.slug] === "number")
|
||||
.sort((a, b) => (nextPositions[a.slug]! - nextPositions[b.slug]!));
|
||||
ordered.forEach((cat, idx) => {
|
||||
const currentLeft = nextPositions[cat.slug]!;
|
||||
if (idx < ordered.length - 1) {
|
||||
const nextLeft = nextPositions[ordered[idx + 1].slug]!;
|
||||
const width = Math.max(0, nextLeft - currentLeft);
|
||||
nextWidths[cat.slug] = width;
|
||||
}
|
||||
});
|
||||
setBlockWidths(nextWidths);
|
||||
|
||||
// 패널 높이 = 블록들 중 최대 높이
|
||||
@@ -166,11 +153,19 @@ export function AppHeader() {
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center gap-8">
|
||||
{categories.map((cat) => (
|
||||
<div key={cat.id} className="relative group min-w-[80px] text-center" onMouseEnter={() => setOpenSlug(cat.slug)}>
|
||||
{categories.map((cat, idx) => (
|
||||
<div
|
||||
key={cat.id}
|
||||
className="relative group min-w-[80px] text-center"
|
||||
onMouseEnter={() => setOpenSlug(cat.slug)}
|
||||
ref={(el) => {
|
||||
navItemRefs.current[cat.slug] = el;
|
||||
}}
|
||||
style={{ minWidth: idx === categories.length - 1 ? 120 : undefined }}
|
||||
>
|
||||
<Link
|
||||
href={cat.boards?.[0]?.id ? `/boards/${cat.boards[0].id}` : `/boards?category=${cat.slug}`}
|
||||
className={`px-2 py-2 text-sm font-medium transition-colors duration-200 hover:text-neutral-900 ${
|
||||
className={`px-2 py-2 text-sm font-medium transition-colors duration-200 hover:text-neutral-900 whitespace-nowrap ${
|
||||
activeCategorySlug === cat.slug ? "text-neutral-900" : "text-neutral-700"
|
||||
}`}
|
||||
ref={(el) => {
|
||||
@@ -197,7 +192,7 @@ export function AppHeader() {
|
||||
onMouseEnter={() => { cancelClose(); setMegaOpen(true); }}
|
||||
onMouseLeave={() => { scheduleClose(); }}
|
||||
>
|
||||
<div className="px-4 py-4 w-full max-w-7xl mx-auto overflow-x-hidden">
|
||||
<div className="px-4 py-4 w-full mx-auto overflow-x-hidden">
|
||||
<div ref={panelRef} className="relative">
|
||||
{categories.map((cat) => (
|
||||
<div
|
||||
@@ -206,7 +201,7 @@ export function AppHeader() {
|
||||
blockRefs.current[cat.slug] = el;
|
||||
}}
|
||||
className="absolute top-0"
|
||||
style={{ left: (leftPositions[cat.slug] ?? 0) + 0, width: blockWidths[cat.slug] ?? undefined }}
|
||||
style={{ left: (leftPositions[cat.slug] ?? 0), width: blockWidths[cat.slug] ?? undefined }}
|
||||
>
|
||||
{/* <div className="mb-2 font-semibold text-neutral-800">{cat.name}</div> */}
|
||||
<div className="flex flex-col gap-3">
|
||||
@@ -214,7 +209,7 @@ export function AppHeader() {
|
||||
<Link
|
||||
key={b.id}
|
||||
href={`/boards/${b.id}`}
|
||||
className={`rounded px-2 py-1 text-sm transition-colors duration-150 hover:bg-neutral-100 hover:text-neutral-900 text-center ${
|
||||
className={`rounded px-2 py-1 text-sm transition-colors duration-150 hover:bg-neutral-100 hover:text-neutral-900 text-center whitespace-nowrap ${
|
||||
activeBoardId === b.id ? "bg-neutral-100 text-neutral-900 font-medium" : "text-neutral-700"
|
||||
}`}
|
||||
aria-current={activeBoardId === b.id ? "page" : undefined}
|
||||
|
||||
Reference in New Issue
Block a user