File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
"use client";
import type { ReactNode } from "react";
import { cx } from "../../utils";
import { FoxCaretRightIcon, FoxHouseIcon } from "../../icons";
export interface FoxBreadcrumbItem {
label: string;
/** 주면 링크가 되고, 없으면 글자만 남는다. 마지막 항목은 있어도 링크가 되지 않는다. */
href?: string;
/** 눌렀을 때. `href`와 함께 주면 라우터를 직접 다루는 호출부가 쓴다. */
onSelect?: () => void;
/** 글자 앞 아이콘. 첫 항목은 넘기지 않아도 집 아이콘이 붙는다. */
icon?: ReactNode;
}
export interface FoxBreadcrumbProps {
items: FoxBreadcrumbItem[];
/** 첫 항목 앞의 집 아이콘. 끄면 글자만 남는다. */
homeIcon?: boolean;
/** 스크린리더가 읽을 이름. 한 화면에 둘 이상 두면 서로 다르게 준다. */
label?: string;
/** 참이면 렌더하지 않는다(DOM에 남지 않는다). */
hidden?: boolean;
/** 배치 조정용. */
className?: string;
}
/**
* @fox 브레드크럼. 마지막 항목이 현재 위치이고 링크가 되지 않는다.
*
* ⚠️ 스타일은 이 파일이 import하지 않는다 — 호스트 앱이 `@use "@fox/styles/components"`
* (또는 개별 파티셜)로 한 번 불러와야 한다.
*/
export function FoxBreadcrumb({
items,
homeIcon = true,
label = "현재 위치",
hidden = false,
className,
}: FoxBreadcrumbProps) {
if (hidden || items.length === 0) {
return null;
}
return (
<nav className={cx("fox-breadcrumb", className)} aria-label={label}>
<ol className="fox-breadcrumb__list">
{items.map((item, index) => {
const last = index === items.length - 1;
const icon = item.icon ?? (index === 0 && homeIcon ? <FoxHouseIcon /> : null);
const body = (
<>
{icon && (
<span className="fox-breadcrumb__icon" aria-hidden="true">
{icon}
</span>
)}
{item.label}
</>
);
return (
<li className="fox-breadcrumb__crumb" key={`${item.label}-${index}`}>
{index > 0 && (
<span className="fox-breadcrumb__separator" aria-hidden="true">
<FoxCaretRightIcon />
</span>
)}
{/* 현재 위치는 누를 곳이 없다. */}
{last ? (
<span className="fox-breadcrumb__item" aria-current="page">
{body}
</span>
) : item.href ? (
<a className="fox-breadcrumb__item" href={item.href} onClick={item.onSelect}>
{body}
</a>
) : (
<button className="fox-breadcrumb__item" type="button" onClick={item.onSelect}>
{body}
</button>
)}
</li>
);
})}
</ol>
</nav>
);
}