/* ============================================================================= * 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(); }, }; }