From a552bfd444ee1bfbaf2463ab47c277d84be5916c Mon Sep 17 00:00:00 2001 From: umsangdon Date: Tue, 8 Sep 2026 18:34:29 +0900 Subject: [PATCH] =?UTF-8?q?fix(ui):=20=EC=95=84=EC=A3=BC=20=EC=A2=81?= =?UTF-8?q?=EC=9D=80=20=ED=8F=AD=EC=97=90=EC=84=9C=EB=8A=94=20=EC=A2=8C?= =?UTF-8?q?=ED=8C=A8=EB=84=90=EC=9D=84=20=EC=A4=84=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EB=A7=90=EA=B3=A0=20=EC=A0=91=EC=9D=80=20=EC=B1=84=EB=A1=9C=20?= =?UTF-8?q?=EC=8B=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ⚠ 앞 커밋의 「본문에 320 을 남긴다」가 폭 500 에서 패널을 **180px 로 눌러** 목록 이름이 잘렸음(랩탑 보조 실측: 잘린 이름 2건). 폭을 반씩 나누면 **둘 다 못 쓰는 화면**이 됨. - CSS ≤560 — 패널을 **안 줄임**(280px 유지). 본문 밀기는 이미 ≤860 에서 꺼져 있어 패널이 **본문 위에 겹쳐** 뜨고, 읽을 때는 손잡이로 접음. 폭 500 에서 잘린 글자 0. - TS — 정한 적이 없고 화면이 아주 좁으면(≤560) **접은 채로 시작**함. 펼친 채로 열면 본문이 가려진 화면부터 보게 되기 때문임. - ⚠ **사용자가 정한 적이 있으면 그 뜻이 이김** — 저장값이 있으면 그대로 따름. - ⚠ **처음 앉힐 때는 저장하지 않음** — 좁아서 접은 것을 「사용자가 접었다」로 적으면 넓은 화면으로 돌아와도 접힌 채로 남음. 실측 정한 적 없음 + 500 → 접힘 true · 저장값 null (기록 안 남김) 정한 적 없음 + 1400 → 접힘 false · 저장값 null 「펼침」 정해 둠 + 500 → 접힘 false (사용자 뜻이 이김) 잘린 글자 860·620·560·500 전부 0 Co-Authored-By: Claude Opus 5 (1M context) --- ui_template/ui_template_overlay.css | 10 ++++++++++ ui_template/ui_template_overlay.ts | 25 ++++++++++++++++++++----- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/ui_template/ui_template_overlay.css b/ui_template/ui_template_overlay.css index f95397ff..236f5941 100644 --- a/ui_template/ui_template_overlay.css +++ b/ui_template/ui_template_overlay.css @@ -81,6 +81,16 @@ } } +/* ⚠ 아주 좁은 폭(≤560)에서는 **줄이지 않는다** — 본문 320 을 남기려다 패널이 180px + 까지 눌려 목록 이름이 잘렸다(2026-09-08 랩탑 보조 실측: 폭 500 에서 잘린 이름 2건). + 폭을 반씩 나누면 **둘 다 못 쓰는 화면**이 되므로, 패널은 쓸 만한 폭을 지키고 + **본문 위에 겹쳐** 뜬다(본문 밀기는 이미 ≤860 에서 꺼져 있다). 읽을 때는 손잡이로 접는다. */ +@media (max-width: 560px) { + .ui-workflow-overlay__panel--title { + width: min(var(--wf-left-panel-narrow-width), calc(100vw - var(--spacing-48))); + } +} + .ui-workflow-overlay__panel--progress .ui-workflow-overlay__header { cursor: move; touch-action: none; diff --git a/ui_template/ui_template_overlay.ts b/ui_template/ui_template_overlay.ts index 3fe0881b..9d1dfccc 100644 --- a/ui_template/ui_template_overlay.ts +++ b/ui_template/ui_template_overlay.ts @@ -84,8 +84,21 @@ export function createWorkflowPanelHandle( return { root, setOpen }; } -function readOpenState(key: string): boolean { - return readByKey(key) !== "false"; +/** 좌측 패널을 **접은 채로 시작**하는 폭 — `ui_template_overlay.css` 의 560 과 짝이다. */ +const NARROW_START_COLLAPSED_MAX_PX = 560; + +/** + * 처음 열 때 펼쳐 둘지. + * + * ⚠ **사용자가 정한 적이 있으면 그 뜻이 이긴다** — 저장값이 있으면 그대로 따른다. + * 정한 적이 없고 화면이 아주 좁으면 **접은 채로 시작**한다. 그 폭에서는 패널이 본문 + * 위에 겹쳐 떠서, 펼친 채로 열면 본문이 가려진 화면부터 보게 된다(2026-09-08). + */ +function readOpenState(key: string, collapseWhenNarrow = false): boolean { + const raw = readByKey(key); + if (raw !== null) return raw !== "false"; + if (!collapseWhenNarrow) return true; + return window.innerWidth > NARROW_START_COLLAPSED_MAX_PX; } /** @@ -183,7 +196,7 @@ function createPanel( let dragHandle: { refresh: () => void } | null = null; - function setOpen(isOpen: boolean): void { + function setOpen(isOpen: boolean, persist = true): void { root.classList.toggle("is-collapsed", !isOpen); if (panelHandle) panelHandle.setOpen(isOpen); else { @@ -192,7 +205,9 @@ function createPanel( toggle.setAttribute("aria-label", toggle.title); toggle.setAttribute("aria-expanded", String(isOpen)); } - writeByKey(storageKey, String(isOpen)); + // ⚠ 처음 앉힐 때는 저장하지 않는다 — 좁아서 접어 둔 것을 「사용자가 접었다」로 + // 적으면 넓은 화면으로 돌아와도 접힌 채로 남는다. + if (persist) writeByKey(storageKey, String(isOpen)); // 펼친 뒤에는 아래 공간이 모자랄 수 있다 — 열리는 방향을 다시 잡는다. if (dragHandle) requestAnimationFrame(() => dragHandle?.refresh()); onOpenChange?.(isOpen); @@ -212,7 +227,7 @@ function createPanel( } }); toggle.addEventListener("click", toggleOpen); - setOpen(readOpenState(storageKey)); + setOpen(readOpenState(storageKey, isSidebar), false); // 진행단계 패널만 사용자가 자리를 옮긴다(제목 패널은 좌측 도킹 사이드바). if (variant === "progress") { dragHandle = makePanelDraggable(root, header, PROGRESS_OVERLAY_POSITION_KEY);