Breadcrumb
Navigation
현재 위치와 상위 경로를 나타내는 이동 경로.
Usage
현재 위치와 상위 경로를 보여주는 계층 내비게이션
import
import
import { Breadcrumb } from '@mildang/design-system/Breadcrumb';Breadcrumb 하나만 가져오면 Breadcrumb.Root · Breadcrumb.List · Breadcrumb.Item · Breadcrumb.Separator · Breadcrumb.Ellipsis 를 그 아래에서 쓸 수 있다.
예제를 복사해 쓸 때 필요한 준비
• @mildang/icons 를 따로 설치한다. DS 패키지에 아이콘 컴포넌트가 포함되지 않는다.
• 외부 패키지를 따로 설치한다. DS 의 전이 의존성에 기대지 않는다.
Anatomy
tsx
import { Breadcrumb } from '@mildang/design-system/Breadcrumb';
export default function Example() {
return (
<Breadcrumb>
<Breadcrumb.List>
<Breadcrumb.Item />
<Breadcrumb.Separator />
<Breadcrumb.Ellipsis />
</Breadcrumb.List>
</Breadcrumb>
);
}부품
필수 여부
반복
위치
Breadcrumb.Root
Breadcrumb.List
Root 안에 둔다.
Breadcrumb.Item
여러 개 가능
List 안에 경로마다 둔다.
Breadcrumb.Separator
여러 개 가능
List 안에서 Item 사이에 둔다.
Breadcrumb.Ellipsis
Item 안에서 사용한다.
- Root 안에 List를 두고, List 안에 경로 Item을 순서대로 배치한다.
API Reference
Breadcrumb Props
Prop
Type
Default
"sm" | "md" | "lg"
md
Breadcrumb.List
경로 항목을 순서대로 감싸는 목록이다.
공개 Props 없음
Breadcrumb.Item
상위 경로나 현재 위치를 나타내는 항목이다.
Prop
Type
Default
boolean
지정 안 함
React.ReactNode
지정 안 함
React.ReactNode
지정 안 함
React.ReactNode
지정 안 함
Breadcrumb.Separator
경로 항목 사이를 시각적으로 구분한다.
Prop
Type
Default
React.ReactNode
지정 안 함
Breadcrumb.Ellipsis
생략된 중간 경로를 나타낸다.
공개 Props 없음
구성 구조
Breadcrumb은 Item만 직접 나열하면 되고, List·Separator는 루트가 이미 자동으로
구성한다 — 재사용 가능한 만능 조립 부품이 아니라, 루트가 내부적으로만 쓰는 파츠다.
| 서브파트 | 직접 배치하나 | 이유 |
|---|---|---|
Breadcrumb.Item | 그렇다 — 경로마다 하나씩 나열 | 유일하게 소비자가 직접 조립하는 단위 |
Breadcrumb.List | 아니다 | 루트가 children을 항상 List로 감싼다. 다시 넣으면 <ol>이 중첩된다 |
Breadcrumb.Separator | 아니다 | 루트가 항목 사이마다 자동으로 하나씩 끼워 넣는다. 직접 넣으면 겹쳐서 두세 개가 보인다 |
Breadcrumb.Ellipsis | 그렇다 — 단, Item의 내용으로 | 축약이 필요한 자리에서 Item을 대신하지 않고 그 안에 넣는다 |
실행 가능한 예시는 아래 basic·ellipsis 예제를 참고한다 — ellipsis 예제가 정확히 이
"Item 안에 Ellipsis" 패턴을 보여준다.
몇 단계부터 Ellipsis로 접을지 자동으로 정해주는 로직은 없다 — 소비자가 직접 판단해서
중간 Item을 Ellipsis로 바꿔 끼운다. 마지막 항목을 "현재 위치"로 스크린리더에
알리려면 aria-current="page"도 소비자가 직접 붙인다(컴포넌트가 자동으로 붙이지 않는다).
기본 사용
세 단 경로를 보여준다. 마지막 항목은 현재 위치라 링크를 걸지 않고, 구분자는 Breadcrumb.List 가 항목 사이에 자동으로 끼워 넣는다.
코드
import type { ComponentProps } from 'react';
import { Breadcrumb as Breadcrumb } from '@mildang/design-system/Breadcrumb';
import Link from 'next/link';
const STORY_DEFAULT_ARGS = { ...({}), ...({
size: 'md',
}) } as ComponentProps<typeof Breadcrumb>;
const BreadcrumbDefaultExampleRender = (args: ComponentProps<typeof Breadcrumb>) => (
<Breadcrumb {...args}>
<Breadcrumb.Item>
<Link href="/">Home</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>
<Link href="/components">Components</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>Breadcrumb</Breadcrumb.Item>
</Breadcrumb>
);
export default function BreadcrumbDefaultExample(props: Partial<ComponentProps<typeof Breadcrumb>>) {
const mergedProps = { ...STORY_DEFAULT_ARGS, ...props } as ComponentProps<typeof Breadcrumb>;
return BreadcrumbDefaultExampleRender(mergedProps);
}
중간 경로 축약
경로 중간을 Breadcrumb.Ellipsis 로 접는다. Item 을 대신하지 않고 Item 안의 내용으로 넣는다.
코드
import type { ComponentProps } from 'react';
import { Breadcrumb as Breadcrumb } from '@mildang/design-system/Breadcrumb';
import Link from 'next/link';
const STORY_DEFAULT_ARGS = { ...({}), ...({}) } as ComponentProps<typeof Breadcrumb>;
const BreadcrumbWithEllipsisExampleRender = (args: ComponentProps<typeof Breadcrumb>) => (
<Breadcrumb {...args}>
<Breadcrumb.Item>
<Link href="/">Home</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>
<Breadcrumb.Ellipsis />
</Breadcrumb.Item>
<Breadcrumb.Item>
<Link href="/components">Components</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>Breadcrumb</Breadcrumb.Item>
</Breadcrumb>
);
export default function BreadcrumbWithEllipsisExample(props: Partial<ComponentProps<typeof Breadcrumb>>) {
const mergedProps = { ...STORY_DEFAULT_ARGS, ...props } as ComponentProps<typeof Breadcrumb>;
return BreadcrumbWithEllipsisExampleRender(mergedProps);
}
상태별 표시
| 상태 | 대상 | 실제 구현 |
|---|---|---|
| Inactive | 링크로 감싼 중간 항목 | 기본 텍스트 색. hover 시 색 변경 + 배경 오버레이(밑줄은 없다) |
| Active | 마지막 항목 | CSS :last-child로 텍스트 색만 강조(굵기는 그대로) — aria-current는 자동으로 붙지 않는다 |
| — (링크 없는 항목) | 일반 텍스트로만 넣은 항목 | hover 스타일은 <a>/<button> 자식에만 적용되므로, 링크가 없으면 hover 효과도 없다 |
기본 사용
세 단 경로를 보여준다. 마지막 항목은 현재 위치라 링크를 걸지 않고, 구분자는 Breadcrumb.List 가 항목 사이에 자동으로 끼워 넣는다.
코드
import type { ComponentProps } from 'react';
import { Breadcrumb as Breadcrumb } from '@mildang/design-system/Breadcrumb';
import Link from 'next/link';
const STORY_DEFAULT_ARGS = { ...({}), ...({
size: 'md',
}) } as ComponentProps<typeof Breadcrumb>;
const BreadcrumbDefaultExampleRender = (args: ComponentProps<typeof Breadcrumb>) => (
<Breadcrumb {...args}>
<Breadcrumb.Item>
<Link href="/">Home</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>
<Link href="/components">Components</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>Breadcrumb</Breadcrumb.Item>
</Breadcrumb>
);
export default function BreadcrumbDefaultExample(props: Partial<ComponentProps<typeof Breadcrumb>>) {
const mergedProps = { ...STORY_DEFAULT_ARGS, ...props } as ComponentProps<typeof Breadcrumb>;
return BreadcrumbDefaultExampleRender(mergedProps);
}
사용 가이드
권장
- 홈과 현재 위치는 항상 노출한다.
- 경로가 길어지면 중간 항목을 Ellipsis로 접는다.
- 모바일에서는 노출 단계를 2~3개로 단순화한다.
지양
- 현재 항목까지 링크로 두지 않는다 — 클릭해도 새로고침과 다를 게 없어 혼란을 준다.
- 경로 하나를 줄바꿈으로 두 줄 이상 표기하지 않는다.
예제
크기
sm·md·lg 를 비교한다. size 는 루트에서 한 번만 지정하면 항목·구분자·아이콘까지 함께 상속받는다.
코드
import { Breadcrumb as Breadcrumb } from '@mildang/design-system/Breadcrumb';
import Link from 'next/link';
const BreadcrumbSizesExample = () => (
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
<Breadcrumb size="sm">
<Breadcrumb.Item>
<Link href="www.google.com">Home</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>Small</Breadcrumb.Item>
</Breadcrumb>
<Breadcrumb size="md">
<Breadcrumb.Item>
<Link href="/">Home</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>Medium</Breadcrumb.Item>
</Breadcrumb>
<Breadcrumb size="lg">
<Breadcrumb.Item>
<Link href="/">Home</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>Large</Breadcrumb.Item>
</Breadcrumb>
</div>
);
export default BreadcrumbSizesExample;
WithIcons
코드
import type { ComponentProps } from 'react';
import { Breadcrumb as Breadcrumb } from '@mildang/design-system/Breadcrumb';
import Home from '@mildang/icons/react/home';
import Link from 'next/link';
const STORY_DEFAULT_ARGS = { ...({}), ...({}) } as ComponentProps<typeof Breadcrumb>;
const BreadcrumbWithIconsExampleRender = (args: ComponentProps<typeof Breadcrumb>) => (
<Breadcrumb {...args}>
<Breadcrumb.Item asChild startIcon={<Home />}>
<Link href="/">Home</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>
<Link href="/components">Components</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>Breadcrumb</Breadcrumb.Item>
</Breadcrumb>
);
export default function BreadcrumbWithIconsExample(props: Partial<ComponentProps<typeof Breadcrumb>>) {
const mergedProps = { ...STORY_DEFAULT_ARGS, ...props } as ComponentProps<typeof Breadcrumb>;
return BreadcrumbWithIconsExampleRender(mergedProps);
}
LongPath
코드
import type { ComponentProps } from 'react';
import { Breadcrumb as Breadcrumb } from '@mildang/design-system/Breadcrumb';
import Link from 'next/link';
const STORY_DEFAULT_ARGS = { ...({}), ...({}) } as ComponentProps<typeof Breadcrumb>;
const BreadcrumbLongPathExampleRender = (args: ComponentProps<typeof Breadcrumb>) => (
<Breadcrumb {...args}>
<Breadcrumb.Item>
<Link href="/">Home</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>
<Link href="/products">Products</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>
<Link href="/products/electronics">Electronics</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>
<Link href="/products/electronics/computers">Computers</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>
<Link href="/products/electronics/computers/laptops">Laptops</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>Gaming Laptops</Breadcrumb.Item>
</Breadcrumb>
);
export default function BreadcrumbLongPathExample(props: Partial<ComponentProps<typeof Breadcrumb>>) {
const mergedProps = { ...STORY_DEFAULT_ARGS, ...props } as ComponentProps<typeof Breadcrumb>;
return BreadcrumbLongPathExampleRender(mergedProps);
}