feat(M02): 구조물 조합 카드 셋 3열 · 단추 「가져오기」 · 「수정」 · 「새 항목」 공용 버튼 크기

40-2 ①~③ — 상세 칸 960px 아래 1열(상세 칸 폭 container query) · 카드 [수정] 툴팁에 무엇을 고치는지 · 「새 항목」 = 저장과 같은 크기.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016PSXsvyDxjNmufteN5bqmt
This commit is contained in:
2026-10-04 22:26:00 +09:00
co-authored by Claude Opus 5.5
parent 68817d7175
commit 74a524202e
5 changed files with 21 additions and 14 deletions
@@ -56,10 +56,10 @@ export const PART_WORD: Record<CardKind, string> = {
const TEXT = {
drawingInfo: "도면 정보",
edit: "도면 수정",
edit: "수정", // 카드 셋 같은 글(40-2) — 무엇을 고치는지는 툴팁
noNumber: "도번 없음",
noDrawing: "도면 없음",
editSheet: "{value} 수정",
editTip: "{value} 수정 — 전체 편집 화면",
noSheetDoc: "{value} 없음",
noFieldNumber: "{value} 없음",
noSheet: "스프레드시트를 못 띄움 — {value}",
@@ -68,7 +68,7 @@ const TEXT = {
sheetHelp: "단축키 — 칸을 고르고 바로 침",
pills: "알약",
pillsTip: "아래 알약 줄 보임 · 숨김",
take: "복사해 가져오기",
take: "가져오기",
takeTip: "다른 항목의 {value} 을(를) 골라 이 칸에 덮어씀 — 번호 · 열은 그대로",
blank: "비어 있음 — 새로 만들거나 다른 항목에서 복사해 옴",
makeNew: "새로 만들기",
@@ -209,10 +209,11 @@ export function createItemCards(opts: ItemCardsOptions): ItemCardsHandle {
kind === "structure" ? DRAWING_KEYS : SHEET_KEYS,
);
const edit = createButton({
label: kind === "structure" ? TEXT.edit : fill(TEXT.editSheet, PART_WORD[kind]),
label: TEXT.edit,
variant: "ghost",
size: "sm",
});
edit.title = fill(TEXT.editTip, PART_WORD[kind]);
edit.addEventListener("click", () => (kind === "labor" ? opts.labor?.() : opts.onEdit(kind)));
const take = createButton({ label: TEXT.take, variant: "ghost", size: "sm" });
take.title = fill(TEXT.takeTip, PART_WORD[kind]);
@@ -325,8 +326,8 @@ export function createItemCards(opts: ItemCardsOptions): ItemCardsHandle {
const cards: Card[] = [info, ...(laborCard ? [laborCard] : []), ...sheets];
const defaults: Record<CardKind, string> = {
structure: TEXT.edit,
area: fill(TEXT.editSheet, PART_WORD.area),
labor: fill(TEXT.editSheet, PART_WORD.labor),
area: TEXT.edit,
labor: TEXT.edit,
};
const root = el("div", {
@@ -1,4 +1,4 @@
/* M02 구조물집계표 아래 설계 컨테이너 — 카드 셋(도면 정보 · 면적산출 · 재료산출) ·
/* M02 구조물집계표 아래 설계 컨테이너 — 카드 셋(도면 정보 · 일위대가 · 면적산출) ·
카드 모양은 좌측 패널과 같은 공용 ui-sidebar-*(ui_template_overlay.css). */
/* 표 밖 형제 자리 — 비어 있을 때 메인 간격이 벌어지지 않게 칸을 지움. */
@@ -6,8 +6,8 @@
display: contents;
}
/* 카드 넷(도면 정보 · 면적산출 · 재료산출 · 선택 입력) = 2행 2열 · 카드 높이 = 화면 높이에 맞춰 크게(PLAN 31-6) ·
칸이 좁으면(720px 아래) 1열 */
/* 카드 셋(도면 정보 · 일위대가 · 면적산출) = 1행 3열(40-2) · 카드 높이 = 화면 높이에 맞춰 크게(PLAN 31-6) ·
상세 칸이 좁으면 1열 */
.m02-struct {
/* 카드 본문은 카드 높이를 채움 — 넘치면 카드 안에서 스크롤 */
--m02-struct-body-min: 0;
@@ -17,13 +17,19 @@
display: grid;
flex: none;
grid-auto-rows: var(--m02-struct-card-h);
grid-template-columns: repeat(2, minmax(0, 1fr));
grid-template-columns: repeat(3, minmax(0, 1fr)); /* 도면 · 일위대가 · 면적산출(40-2) */
padding-top: var(--spacing-12);
border-top: 1px solid var(--color-border);
min-width: 0;
}
@media (max-width: 720px) {
/* 상세 칸이 좁으면(카드 하나 300px 아래) 1열 — 좌측 패널을 접어도 맞게 상세 칸 폭으로 잼
(카드 자리 `m02-main__extra` 는 상자 없음 — 상세 칸이 잣대) */
.m02-main:has(> .m02-main__extra > .m02-struct) {
container-type: inline-size;
}
@container (max-width: 960px) {
.m02-struct {
grid-template-columns: minmax(0, 1fr);
}
@@ -113,7 +113,7 @@ export interface MainExtras {
/** 상세 제목 줄 오른쪽 끝 「새 …」 단추 — 공용 모양 `m02-main__new`(일위대가 「새 조합」과 같게 · 30-5) */
export function newItemButton(run: () => void, label = L("M02_TreeNewItem")): HTMLElement {
const button = createButton({ label, variant: "filled", size: "sm" });
const button = createButton({ label, variant: "filled" }); // 공용 버튼 크기(40-2 · 저장과 같음)
button.classList.add("m02-main__new");
button.addEventListener("click", run);
return button;