Skip to content

Commit 9ecce54

Browse files
committed
[task/121] Breadcrumb 생성
1 parent 184f396 commit 9ecce54

5 files changed

Lines changed: 151 additions & 60 deletions

File tree

index.html

Lines changed: 2 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -44,57 +44,6 @@
4444
class="dark:bg-gray-dark-100 fixed top-0 z-40 hidden h-screen w-full flex-none overflow-x-hidden overflow-y-auto bg-[#f9f9fa] md:sticky md:top-12 md:z-auto md:block md:h-[calc(100vh-64px)] md:w-[320px]"
4545
>
4646
<div class="dark:bg-gray-dark-100 z-50 w-full p-4 md:block">
47-
<div id="nav__get-started" class="px-2 py-2 text-black">
48-
<div class="flex w-full items-center justify-between">
49-
<a
50-
class="flex items-center font-light text-black hover:text-blue-500 md:text-base dark:hover:text-blue-500"
51-
href="#/get-started"
52-
>
53-
<span class="m-0 p-0 pr-2">
54-
<svg
55-
xmlns="http://www.w3.org/2000/svg"
56-
viewBox="0 0 512 512"
57-
width="12"
58-
height="12"
59-
>
60-
<path
61-
d="M288 32c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 242.7-73.4-73.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l128 128c12.5 12.5 32.8 12.5 45.3 0l128-128c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L288 274.7 288 32zM64 352c-35.3 0-64 28.7-64 64l0 32c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-32c0-35.3-28.7-64-64-64l-101.5 0-45.3 45.3c-25 25-65.5 25-90.5 0L125.5 352 64 352zm368 56a24 24 0 1 1 0 48 24 24 0 1 1 0-48z"
62-
/>
63-
</svg>
64-
</span>
65-
Get started
66-
</a>
67-
<button
68-
class="inline-flex h-7 w-7 items-center justify-center rounded hover:cursor-pointer hover:bg-gray-400 hover:dark:bg-gray-400"
69-
>
70-
<span>
71-
<svg
72-
xmlns="http://www.w3.org/2000/svg"
73-
viewBox="0 0 512 512"
74-
width="12"
75-
height="12"
76-
>
77-
<path
78-
d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 129.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z"
79-
/>
80-
</svg>
81-
</span>
82-
<span class="hidden">
83-
<svg
84-
xmlns="http://www.w3.org/2000/svg"
85-
viewBox="0 0 512 512"
86-
width="12"
87-
height="12"
88-
>
89-
<path
90-
d="M233.4 105.4c12.5-12.5 32.8-12.5 45.3 0l192 192c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L256 173.3 86.6 342.6c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3l192-192z"
91-
/>
92-
</svg>
93-
</span>
94-
</button>
95-
</div>
96-
</div>
97-
<hr class="text-gray-light-200 dark:text-gray-dark-300 m-2" />
9847
<div
9948
id="nav__content"
10049
class="flex flex-col font-light text-black md:text-base"
@@ -671,13 +620,13 @@
671620
<!-- content: (마크다운 파일) 표시 공간 : 중간 부분 -->
672621
<div
673622
id="content"
674-
class="dark:bg-background-dark w-full min-w-0 bg-white p-8"
623+
class="dark:bg-background-dark w-full min-w-0 bg-white p-10"
675624
></div>
676625

677626
<!-- aside: 오른쪽 부분 사이드 -->
678627
<aside
679628
id="aside-toc"
680-
class="sticky top-12 h-full min-w-80 overflow-y-auto px-2 py-4 lg:block"
629+
class="sticky top-12 h-full min-w-70 overflow-y-auto px-2 py-4 lg:block"
681630
>
682631
<div id="toc" class="text-[14px] text-black font-bold"></div>
683632
</aside>

src/data/breadcrumb.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"breadcrumb": {
3+
"get-started": "시작하기",
4+
"get-docker": "Docker 설치",
5+
"docker-overview": "Docker 개요",
6+
"introduction": "소개",
7+
"build-and-push-first-image": "첫 번째 이미지 빌드 및 푸시",
8+
"develop-with-containers": "컨테이너로 개발",
9+
"get-docker-desktop": "Docker Desktop 설치",
10+
"whats-next": "다음 단계",
11+
"docker-concepts": "Docker 개념",
12+
"the-basics": "기본 사항",
13+
"what-is-a-container": "컨테이너란?",
14+
"what-is-a-registry": "레지스트리란?",
15+
"what-is-an-image": "이미지란?",
16+
"what-is-docker-compose": "Docker Compose란?",
17+
"building-images": "이미지 빌드",
18+
"understanding-image-layers": "이미지 레이어 이해",
19+
"writing-a-dockerfile": "Dockerfile 작성",
20+
"build-tag-and-publish-an-image": "이미지 빌드, 태그, 게시",
21+
"using-the-build-cache": "빌드 캐시 사용",
22+
"multi-stage-builds": "멀티 스테이지 빌드",
23+
"running-containers": "컨테이너 실행",
24+
"multi-container-applications": "멀티 컨테이너 애플리케이션",
25+
"overriding-container-defaults": "컨테이너 기본값 재정의",
26+
"persisting-container-data": "컨테이너 데이터 유지",
27+
"publishing-ports": "포트 게시",
28+
"sharing-local-files": "로컬 파일 공유",
29+
"docker-workshop": "Docker 워크샵",
30+
"resources": "리소스",
31+
"workshop": "워크샵",
32+
"02_our_app": "애플리케이션 컨테이너화",
33+
"03_updating_app": "애플리케이션 업데이트",
34+
"04_sharing_app": "애플리케이션 공유",
35+
"05_persisting_data": "데이터베이스 유지",
36+
"06_bind_mounts": "바인드 마운트 사용",
37+
"07_multi_container": "멀티 컨테이너 애플리케이션",
38+
"08_using_compose": "Docker Compose 사용",
39+
"09_image_best": "이미지 빌드 모범 사례",
40+
"10_what_next": "Docker 워크숍 이후 단계"
41+
}
42+
}

src/scripts/breadcrumb.ts

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import translations from '../data/breadcrumb.json';
2+
3+
interface BreadcrumbItem {
4+
name: string;
5+
path: string;
6+
}
7+
8+
interface TranslationData {
9+
breadcrumb: Record<string, string>;
10+
}
11+
12+
/**
13+
* 경로 세그먼트를 번역합니다.
14+
* @param segment 번역할 세그먼트
15+
* @returns 번역된 텍스트 또는 원본 텍스트
16+
*/
17+
function translatePathSegment(segment: string): string {
18+
const translationData = translations as TranslationData;
19+
return translationData.breadcrumb[segment] || segment;
20+
}
21+
22+
/**
23+
* 현재 hash를 기반으로 breadcrumb 아이템들을 생성합니다.
24+
*/
25+
function generateBreadcrumbItems(): BreadcrumbItem[] {
26+
const hash = window.location.hash.slice(1); // # 제거
27+
28+
if (!hash || hash === '/') {
29+
return [{ name: '홈', path: '#/' }];
30+
}
31+
32+
const pathSegments = hash.split('/').filter(segment => segment !== '');
33+
const breadcrumbItems: BreadcrumbItem[] = [
34+
{ name: '홈', path: '#/' }
35+
];
36+
37+
let currentPath = '';
38+
39+
pathSegments.forEach((segment) => {
40+
currentPath += `/${segment}`;
41+
42+
// 세그먼트 이름을 한국어로 변환
43+
const displayName = translatePathSegment(segment);
44+
45+
breadcrumbItems.push({
46+
name: displayName,
47+
path: `#${currentPath}`
48+
});
49+
});
50+
51+
return breadcrumbItems;
52+
}
53+
54+
/**
55+
* Breadcrumb HTML 요소를 생성합니다.
56+
*/
57+
function createBreadcrumbElement(items: BreadcrumbItem[]): HTMLElement {
58+
const breadcrumbNav = document.createElement('nav');
59+
breadcrumbNav.id = 'breadcrumbs';
60+
breadcrumbNav.className = 'pb-3 flex min-w-0 items-center gap-2 text-gray-400 dark:text-gray-300';
61+
62+
// HTML 문자열로 breadcrumb 구조 생성
63+
const breadcrumbHTML = items.map((item, index) => {
64+
const isLast = index === items.length - 1;
65+
66+
if (isLast) {
67+
// 현재 페이지는 span으로 표시
68+
return `<span class="truncate">${item.name}</span>`;
69+
} else {
70+
// 이전 페이지들은 링크로 표시 + 구분자
71+
return `<a href="${item.path}" class="link truncate">${item.name}</a> / `;
72+
}
73+
}).join('');
74+
75+
breadcrumbNav.innerHTML = breadcrumbHTML;
76+
return breadcrumbNav;
77+
}
78+
79+
/**
80+
* 기존 breadcrumb을 제거합니다.
81+
*/
82+
function removePreviousBreadcrumb(): void {
83+
const existingBreadcrumb = document.getElementById('breadcrumbs');
84+
if (existingBreadcrumb) {
85+
existingBreadcrumb.remove();
86+
}
87+
}
88+
89+
/**
90+
* Breadcrumb을 생성하고 div#content의 첫 번째 자식으로 추가합니다.
91+
*/
92+
export function initializeBreadcrumb(): void {
93+
const contentDiv = document.getElementById('content')!;
94+
95+
// 기존 breadcrumb 제거
96+
removePreviousBreadcrumb();
97+
98+
// 새 breadcrumb 생성
99+
const breadcrumbItems = generateBreadcrumbItems();
100+
const breadcrumbElement = createBreadcrumbElement(breadcrumbItems);
101+
102+
// div#content의 첫 번째 자식으로 추가
103+
contentDiv.insertBefore(breadcrumbElement, contentDiv.firstChild);
104+
}

src/scripts/main.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ import './components/box-component';
77
import { initializeMarkdownLoader } from './load_md';
88
import { initializeNavFn } from './nav';
99
import { initializeTableContents } from './table-contents';
10+
import { initializeBreadcrumb } from './breadcrumb';
1011

1112
document.addEventListener('DOMContentLoaded', async () => {
1213
try {
1314
await initializeMarkdownLoader();
1415
initializeNavFn();
1516
initializeTableContents();
17+
initializeBreadcrumb();
1618
} catch (error) {
1719
console.error('❌ main.ts: DOMContentLoaded : Markdown 로드 실패!', error);
1820
// 실제 다른 작업이 필요
@@ -23,6 +25,7 @@ window.addEventListener('hashchange', async () => {
2325
try {
2426
await initializeMarkdownLoader();
2527
initializeTableContents();
28+
initializeBreadcrumb();
2629
window.scrollTo(0, 0); // 페이지 이동 시 최상단으로 스크롤 이동
2730
} catch (error) {
2831
console.error('❌ main.ts: hashchange : Markdown 로드 실패!', error);

src/styles/content_style.css

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
#content {
2-
color: black !important;
3-
background-color: white;
4-
padding: 1rem;
5-
border-radius: 5px;
6-
}
7-
81
#content h1,
92
h2,
103
h3,

0 commit comments

Comments
 (0)