File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
08-14
08-14
08-14
08-14
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>
);
}