From c10f81716f0f0aed76a6992e8cdfbb4192b5fa83 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Fri, 25 Sep 2026 09:49:45 +0900 Subject: [PATCH] =?UTF-8?q?feat(sheet):=20=EC=B9=B8=EC=97=90=20=3D=20?= =?UTF-8?q?=EB=A1=9C=20=EC=B9=98=EB=A9=B4=20=EA=B7=B8=20=EC=B9=B8=EB=A7=8C?= =?UTF-8?q?=20=EC=8B=9D(=EC=A4=84.=EC=8B=9D)=20=C2=B7=20=EB=84=88=EB=B9=84?= =?UTF-8?q?=20=EC=86=90=EC=9E=A1=EC=9D=B4=EB=A5=BC=20=EC=B9=B8=20=EC=95=88?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=C2=B7=20=EC=A4=84=EB=A8=B8=EB=A6=AC=20?= =?UTF-8?q?=EC=B9=B8=20=EB=84=93=ED=9E=98=20(PLAN=2010-2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - master 는 계산 칸도 = 식으로 고침 · 지우면 열 식으로 돌아감 · project 손 열도 = 식 받음 - 너비 손잡이 반쪽이 옆 칸에 가려 안 잡히던 것 고침 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Tjoit7rxvpLMM7cafeVTo1 --- ui_template/sheet/ui_template_sheet.css | 2 +- ui_template/sheet/ui_template_sheet.ts | 5 ++++- ui_template/sheet/ui_template_sheet_ops.ts | 18 +++++++++++++----- ui_template/sheet/ui_template_sheet_render.ts | 2 +- ui_template/sheet/ui_template_sheet_text.ts | 4 ++-- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/ui_template/sheet/ui_template_sheet.css b/ui_template/sheet/ui_template_sheet.css index 2390fd79..8255b423 100644 --- a/ui_template/sheet/ui_template_sheet.css +++ b/ui_template/sheet/ui_template_sheet.css @@ -171,7 +171,7 @@ .ui-sheet__resize { position: absolute; top: 0; - right: -3px; + right: 0; z-index: 3; width: 6px; height: 100%; diff --git a/ui_template/sheet/ui_template_sheet.ts b/ui_template/sheet/ui_template_sheet.ts index 33c55e15..6545381b 100644 --- a/ui_template/sheet/ui_template_sheet.ts +++ b/ui_template/sheet/ui_template_sheet.ts @@ -169,7 +169,10 @@ export function createSheet(host: HTMLElement, input: SheetDoc, opts: SheetOptio if (key === "s:formula") return col.식 ?? ""; if (key === "s:desc") return col.설명 ?? ""; if (key === "s:price") return col.일위대가 ?? ""; - const raw = state.doc.줄.find((r) => `d:${r.id}` === key)?.값[col.id]; + const row = state.doc.줄.find((r) => `d:${r.id}` === key); + const formula = row?.식?.[col.id] ?? col.식; + if (formula) return `=${formula}`; + const raw = row?.값[col.id]; return raw === null || raw === undefined ? "" : String(raw); }; const write = (key: string, col: SheetColumn, text: string): void => { diff --git a/ui_template/sheet/ui_template_sheet_ops.ts b/ui_template/sheet/ui_template_sheet_ops.ts index ebf1e309..e9f1d59e 100644 --- a/ui_template/sheet/ui_template_sheet_ops.ts +++ b/ui_template/sheet/ui_template_sheet_ops.ts @@ -27,11 +27,10 @@ export function orderedRows(doc: SheetDoc): SheetRow[] { export const isCalcColumn = (col: SheetColumn): boolean => !!col.식; export const isBoundColumn = (col: SheetColumn): boolean => !!col.바인딩; -/** 본문 칸을 고칠 수 있나 — master 는 계산 열 밖 전부 · project 는 손 열만(+ 사용자가 더한 줄의 글 열). */ +/** 본문 칸을 고칠 수 있나 — master 는 전부(계산 칸은 `=` 식으로) · project 는 손 열만(+ 사용자가 더한 줄의 글 열). */ export function cellEditable(mode: SheetMode, col: SheetColumn, row: SheetRow): boolean { - if (row.식?.[col.id] || isCalcColumn(col)) return false; if (mode === "master") return true; - if (isBoundColumn(col)) return false; + if (isBoundColumn(col) || isCalcColumn(col)) return false; return !!col.손 || (!!row.손 && col.꼴 === "글"); } @@ -85,12 +84,21 @@ export function deleteColumn(doc: SheetDoc, id: string): void { if (doc.보기?.열너비) delete doc.보기.열너비[id]; } -/** 칸에 친 글 → 저장 값. 수 열은 수 꼴이면 수 · 빈 글은 칸을 비움. */ +/** 칸에 친 글 → 저장 값. `=` 로 시작하면 그 칸만의 식(`줄.식`) · 수 열은 수 꼴이면 수 · 빈 글은 칸을 비움. */ export function setCell(doc: SheetDoc, rowId: string, col: SheetColumn, text: string): void { const row = doc.줄.find((r) => r.id === rowId); if (!row) return; const trimmed = text.trim(); - if (trimmed === "") { + if (row.식) { + delete row.식[col.id]; + if (!Object.keys(row.식).length) delete row.식; + } + if (trimmed.startsWith("=") && trimmed.slice(1).trim() !== (col.식 ?? "")) { + delete row.값[col.id]; + (row.식 ??= {})[col.id] = trimmed.slice(1).trim(); + return; + } + if (trimmed === "" || trimmed.startsWith("=")) { delete row.값[col.id]; return; } diff --git a/ui_template/sheet/ui_template_sheet_render.ts b/ui_template/sheet/ui_template_sheet_render.ts index 816130f8..25f9ddb0 100644 --- a/ui_template/sheet/ui_template_sheet_render.ts +++ b/ui_template/sheet/ui_template_sheet_render.ts @@ -22,7 +22,7 @@ import type { SheetColumn, SheetDoc, SheetResult, SheetRow } from "./ui_template export const KEY_UNIT = "s:unit"; const MASTER_ROWS = ["s:formula", "s:desc", "s:price"] as const; -const GUTTER = 48; +const GUTTER = 64; const DEFAULT_WIDTH = { 수: 72, 글: 96 }; const PAGE_ROWS = 50; diff --git a/ui_template/sheet/ui_template_sheet_text.ts b/ui_template/sheet/ui_template_sheet_text.ts index d830c843..37ac1a63 100644 --- a/ui_template/sheet/ui_template_sheet_text.ts +++ b/ui_template/sheet/ui_template_sheet_text.ts @@ -23,8 +23,8 @@ const TEXT = { Page: ["쪽", "page"], Error: ["#오류", "#ERR"], Hint: [ - "칸을 누르고 바로 치거나 Enter · F2 로 고침 · 화살표 · Tab 으로 옮김 · Delete 로 비움", - "Type or press Enter / F2 to edit · arrows / Tab to move · Delete to clear", + "칸을 누르고 바로 치거나 Enter · F2 로 고침 · = 로 시작하면 그 칸만 식 · 화살표 · Tab 으로 옮김 · Delete 로 비움", + "Type or press Enter / F2 to edit · start with = for a cell formula · arrows / Tab to move · Delete to clear", ], } as const;