Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 26x 26x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 1x 1x 11x 11x 11x 11x 11x 11x 11x | 'use client';
import Link from 'next/link';
import { useSearchParams } from 'next/navigation';
import { Suspense } from 'react';
import { cn } from '@/lib/utils';
export interface Tab {
label: string;
value: string;
}
interface TabNavigationProps {
tabs: Tab[];
paramName?: string;
basePath?: string;
defaultValue?: string;
}
interface TabItemProps {
label: string;
href: string;
isActive: boolean;
}
const TAB_TEXT_STYLES = {
base: 'flex h-full items-center justify-center text-text-sm-semibold transition-colors',
active: 'text-mint-600',
inactive: 'text-gray-600',
} as const;
const INDICATOR_STYLES = 'absolute bottom-0 left-0 z-10 h-[2px] w-full bg-mint-500';
const BASE_LINE_STYLES = 'absolute bottom-0 left-0 right-0 h-[2px] bg-gray-200';
const TabItem = ({ label, href, isActive }: TabItemProps) => (
<li className='relative flex-1'>
<Link
href={href}
className={cn(
TAB_TEXT_STYLES.base,
isActive ? TAB_TEXT_STYLES.active : TAB_TEXT_STYLES.inactive,
)}
>
{label}
</Link>
{isActive && <span className={INDICATOR_STYLES} />}
</li>
);
const TabNavigationInner = ({
tabs,
paramName = 'tab',
basePath = '',
defaultValue,
}: TabNavigationProps) => {
const searchParams = useSearchParams();
const currentTab = searchParams.get(paramName) ?? defaultValue ?? tabs[0].value;
return (
<nav className='sticky top-14 z-50 h-11 bg-white'>
<ul className='flex h-full w-full px-4'>
{tabs.map((tab) => (
<TabItem
key={tab.value}
href={`${basePath}?${paramName}=${tab.value}`}
isActive={currentTab === tab.value}
label={tab.label}
/>
))}
</ul>
<div className={BASE_LINE_STYLES} />
</nav>
);
};
export const TabNavigation = (props: TabNavigationProps) => {
return (
// 나중에 레이아웃으로 뺄거임 임시
<Suspense fallback={null}>
<TabNavigationInner {...props} />
</Suspense>
);
};
|