feat(B09): 설계내역서 접히지 않는 트리 — 폴더 줄 수식 · 파일 줄 입력 · 안내선 · 더블클릭 입력 · 고른 줄 상자(235-1)

- 공용 표 editOnDouble — 고칠 칸 = 글 · 더블클릭 · Enter · F2 = 그 칸만 글 상자 · Enter · 초점 떠남 = 입력 끝
- 공용 표 level.tree — ├ └ │ 안내선 + 폴더 · 파일 아이콘(공용 나무와 한 벌 TREE_ICON)
- 설계내역서 — 폴더 줄 금액 = 자손 합 수식 풍선 · 고른 줄 = accent 상자 테두리
- test_235_1 새 시험 · test_228_1 들여쓰기 식 개수 고침

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SE9MxeXTu2uaDZ55BJowAY
This commit is contained in:
2026-10-10 19:09:00 +09:00
co-authored by Claude Opus 5.5
parent 21c1428772
commit 3e70362b14
10 changed files with 580 additions and 27 deletions
+2 -8
View File
@@ -8,6 +8,7 @@
import "./ui_template_tree.css";
import { enterMenu, leaveMenu } from "./ui_template_context_menu";
import { TREE_ICON } from "./ui_template_data_table";
import { el } from "./ui_template_elements";
export interface TreeNode {
@@ -28,13 +29,6 @@ export interface TreeNode {
folder?: boolean;
}
/** 기본 줄 아이콘 — 폴더 · 항목(글꼴색을 따름) */
const ICON = {
folder:
'<svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"><path d="M1.5 3.5h4l1.5 1.5h7.5v8h-13z" fill="none" stroke="currentColor" stroke-linejoin="round"/></svg>',
leaf: '<svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"><path d="M3.5 1.5h6l3 3v10h-9z M9.5 1.5v3h3" fill="none" stroke="currentColor" stroke-linejoin="round"/></svg>',
};
export interface TreeMenuItem {
label: string;
run: () => void;
@@ -130,7 +124,7 @@ export function createTreeRow(
): HTMLButtonElement {
const branch = !!node.children?.length || !!node.folder;
const icon = el("span", { className: "ui-tree__icon" });
icon.innerHTML = branch ? ICON.folder : ICON.leaf; // 고정 SVG 글만
icon.innerHTML = branch ? TREE_ICON.folder : TREE_ICON.leaf; // 고정 SVG 글만
const button = el("button", {
className: `ui-tree__row ui-sidebar-row${branch ? " is-branch" : ""}`,
attrs: { type: "button" },