fix(M02): 작도 영역을 값이 다 보이는 단추 하나로 — 누르면 칸 넷이 작은 창으로 펼쳐짐

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PxvYb5ufV1kWdBvZbpDfu6
This commit is contained in:
2026-09-25 18:04:27 +09:00
co-authored by Claude Sonnet 5
parent 39c79f05d0
commit ef63904866
2 changed files with 50 additions and 35 deletions
@@ -43,35 +43,24 @@
color: var(--color-text);
}
.m02-drawing__area {
display: flex;
align-items: flex-end;
gap: var(--spacing-4, 4px);
}
.m02-drawing__area {
flex-wrap: wrap;
align-items: center;
}
/* 칸 이름과 입력을 한 줄로 — 세로로 쌓지 않는다. */
.m02-drawing__area .ui-field {
flex-direction: row;
align-items: center;
gap: var(--spacing-4, 4px);
width: auto;
}
.m02-drawing__area .ui-field input {
width: 3rem;
padding-block: 2px;
}
.m02-drawing__area .ui-field label {
font-size: 0.72rem;
.m02-drawing__areabtn {
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
.m02-drawing__areabtn.is-invalid {
border-color: var(--color-danger);
color: var(--color-danger);
}
/* 작은 창 안 칸 넷 — 이름이 다 보이는 넉넉한 폭 */
.m02-drawing__areaform {
display: grid;
grid-template-columns: repeat(2, minmax(9rem, 1fr));
gap: var(--spacing-12);
min-width: min(22rem, 80vw);
}
.m02-drawing__toolbar--slot {
flex: 1 1 0;
min-width: 0;
@@ -14,6 +14,7 @@ import "./M02_MasterTemplete_Drawing.css";
import { API_BASE_URL } from "@config/config_frontend";
import { createCadHost, type CadHostDrawing } from "@ui/cad_host/cad_host";
import { createButton, createInputField, showToast } from "@ui/ui_template_elements";
import { openModal } from "@ui/ui_template_modal";
/** 도면 양식 문서 — 작도 영역은 [x0, y0, x1, y1] (양식 좌표 mm). */
export interface DrawingTemplateDoc extends CadHostDrawing {
@@ -73,7 +74,7 @@ export interface DrawingTemplateHandle {
/** 작도 영역 칸이 없는 양식이 쓰는 값 — 서버 `Engine_Template._A1_INNER` 와 같다. */
const DEFAULT_AREA: [number, number, number, number] = [42, 47, 812, 567];
const AREA_LABELS = ["왼x", "아래y", "오른x", "위y"];
const AREA_LABELS = ["왼쪽 x", "아래 y", "오른쪽 x", "위 y"];
async function importDrawingFile(
file: File,
@@ -109,25 +110,49 @@ export function mountDrawingTemplate(
const toolbar = document.createElement("div");
toolbar.className = "m02-drawing__toolbar";
// 작도 영역 — 도면 내용이 이 칸 한가운데에 놓인다.
const area = document.createElement("div");
area.className = "m02-drawing__area";
// 작도 영역 — 도면 내용이 이 칸 한가운데에 놓인다. 제목 줄에는 값이 다 보이는 단추 하나,
// 누르면 칸 넷이 작은 창으로 펼쳐진다(칸은 창을 닫아도 그대로 살아 있음).
const areaForm = document.createElement("div");
areaForm.className = "m02-drawing__areaform";
const start = doc.drawing_area ?? DEFAULT_AREA;
const areaInputs = AREA_LABELS.map((label, index) => {
const field = createInputField({ label, type: "number", value: String(start[index]) });
field.input.disabled = readOnly;
field.input.addEventListener("input", () => options.onChanged?.(true));
field.input.addEventListener("input", () => {
options.onChanged?.(true);
readArea();
});
return field;
});
area.title = "작도 영역 — 도면 내용이 놓이는 칸(양식 좌표 mm)";
area.append(...areaInputs.map((field) => field.root));
areaForm.append(...areaInputs.map((field) => field.root));
const areaButton = createButton({ label: "", variant: "ghost" });
areaButton.classList.add("m02-drawing__areabtn");
areaButton.title = "작도 영역 — 도면 내용이 놓이는 칸(양식 좌표 mm) · 눌러서 고침";
let areaModal: { close: () => void } | null = null;
const readArea = (): [number, number, number, number] | null => {
const values = areaInputs.map((field) => Number(field.input.value));
const valid = values.every(Number.isFinite) && values[0] < values[2] && values[1] < values[3];
const valid =
areaInputs.every((field) => field.input.value.trim() !== "") &&
values.every(Number.isFinite) &&
values[0] < values[2] &&
values[1] < values[3];
areaInputs.forEach((field) => field.setError(valid ? undefined : "왼쪽<오른쪽 · 아래<위"));
areaButton.textContent = `작도 영역 ${areaInputs.map((f) => f.input.value.trim() || "?").join(" · ")}`;
areaButton.classList.toggle("is-invalid", !valid);
return valid ? (values as [number, number, number, number]) : null;
};
readArea();
areaButton.addEventListener("click", () => {
areaModal?.close();
areaModal = openModal({
title: "작도 영역",
closeLabel: "닫기",
dialogClass: "m02-modal",
mount: (body) => body.append(areaForm),
});
});
// CAD 안 💾 · Ctrl+S — 양식 파일은 페이지 [저장] 만 쓴다. 저장 중 또 눌러도 한 번만 부른다.
let saving = false;
@@ -203,7 +228,7 @@ export function mountDrawingTemplate(
};
// 한 줄 — 페이지가 머리 칸(headerSlot)을 주면 거기, 아니면 그림 칸 위에 작게.
toolbar.append(area, actions);
toolbar.append(areaButton, actions);
if (options.headerSlot) {
toolbar.classList.add("m02-drawing__toolbar--slot");
options.headerSlot.append(toolbar);
@@ -215,6 +240,7 @@ export function mountDrawingTemplate(
return {
getDoc,
destroy: () => {
areaModal?.close();
cad.destroy();
toolbar.remove();
root.remove();