Skip to content

Commit 59641c4

Browse files
committed
fix(ui): resolve docker build error by replacing non-ascii character in App.svelte
1 parent 93a4d83 commit 59641c4

File tree

8 files changed

+479
-360
lines changed

8 files changed

+479
-360
lines changed

src/App.svelte

Lines changed: 44 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,19 @@ import PostDetail from "./components/PostDetail.svelte";
77
import Sidebar from "./components/Sidebar.svelte";
88
import { posts } from "./stores/posts";
99
10-
void Router;
11-
void Footer;
12-
void Sidebar;
13-
void posts;
14-
1510
let sidebarCollapsed = false;
16-
let sidebarElement;
17-
let mainContentElement;
18-
let contentElement;
19-
let manualToggle = false; // 수동 토글 상태
20-
let _manualToggleTimeout;
21-
let resizeTimeout; // 리사이즈 디바운스용
22-
23-
// 라우트 정의
11+
let sidebarElement: HTMLElement | null = null;
12+
let mainContentElement: HTMLElement | null = null;
13+
let contentElement: HTMLElement | null = null;
14+
let manualToggle = false;
15+
let resizeTimeout: any = null;
16+
2417
const routes = {
2518
"/": BlogList,
2619
"/category/:category": BlogList,
2720
"/post/:slug": PostDetail,
2821
};
2922
30-
void routes;
31-
32-
// 사이드바 상태 변화 감지
3323
$: {
3424
if (typeof document !== "undefined") {
3525
if (sidebarCollapsed) {
@@ -40,27 +30,23 @@ $: {
4030
}
4131
}
4232
43-
let checkTimeout = null;
33+
let checkTimeout: any = null;
4434
4535
function checkSidebarCollision() {
4636
if (!sidebarElement || !mainContentElement) {
4737
return;
4838
}
4939
50-
// manualToggle 상태일 때는 자동 충돌 감지 비활성화
5140
if (manualToggle) {
5241
return;
5342
}
5443
55-
// 디바운스: 이전 타이머 취소하고 새로 설정
5644
clearTimeout(resizeTimeout);
5745
resizeTimeout = setTimeout(() => {
58-
// 요소가 null이면 리턴
5946
if (!sidebarElement || !contentElement) {
6047
return;
6148
}
6249
63-
// 요소가 아직 렌더링되지 않았다면 사이드바를 표시
6450
const sidebarRect = sidebarElement.getBoundingClientRect();
6551
const contentRect = contentElement.getBoundingClientRect();
6652
@@ -71,35 +57,28 @@ function checkSidebarCollision() {
7157
return;
7258
}
7359
74-
// 화면이 너무 작으면 자동으로 접기
7560
if (window.innerWidth < 768) {
7661
if (!sidebarCollapsed) {
7762
sidebarCollapsed = true;
7863
}
7964
return;
8065
}
8166
82-
// 화면이 충분히 크고 사이드바가 접혀있으면 펼치기
8367
if (window.innerWidth >= 1200 && sidebarCollapsed) {
8468
if (contentRect.left > 120) {
8569
sidebarCollapsed = false;
8670
}
8771
return;
8872
}
8973
90-
// 사이드바와 콘텐츠가 겹치는지 확인 (사이드바 오른쪽 끝이 콘텐츠 왼쪽 시작점을 넘어가면 겹침)
9174
const isOverlapping = sidebarRect.right >= contentRect.left;
9275
93-
// 무한 루프 방지: 현재 상태와 다를 때만 변경
94-
// 겹치면서 현재 펼쳐져 있으면 접기
9576
if (isOverlapping && !sidebarCollapsed) {
9677
sidebarCollapsed = true;
97-
}
98-
// 콘텐츠의 왼쪽 x좌표가 120보다 크고 현재 접혀져 있으면 펼치기
99-
else if (contentRect.left > 120 && sidebarCollapsed) {
78+
} else if (contentRect.left > 120 && sidebarCollapsed) {
10079
sidebarCollapsed = false;
10180
}
102-
}, 5); // 5ms 디바운스
81+
}, 5);
10382
}
10483
10584
function debouncedCheckSidebarCollision() {
@@ -110,7 +89,6 @@ function debouncedCheckSidebarCollision() {
11089
}
11190
11291
function handleResize() {
113-
// 리사이즈 시 수동 토글 상태 리셋
11492
manualToggle = false;
11593
checkSidebarCollision();
11694
}
@@ -121,18 +99,15 @@ function toggleSidebar() {
12199
}
122100
123101
onMount(() => {
124-
// 초기 체크를 여러 번 시도 (배포 환경에서 DOM 로딩 지연 대응)
125102
const checkWithRetry = () => {
126103
checkSidebarCollision();
127-
// 요소가 아직 준비되지 않았으면 다시 시도
128104
if (!sidebarElement || !mainContentElement) {
129105
setTimeout(checkWithRetry, 200);
130106
}
131107
};
132108
133109
setTimeout(checkWithRetry, 100);
134110
135-
// ResizeObserver로 요소 크기 변화 감지
136111
const resizeObserver = new ResizeObserver(() => {
137112
debouncedCheckSidebarCollision();
138113
});
@@ -142,7 +117,6 @@ onMount(() => {
142117
143118
window.addEventListener("resize", handleResize);
144119
145-
// 토글 이벤트 리스너
146120
const handleToggleSidebar = () => {
147121
toggleSidebar();
148122
};
@@ -161,16 +135,16 @@ onMount(() => {
161135
</script>
162136

163137
<div id="app-container" class:sidebar-collapsed={sidebarCollapsed}>
164-
<!-- 토글 버튼을 항상 왼쪽 위에 고정 -->
165-
<button class="sidebar-toggle" on:click={toggleSidebar}>
166-
138+
<button class="sidebar-toggle" on:click={toggleSidebar} aria-label="Toggle Sidebar">
139+
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
140+
<path d="M3 5H17M3 10H17M3 15H17" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
141+
</svg>
167142
</button>
168143

169144
<aside id="sidebar" class:collapsed={sidebarCollapsed} bind:this={sidebarElement}>
170145
<Sidebar />
171146
</aside>
172147

173-
174148
<main id="main-content" bind:this={mainContentElement}>
175149
<div id="content" bind:this={contentElement}>
176150
{#await $posts}
@@ -185,8 +159,6 @@ onMount(() => {
185159
</main>
186160
</div>
187161

188-
189-
190162
<style>
191163
:global(body) {
192164
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
@@ -219,7 +191,6 @@ onMount(() => {
219191
transform: translateX(-100%);
220192
}
221193
222-
223194
#main-content {
224195
flex: 1;
225196
margin-left: 240px;
@@ -229,8 +200,6 @@ onMount(() => {
229200
transition: margin-left 0.01s ease;
230201
}
231202
232-
233-
234203
#content {
235204
flex: 1;
236205
max-width: 800px;
@@ -248,7 +217,6 @@ onMount(() => {
248217
}
249218
}
250219
251-
/* Mermaid 다이어그램 스타일 */
252220
:global(.mermaid-diagram) {
253221
text-align: center;
254222
margin: 20px 0;
@@ -273,43 +241,41 @@ onMount(() => {
273241
text-align: center;
274242
}
275243
276-
/* 토글 버튼 스타일 - 항상 왼쪽 위에 고정 */
277244
.sidebar-toggle {
278-
position: fixed;
279-
top: 15px;
280-
left: 15px;
281-
z-index: 1002; /* 사이드바보다 높은 z-index */
282-
background: #0366d6;
283-
color: white;
284-
border: none;
285-
border-radius: 4px;
286-
padding: 8px;
287-
font-size: 16px;
288-
cursor: pointer;
289-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
290-
transition: background-color 0.2s;
291-
}
245+
position: fixed;
246+
top: 15px;
247+
left: 15px;
248+
z-index: 1002;
249+
background: #0366d6;
250+
color: white;
251+
border: none;
252+
border-radius: 4px;
253+
padding: 8px;
254+
font-size: 16px;
255+
cursor: pointer;
256+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
257+
transition: background-color 0.2s;
258+
}
292259
293260
.sidebar-toggle:hover {
294261
background: #0256cc;
295262
}
296263
297-
/* 반응형 디자인 */
298-
@media (max-width: 768px) {
299-
.sidebar-toggle {
300-
top: 10px;
301-
left: 10px;
302-
padding: 6px;
303-
font-size: 14px;
304-
}
305-
}
306-
307-
@media (max-width: 480px) {
308-
.sidebar-toggle {
309-
top: 8px;
310-
left: 8px;
311-
padding: 5px;
312-
font-size: 12px;
313-
}
314-
}
264+
@media (max-width: 768px) {
265+
.sidebar-toggle {
266+
top: 10px;
267+
left: 10px;
268+
padding: 6px;
269+
font-size: 14px;
270+
}
271+
}
272+
273+
@media (max-width: 480px) {
274+
.sidebar-toggle {
275+
top: 8px;
276+
left: 8px;
277+
padding: 5px;
278+
font-size: 12px;
279+
}
280+
}
315281
</style>

0 commit comments

Comments
 (0)