spreadsheet_sheet_extra.ts 새로 만듦 — 시트 관리 창(숨김 토글·탭 색 고르기), 마지막 보이는 시트는 숨김 거절, 활성 시트를 숨기면 다른 시트로 옮김. 계약(spreadsheet_types.ts)에 Sheet.숨김·탭색 최소로 더함(git-sync 뒤 더함) · 파일 목록 표에 이번 셋(상태 표시줄·자동 합계·시트 여분) 적음 · css(spreadsheet_stage3.css)에 세 파일 스타일 얹음. 엔진 A·격자 C 안 건드림 — 탭 줄(spreadsheet_tabs.ts) 이음은 sub7 몫(머리 주석에 적음). 시험 resources/tester/spreadsheet/test_stage3_sheet_extra.ts 9개 통과. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EUypcnp5d1gU2aeKh9F2H7
114 lines
4.7 KiB
TypeScript
114 lines
4.7 KiB
TypeScript
/* =============================================================================
|
|
* spreadsheet_sheet_extra.ts (3단계 · 주인 sub_laptop_4)
|
|
* 시트 숨기기 · 보이기 · 시트 탭 색. 저장 자리 `Sheet.숨김` · `Sheet.탭색`(0 계약에 방금 더함).
|
|
* 이 파일은 관리 창(전체 시트 목록 + 숨김 · 색 조작)만 그림 — 실제 탭 줄(`spreadsheet_tabs.ts`,
|
|
* E 파일)을 안 건드림.
|
|
*
|
|
* 잇는 법(E `spreadsheet_tabs.ts` · sub7 — 지금은 하나도 안 이어짐):
|
|
* 1) `mountTabs` 의 `render()` 가 `ctx.book.시트` 를 돌 때 `숨김` 인 시트는 탭을 안 그림.
|
|
* 2) 탭 엘리먼트에 `sheet.탭색` 이 있으면 밑줄 · 배경을 그 색으로(엑셀처럼).
|
|
* 3) 숨은 시트를 다시 보이려면 탭 우클릭 메뉴에 [숨긴 시트 보이기] 항목을 두고 이 파일의
|
|
* `createSheetExtraPanel(ctx)` 를 열거나, `showSheet(ctx, id)` 를 바로 부름.
|
|
* ========================================================================== */
|
|
|
|
import { createButton, el } from "@ui/ui_template_elements";
|
|
import type { Sheet } from "./spreadsheet_types";
|
|
import type { PartHandle, SpreadsheetContext } from "./spreadsheet_view_types";
|
|
|
|
// css 는 stage3.css 에 얹음(잇는 법 머리 참고) — 실제로 붙일 때 `import "./spreadsheet_stage3.css";` 더함.
|
|
|
|
function applySheet(ctx: SpreadsheetContext, sheetId: string, next: Sheet): void {
|
|
ctx.dispatch({ 종류: "시트통째", 시트: { ...next, id: sheetId } });
|
|
}
|
|
|
|
/** 시트를 숨김 — 마지막 보이는 시트는 못 숨김(까닭 글 돌려줌 · 되면 null). 활성 시트를 숨기면
|
|
* 다른 보이는 시트로 활성을 옮김. */
|
|
export function hideSheet(ctx: SpreadsheetContext, id: string): string | null {
|
|
const others = ctx.book.시트.filter((s) => s.id !== id && !s.숨김);
|
|
if (!others.length) return "마지막 보이는 시트는 못 숨김";
|
|
const sheet = ctx.book.시트.find((s) => s.id === id);
|
|
if (!sheet || sheet.숨김) return null;
|
|
applySheet(ctx, id, { ...sheet, 숨김: true });
|
|
if (ctx.book.활성 === id) ctx.showSheet(others[0].id);
|
|
return null;
|
|
}
|
|
|
|
/** 숨긴 시트를 다시 보임. */
|
|
export function unhideSheet(ctx: SpreadsheetContext, id: string): void {
|
|
const sheet = ctx.book.시트.find((s) => s.id === id);
|
|
if (!sheet || !sheet.숨김) return;
|
|
applySheet(ctx, id, { ...sheet, 숨김: false });
|
|
}
|
|
|
|
/** 탭 색 — `color` 가 null 이면 색을 지움(기본 탭 색으로). */
|
|
export function setSheetTabColor(ctx: SpreadsheetContext, id: string, color: string | null): void {
|
|
const sheet = ctx.book.시트.find((s) => s.id === id);
|
|
if (!sheet) return;
|
|
const next: Sheet = { ...sheet };
|
|
if (color) next.탭색 = color;
|
|
else delete next.탭색;
|
|
applySheet(ctx, id, next);
|
|
}
|
|
|
|
/** 시트 관리 창 — 전체 시트 목록 + 숨김 토글 · 탭 색 고르기. */
|
|
export function createSheetExtraPanel(ctx: SpreadsheetContext): PartHandle {
|
|
const root = el("div", { className: "ss-sheetextra" });
|
|
const list = el("ul", { className: "ss-sheetextra__list" });
|
|
let error: HTMLElement | null = null;
|
|
|
|
const showError = (msg: string | null): void => {
|
|
error?.remove();
|
|
error = null;
|
|
if (!msg) return;
|
|
error = el("p", { text: msg });
|
|
error.style.color = "var(--color-danger, red)";
|
|
root.append(error);
|
|
};
|
|
|
|
function render(): void {
|
|
list.replaceChildren(
|
|
...ctx.book.시트.map((sheet) => {
|
|
const li = el("li", { className: "ss-sheetextra__row" });
|
|
const label = el("span", { text: sheet.이름 + (sheet.숨김 ? "(숨김)" : "") });
|
|
const colorInput = el("input", {
|
|
attrs: { type: "color", value: sheet.탭색 ?? "#ffffff" },
|
|
}) as HTMLInputElement;
|
|
colorInput.addEventListener("change", () =>
|
|
setSheetTabColor(ctx, sheet.id, colorInput.value),
|
|
);
|
|
const colorClear = createButton({ label: "색 지움", variant: "ghost" });
|
|
colorClear.addEventListener("click", () => {
|
|
setSheetTabColor(ctx, sheet.id, null);
|
|
render();
|
|
});
|
|
const toggle = createButton({
|
|
label: sheet.숨김 ? "보이기" : "숨기기",
|
|
variant: "ghost",
|
|
});
|
|
toggle.addEventListener("click", () => {
|
|
if (sheet.숨김) {
|
|
unhideSheet(ctx, sheet.id);
|
|
showError(null);
|
|
} else {
|
|
showError(hideSheet(ctx, sheet.id));
|
|
}
|
|
render();
|
|
});
|
|
li.append(label, colorInput, colorClear, toggle);
|
|
return li;
|
|
}),
|
|
);
|
|
}
|
|
|
|
root.append(el("h4", { text: "시트 관리" }), list);
|
|
render();
|
|
|
|
return {
|
|
root,
|
|
refresh: render,
|
|
destroy(): void {
|
|
root.remove();
|
|
},
|
|
};
|
|
}
|