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

size

"sm" | "md" | "lg"

md

Breadcrumb.List

경로 항목을 순서대로 감싸는 목록이다.

공개 Props 없음

Breadcrumb.Item

상위 경로나 현재 위치를 나타내는 항목이다.

Prop

Type

Default

asChild

boolean

지정 안 함

children

React.ReactNode

지정 안 함

endIcon

React.ReactNode

지정 안 함

startIcon

React.ReactNode

지정 안 함

Breadcrumb.Separator

경로 항목 사이를 시각적으로 구분한다.

Prop

Type

Default

children

React.ReactNode

지정 안 함

Breadcrumb.Ellipsis

생략된 중간 경로를 나타낸다.

공개 Props 없음

구성 구조

BreadcrumbItem만 직접 나열하면 되고, List·Separator는 루트가 이미 자동으로 구성한다 — 재사용 가능한 만능 조립 부품이 아니라, 루트가 내부적으로만 쓰는 파츠다.

서브파트직접 배치하나이유
Breadcrumb.Item그렇다 — 경로마다 하나씩 나열유일하게 소비자가 직접 조립하는 단위
Breadcrumb.List아니다루트가 children을 항상 List로 감싼다. 다시 넣으면 <ol>이 중첩된다
Breadcrumb.Separator아니다루트가 항목 사이마다 자동으로 하나씩 끼워 넣는다. 직접 넣으면 겹쳐서 두세 개가 보인다
Breadcrumb.Ellipsis그렇다 — 단, Item의 내용으로축약이 필요한 자리에서 Item을 대신하지 않고 그 안에 넣는다

실행 가능한 예시는 아래 basic·ellipsis 예제를 참고한다 — ellipsis 예제가 정확히 이 "Item 안에 Ellipsis" 패턴을 보여준다.

몇 단계부터 Ellipsis로 접을지 자동으로 정해주는 로직은 없다 — 소비자가 직접 판단해서 중간 ItemEllipsis로 바꿔 끼운다. 마지막 항목을 "현재 위치"로 스크린리더에 알리려면 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);
}