feat(M02): 면적산출 카드 [알약] 켬끔 — 아래 알약 줄 기본 숨김 · 계정 취향 기억 · 상세는 늘 보임 (PLAN 39-4 D1)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W4uKaV4ZBhsJN4GHG7yRj4
This commit is contained in:
2026-10-04 17:20:47 +09:00
co-authored by Claude Opus 5.5
parent 5cf7c1c5b1
commit 1871b6ffc2
4 changed files with 39 additions and 0 deletions
+2
View File
@@ -62,6 +62,8 @@ export const STATE_REGISTRY = {
/** M02 면적산출 · 재료산출 오른쪽 조합 패널 — 접힘 · 폭 */
"m02-combo-panel-collapsed": { bucket: "pref", scope: "global" },
"m02-combo-panel-width": { bucket: "pref", scope: "global" },
/** M02 면적산출 카드 미리보기 아래 알약 줄 보임(기본 숨김 · 상세는 늘 보임) */
"m02-card-pills": { bucket: "pref", scope: "global" },
/** B05 계획노선 편집 창 — 보던 화면(회전 · 가운데 · 배율). 프로젝트마다 따로 */
"routeedit-view": { bucket: "pref", scope: "project" },
/** B05 계획노선 편집 창 — 시점 · 종점 · 교각점 고정. [저장] 대상이 아니라 draft 에 안 둠 */
@@ -13,6 +13,7 @@
import { createButton, el, showConfirmDialog } from "@ui/ui_template_elements";
import { attachCollapsible } from "@ui/ui_template_collapsible";
import { readStateRaw, writeStateRaw } from "../A00_Common/b_page_state";
import type {
LinkOptions,
SpreadsheetHandle,
@@ -62,6 +63,8 @@ const TEXT = {
readFailed: "{value} 파일을 못 읽음 — {why}",
discard: "카드에 저장 안 한 고침이 있음 — 버리고 다른 항목을 열까요?",
sheetHelp: "단축키 — 칸을 고르고 바로 침",
pills: "알약",
pillsTip: "아래 알약 줄 보임 · 숨김",
};
/** 엑셀 카드 단축키 — 스프레드시트 미리보기(`spreadsheet_keys.ts`)가 받는 것만 */
@@ -221,6 +224,20 @@ export function createItemCards(opts: ItemCardsOptions): ItemCardsHandle {
return card;
};
const sheets = [sheetCard("area"), sheetCard("material")];
// 면적산출 카드 [알약] — 아래 알약 줄 보임 · 숨김(기본 숨김 · 계정 취향 · 상세는 늘 보임)
const pills = createButton({ label: TEXT.pills, variant: "ghost", size: "sm" });
pills.title = TEXT.pillsTip;
const paintPills = (shown: boolean): void => {
pills.setAttribute("aria-pressed", String(shown));
sheets[0].host.classList.toggle("is-pills-off", !shown);
};
pills.addEventListener("click", () => {
const shown = pills.getAttribute("aria-pressed") !== "true";
writeStateRaw("m02-card-pills", String(shown));
paintPills(shown);
});
paintPills(readStateRaw("m02-card-pills") === "true");
sheets[0].shell.tools.prepend(pills);
const cards: Card[] = [info, ...sheets];
const defaults: Record<EditKind, string> = {
structure: TEXT.edit,
@@ -244,6 +261,7 @@ export function createItemCards(opts: ItemCardsOptions): ItemCardsHandle {
c.saver.button.hidden = c.help.hidden = !can;
c.edit.hidden = !opts.editable();
}
pills.hidden = !sheetEdit;
};
const drop = (): void => {
@@ -247,3 +247,8 @@
.m02-struct__sheet-grid .ss-links__list {
max-height: 8rem;
}
/* 면적산출 카드 [알약] 끔(기본) — 아래 알약 줄만 숨김 · 연결 · 칸 세모는 그대로 */
.m02-struct__sheet.is-pills-off .ss-links {
display: none;
}
@@ -75,3 +75,17 @@ def test_저장_안_한_카드_고침_물음():
assert main.count("busy()") >= 3 # 떠나기 · 새로고침 막기 · 나무 고침(settle)
assert main.index("await panel.saveCards();") < main.index("await panel.reload();")
assert "keepColumn: (colId) => sheet?.selectColumn(colId)" in main
def test_면적산출_카드_알약_줄_켬끔_기본_숨김():
cards = _text(M02 / "M02_MasterTemplete_ItemCards.ts")
assert 'paintPills(readStateRaw("m02-card-pills") === "true");' in cards # 없으면 숨김
assert 'writeStateRaw("m02-card-pills", String(shown));' in cards
assert 'sheets[0].host.classList.toggle("is-pills-off", !shown);' in cards
assert "pills.hidden = !sheetEdit;" in cards # 고칠 수 있는 카드만(보기만은 알약 줄 없음)
css = _text(M02 / "M02_MasterTemplete_Structure.css")
assert re.search(r"\.m02-struct__sheet\.is-pills-off \.ss-links \{\s*display: none;", css)
state = _text(ROOT / "A00_Common" / "b_page_state.ts")
assert '"m02-card-pills": { bucket: "pref", scope: "global" },' in state
# 상세(전체 편집기)는 켬끔 없음 — 늘 보임
assert "is-pills-off" not in _text(M02 / "M02_MasterTemplete_UI_Main.ts")