내비게이션
메인 메뉴·브레드크럼·사이드 메뉴·페이지네이션으로 사이트 탐색을 구성합니다.
설치
MainMenu
1Depth 메뉴 바입니다. active는 현재 섹션에 하단 강조 바를 표시하고, hasSubmenu는 하위 메뉴 표시자를 추가합니다.
import { MainMenu, MainMenuBar, MainMenuBarItem } from "@/components/ui/krds/(navigation)/main-menu"
export function GlobalNav() {
return (
<MainMenu>
<MainMenuBar aria-label="주요 메뉴">
<MainMenuBarItem href="/policy" hasSubmenu>
정책정보
</MainMenuBarItem>
<MainMenuBarItem href="/services" hasSubmenu>
민원 서비스
</MainMenuBarItem>
<MainMenuBarItem href="/notice" active>
공지사항
</MainMenuBarItem>
</MainMenuBar>
</MainMenu>
)
}대형 드롭다운 패널이 필요하면 MainMenuPanel 계열 컴포넌트로 확장합니다. MainMenu 문서의 패널 예제를 참고하세요.
Breadcrumb
BreadcrumbHome은 홈 아이콘과 링크(/)가 기본값입니다. 마지막 항목은 링크가 아닌 BreadcrumbPage를 사용하며 aria-current="page"가 적용됩니다. 모바일에서는 중간 항목이 자동으로 축약됩니다.
import {
Breadcrumb,
BreadcrumbHome,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from "@/components/ui/krds/(navigation)/breadcrumb"
export function PageBreadcrumb() {
return (
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbHome />
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink href="/services">민원 서비스</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>신청 내역</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
)
}SideNavigation
2·3Depth를 접이식 그룹으로 구성합니다. 그룹 열림 상태는 defaultOpen(uncontrolled) 또는 open/onOpenChange(controlled)로 제어합니다.
import {
SideNavigation,
SideNavigationGroup,
SideNavigationItem,
SideNavigationList,
SideNavigationTitle,
SideNavigationTrigger,
} from "@/components/ui/krds/(navigation)/side-navigation"
export function ServiceSideNav() {
return (
<SideNavigation>
<SideNavigationTitle>민원 서비스</SideNavigationTitle>
<SideNavigationGroup defaultOpen>
<SideNavigationTrigger>신청·접수</SideNavigationTrigger>
<SideNavigationList>
<SideNavigationItem href="/services/apply" active>
온라인 신청
</SideNavigationItem>
<SideNavigationItem href="/services/status">신청 내역 조회</SideNavigationItem>
</SideNavigationList>
</SideNavigationGroup>
<SideNavigationGroup>
<SideNavigationTrigger>증명서 발급</SideNavigationTrigger>
</SideNavigationGroup>
</SideNavigation>
)
}본문과 함께 배치할 때는 사이드 메뉴와 본문을 가로로 나란히 놓습니다.
export function ServiceLayout({ children }: { children: React.ReactNode }) {
return (
<div className="flex gap-8">
<ServiceSideNav />
<main id="main-content" tabIndex={-1} className="flex-1">
{children}
</main>
</div>
)
}Pagination
Pagination은 controlled 컴포넌트입니다. 현재 페이지 상태는 사용하는 쪽에서 관리하고, 번호·줄임표 배열은 buildPageItems 헬퍼로 계산합니다. buildPageItems(current, total, boundary, sibling)은 양끝 고정 개수(boundary)와 현재 페이지 주변 개수(sibling)를 받아 숫자와 "dots"가 섞인 배열을 반환합니다.
"use client"
import * as React from "react"
import {
buildPageItems,
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationNext,
PaginationPrev,
} from "@/components/ui/krds/(navigation)/pagination"
export function NoticePagination({ total = 10 }: { total?: number }) {
const [current, setCurrent] = React.useState(1)
const items = buildPageItems(current, total, 1, 3)
return (
<Pagination>
<PaginationContent>
<PaginationPrev disabled={current === 1} onClick={() => setCurrent((p) => Math.max(1, p - 1))} />
{items.map((item, index) =>
item === "dots" ? (
<PaginationEllipsis key={`dots-${index}`} />
) : (
<PaginationItem key={item} active={item === current} onClick={() => setCurrent(item)}>
{item}
</PaginationItem>
)
)}
<PaginationNext disabled={current === total} onClick={() => setCurrent((p) => Math.min(total, p + 1))} />
</PaginationContent>
</Pagination>
)
}다음 단계
목록과 표에서 데이터 표시 컴포넌트를 구성합니다.