feat(sheet): 칸에 = 로 치면 그 칸만 식(줄.식) · 너비 손잡이를 칸 안으로 · 줄머리 칸 넓힘 (PLAN 10-2)

- master 는 계산 칸도 = 식으로 고침 · 지우면 열 식으로 돌아감 · project 손 열도 = 식 받음
- 너비 손잡이 반쪽이 옆 칸에 가려 안 잡히던 것 고침

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tjoit7rxvpLMM7cafeVTo1
This commit is contained in:
2026-09-25 09:49:45 +09:00
co-authored by Claude Opus 5.5
parent 4d94b6cb96
commit c10f81716f
5 changed files with 21 additions and 10 deletions
+1 -1
View File
@@ -171,7 +171,7 @@
.ui-sheet__resize {
position: absolute;
top: 0;
right: -3px;
right: 0;
z-index: 3;
width: 6px;
height: 100%;
+4 -1
View File
@@ -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 => {
+13 -5
View File
@@ -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;
}
@@ -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;
+2 -2
View File
@@ -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;