JS Design System v0.6

Breadcrumb

현재 위치의 계층 경로를 보여주고 상위로 돌아가게 합니다. 3단계 이상 깊은 상세 화면에 씁니다.

1. Default

nav > ol. 마지막 항목은 링크 없이 aria-current=page 이고, 라벨은 span 으로 감쌉니다 — 220px 를 넘으면 말줄임.

2. Collapsed

가운데가 2개 이상일 때(5단계 이상) 접습니다. 첫 항목과 끝 2개는 남기고 가운데만 … 로 묶으며, 누르면 펼쳐집니다.

Props

HTML 에서는 클래스와 속성으로, React(@jiran/ds-react)에서는 같은 이름의 prop(variant · size …)으로 변형·상태를 지정합니다.

Prop / ClassType · ValuesDefaultDescription
.breadcrumbol—nav[aria-label] 안의 ol. React Breadcrumb 의 label 이 그 aria-label
li alink—상위 경로 링크(React BreadcrumbItem href). 220px 를 넘으면 말줄임 — 전체 문구는 title 로 함께
li[aria-current=page] > spancurrent—현재 페이지. 링크 없이 Semibold. 라벨을 span 으로 감싸야 말줄임이 걸립니다(li 가 flex) — React current 가 자동으로 감쌉니다
a.iconbooleanfalse홈 아이콘처럼 아이콘만 있는 링크. aria-label 필수 — 없으면 이름 없는 링크로 읽힙니다. 클릭 영역은 24×24
.morebutton—접힌 경로 펼치기(React BreadcrumbMore). 클릭 영역 24×24
.more[data-items]attribute—필수 — 접은 경로를 | 로 이어 둡니다("정책|USB 제어"). 누르면 그 자리에 링크로 펼치고 첫 링크로 포커스를 옮기며 ds:expand 를 발행합니다. 비어 있으면 아무 일도 하지 않습니다 — ds.js 담당. React 는 BreadcrumbMore 의 onClick 으로 직접 처리
.breadcrumb li a svgelement—링크 앞 아이콘. 홈 아이콘 18 · .more 아이콘 14

Usage

React: @jiran/ds-react 패키지를 설치하고 style.css 를 한 번 import 하면 위 React 탭 코드를 그대로 쓸 수 있습니다(React Package). HTML: assets/style.css 를 연결하고(일부만 필요하면 아래 컴포넌트 CSS 복사), 동작이 필요하면 assets/ds.js 를 함께 넣습니다 — 이 페이지의 프리뷰가 그 스크립트로 동작합니다. 색은 전부 토큰(var(--accent) 등)을 참조하므로 --accent-* 만 제품 컬러로 바꾸면 됩니다.

React @jiran/ds-react

npm i @jiran/ds-react

// main.tsx — 앱 진입점에서 한 번
import "@jiran/ds-react/style.css";

// 컴포넌트
import { Breadcrumb, BreadcrumbItem, BreadcrumbMore } from "@jiran/ds-react";

HTML

<!-- 1) 토큰 + 전체 컴포넌트 스타일 한 번에 연결 -->
<link rel="stylesheet" href="assets/style.css">
<!-- 동작(드롭다운·탭·달력·표 정렬/선택·토스트 등) — 순수 JS 한 파일. React 제품은 불필요 -->
<script src="assets/ds.js" defer></script>

<!-- 2) 또는 아래 "Component CSS" 만 프로젝트 CSS 에 붙이고,
        :root 토큰은 Foundations › Design Token 에서 복사 -->

Component CSS .breadcrumb

/* JS Design System v0.6 · .breadcrumb · 토큰(var(--*))은 assets/style.css :root 참고 */
.breadcrumb{display:flex;align-items:center;gap:6px;font-size:14px;list-style:none;padding:0;margin:0;flex-wrap:wrap}
.breadcrumb li{display:flex;align-items:center;gap:6px;color:var(--text-tertiary);margin:0}
.breadcrumb li+li::before{content:"";width:12px;height:12px;flex:none;background:var(--text-disabled);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%2224%22 height=%2224%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22 %3E%3Cpath d=%22M17 5l-10 14%22 /%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%2224%22 height=%2224%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22 %3E%3Cpath d=%22M17 5l-10 14%22 /%3E%3C/svg%3E") center/contain no-repeat}
.breadcrumb a{color:inherit;text-decoration:none}
.breadcrumb a:hover{color:var(--text-primary);text-decoration:underline}
.breadcrumb li[aria-current]{color:var(--text-primary);font-weight:600}
.breadcrumb .more{padding:0 4px;color:var(--text-tertiary);cursor:pointer;border:0;background:none;font:inherit}
.breadcrumb .more:hover{color:var(--text-primary)}
.breadcrumb .more svg{width:14px;height:14px;display:block}
.breadcrumb li>a:not(.icon),.breadcrumb li>span{max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.breadcrumb li>a.icon,.breadcrumb .more{position:relative}
.breadcrumb li>a.icon::after,.breadcrumb .more::after{content:"";position:absolute;top:50%;left:50%;width:100%;height:24px;min-width:24px;transform:translate(-50%,-50%)}