refactor(ui): 사이드 패널을 [스크롤 영역][고정 액션 영역]으로 분리
sticky + margin-top:auto 조합은 본문 높이가 패널 높이를 넘나들 때마다 액션 줄이 붙었다 떨어졌다 했다(2026-08-18 사용자 보고). 액션 줄을 스크롤 대상에서 아예 빼는 구조로 바꾼다. - overlay.ts: 사이드 패널 생성 시 본문의 `.ui-sidebar-actions` 앞 형제들을 마진·패딩 없는 `.ui-sidebar-scroll` 래퍼로 옮기고 body에 `ui-sidebar-split`을 붙인다. 페이지 코드는 지금처럼 본문 끝에 액션 줄을 붙이기만 하면 된다. - overlay.css: split body = 세로 플렉스 + overflow hidden + padding-bottom 0, 스크롤 래퍼 = flex:1/min-height:0/overflow-y:scroll + gap:inherit(그룹 간격 유지), 액션 줄 = flex:none(sticky·margin-top 제거). - B08: 전용 sticky 규칙을 버리고 공용 ui-sidebar-actions로 통합 — B04~B08이 한 규칙. 스크롤바 자리 상시 예약(2026-08-17)은 래퍼가 이어받아 내용 폭은 그대로다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -510,9 +510,9 @@ export async function renderB08DesignDetail(root: HTMLElement): Promise<void> {
|
||||
);
|
||||
drawingListEl = drawingPanel;
|
||||
const confirmActions = document.createElement("div");
|
||||
// b08-drawing-actions는 자체 sticky 하단 고정(B08 Style.css) — 공용 ui-sidebar-actions와
|
||||
// 같은 동작이라 중복 적용하지 않는다(2026-08-05 확인).
|
||||
confirmActions.className = "b08-drawing-actions";
|
||||
// 하단 고정은 공용 ui-sidebar-actions로 통일 — 사이드 본문이 [스크롤 영역][액션 줄]로
|
||||
// 쪼개지고 액션 줄은 스크롤 밖에 남는다(2026-08-18 사용자 지시, B04~B08 공통).
|
||||
confirmActions.className = "b08-drawing-actions ui-sidebar-actions";
|
||||
confirmActions.append(confirmButton);
|
||||
|
||||
drawingPanel.append(infoPanelHost, confirmActions);
|
||||
|
||||
@@ -113,12 +113,10 @@
|
||||
color: var(--color-success);
|
||||
}
|
||||
|
||||
/* 하단 고정·배경·상단 구분선은 공용 ui-sidebar-actions가 맡는다(2026-08-18 통합).
|
||||
여기서는 B08 고유 여백만 남긴다. */
|
||||
.b08-drawing-actions {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
margin-top: auto;
|
||||
padding-top: var(--spacing-12);
|
||||
background: var(--color-surface-raised);
|
||||
}
|
||||
|
||||
.b08-drawing-actions > button {
|
||||
|
||||
@@ -232,31 +232,48 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* 사이드 패널 최하단 고정 액션 줄(계산·확정 버튼) — 스크롤에서 제외된다.
|
||||
B04·B05·B06·B07 공통(2026-08-05 사용자 지시). 스크롤로 지나가는 다른 버튼·내용이
|
||||
틈으로 노출되지 않게 불투명 배경 + 사이드 body의 하단 패딩(16px)까지 덮는다. */
|
||||
/* 사이드 패널 최하단 고정 액션 줄(계산·확정 버튼) — B04~B08 공통(2026-08-05 사용자
|
||||
지시). 스크롤 영역(.ui-sidebar-scroll) 바깥의 형제라 자리가 흔들리지 않는다
|
||||
(2026-08-18 개편 — sticky로만 붙이던 때는 본문 높이가 패널 높이를 넘나들 때마다
|
||||
붙었다 떨어졌다 했다). 스크롤로 지나가는 내용이 틈으로 비치지 않게 배경은 불투명. */
|
||||
.ui-sidebar-actions {
|
||||
position: sticky;
|
||||
bottom: calc(-1 * var(--spacing-16));
|
||||
z-index: 5;
|
||||
flex: none;
|
||||
display: flex;
|
||||
gap: var(--spacing-8);
|
||||
/* 내용이 패널보다 짧아도 액션 줄은 패널 최하단에 붙는다 — 위 여백을 이 줄이
|
||||
전부 먹는다(2026-08-18 사용자 지시, B04~B08 공통). 내용이 길면 auto가 0이 돼
|
||||
기존처럼 sticky로 따라온다. */
|
||||
margin-top: auto;
|
||||
padding: var(--spacing-8) 0 var(--spacing-16);
|
||||
background: var(--color-surface-raised);
|
||||
border-top: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
/* margin-top:auto가 먹히려면 액션 줄을 담은 사이드 body가 세로 플렉스여야 하고
|
||||
높이가 정해져 있어야 한다(--panel--title의 body는 flex:1로 이미 정해진다).
|
||||
B04·B05·B06은 페이지 CSS가 이미 세로 플렉스지만, 규칙 없이 블록으로 남은
|
||||
패널(B07)도 같이 걸리게 여기서 공통으로 준다. */
|
||||
.ui-workflow-overlay__body:has(> .ui-sidebar-actions) {
|
||||
/* 액션 줄이 있는 사이드 body는 [스크롤 영역][액션 줄] 두 칸(overlay.ts가 래퍼를
|
||||
끼운다). body 자신은 스크롤하지 않는다 — 스크롤은 안쪽 래퍼 몫. */
|
||||
.ui-workflow-overlay__body.ui-sidebar-split {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
/* 액션 줄이 바닥까지 내려온다 — 아래 여백은 액션 줄 자신의 패딩(16px)이 만든다. */
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
/* 마진·패딩 없는 순수 스크롤 래퍼. 그룹 간격(gap)은 페이지가 body에 준 값을 그대로
|
||||
물려받아 기존 간격이 유지된다. */
|
||||
.ui-sidebar-split > .ui-sidebar-scroll {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: inherit;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow-y: scroll;
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
|
||||
/* 스크롤은 안쪽 래퍼가 맡으므로 body 자신의 상시 스크롤(위 --panel--title 규칙)은
|
||||
끈다. 오른쪽 패딩 보정(-8px)은 그대로 둔다 — 래퍼가 그 폭 안에서 스크롤바 자리를
|
||||
예약하므로 내용 폭은 개편 전과 같다. */
|
||||
.ui-workflow-overlay__panel--title > .ui-workflow-overlay__body.ui-sidebar-split {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.ui-sidebar-actions > * {
|
||||
|
||||
@@ -81,6 +81,25 @@ function readOpenState(key: string): boolean {
|
||||
return sessionStorage.getItem(key) !== "false";
|
||||
}
|
||||
|
||||
/**
|
||||
* 사이드 패널 본문을 [스크롤 영역][고정 액션 영역] 두 칸으로 쪼갠다.
|
||||
*
|
||||
* 액션 줄(`.ui-sidebar-actions`)을 sticky로만 붙여 두면 본문 높이가 패널 높이를
|
||||
* 넘나들 때마다 자리가 흔들린다(2026-08-18 사용자 보고). 액션 줄을 스크롤 대상에서
|
||||
* 아예 빼고, 나머지 그룹만 마진·패딩 없는 래퍼(`.ui-sidebar-scroll`)에 담아 그쪽만
|
||||
* 스크롤시킨다. 페이지는 지금처럼 본문 마지막에 액션 줄을 붙이기만 하면 된다.
|
||||
*/
|
||||
function splitSidebarActions(body: HTMLElement): void {
|
||||
const actions = body.querySelector<HTMLElement>(":scope > .ui-sidebar-actions");
|
||||
if (!actions) return;
|
||||
const scroll = document.createElement("div");
|
||||
scroll.className = "ui-sidebar-scroll";
|
||||
// 액션 줄 앞의 형제만 옮긴다 — 뒤에 붙은 요소(없어야 정상)는 그대로 둔다.
|
||||
while (body.firstChild && body.firstChild !== actions) scroll.append(body.firstChild);
|
||||
body.prepend(scroll);
|
||||
body.classList.add("ui-sidebar-split");
|
||||
}
|
||||
|
||||
function createPanel(
|
||||
variant: "title" | "progress",
|
||||
titleText: string,
|
||||
@@ -115,6 +134,7 @@ function createPanel(
|
||||
}
|
||||
if (body.childElementCount > 0) {
|
||||
body.classList.add("ui-workflow-overlay__body");
|
||||
if (isSidebar) splitSidebarActions(body);
|
||||
root.append(body);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user