perf(spreadsheet): D — 누를 때만 쓰는 창을 늦게 불러옴(크기 예산 화면 28 KB 안)
- spreadsheet_data_menu.ts — 정렬(↑ ↓ · 정렬…) · 조건부 서식 · 시트 숨김/탭 색 창은 import() - spreadsheet_extras.ts — 셀 서식 창(Ctrl+1 · [서식…]) import() - 크기 시험: 엔진 31.4 · 화면 27.2 · css 3.9 · 합 62.6 KB Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L6KXAabDTenEU7hrDQmCKY
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
* 조건부 서식 · 데이터 유효성 · 이름 관리 · 시트 숨김/탭 색(sub4 패널 — 부품 오른위 창에 띄움) · 눈금선 ·
|
||||
* 수식 분석(sub3 — 선행 · 종속 추적 화살표 · 화살표 지우기 · 수식 계산 · 오류 ⚠ 풍선) · 자동 합계(Σ · Alt+=).
|
||||
* 유효성 목록 칸은 고르면 칸 옆 ▼ · Alt+↓ 로 값 목록(필터 머리 칸이면 필터 목록이 먼저).
|
||||
* 누를 때만 쓰는 창(정렬 · 조건부 서식 · 시트)은 `import()` 로 늦게 — 크기 예산(열 때 받는 조각).
|
||||
* ========================================================================== */
|
||||
|
||||
import "./spreadsheet_stage3.css"; // sub4 패널 스타일(잇는 쪽이 붙임)
|
||||
@@ -12,13 +13,10 @@ import { createMapContextMenu, type MapContextMenuItem } from "@ui/ui_template_c
|
||||
import { el, showToast } from "@ui/ui_template_elements";
|
||||
import { parseRange, rangeToA1, toA1 } from "./spreadsheet_address";
|
||||
import { autoSumRange } from "./spreadsheet_autosum";
|
||||
import { createCondFmtPanel } from "./spreadsheet_condfmt";
|
||||
import { attachErrorTip } from "./spreadsheet_errcheck";
|
||||
import { openEvalSteps } from "./spreadsheet_eval_steps";
|
||||
import { attachFilter, toggleFilter } from "./spreadsheet_filter";
|
||||
import { createNameManagerPanel } from "./spreadsheet_names";
|
||||
import { createSheetExtraPanel } from "./spreadsheet_sheet_extra";
|
||||
import { openSortDialog, sortSelection } from "./spreadsheet_sort_dialog";
|
||||
import { attachTrace } from "./spreadsheet_trace";
|
||||
import {
|
||||
createValidationDropdown,
|
||||
@@ -108,7 +106,11 @@ export function mountDataMenu(ctx: SpreadsheetContext, back: () => void): DataMe
|
||||
closePanel();
|
||||
back();
|
||||
});
|
||||
function openPanel(name: string, make: (c: SpreadsheetContext) => PartHandle): void {
|
||||
async function openPanel(
|
||||
name: string,
|
||||
load: () => Promise<(c: SpreadsheetContext) => PartHandle>,
|
||||
): Promise<void> {
|
||||
const make = await load();
|
||||
closePanel();
|
||||
panel = make(ctx);
|
||||
title.textContent = name.replace("…", "");
|
||||
@@ -116,15 +118,42 @@ export function mountDataMenu(ctx: SpreadsheetContext, back: () => void): DataMe
|
||||
dialog.removeAttribute("hidden");
|
||||
}
|
||||
|
||||
const sorting = () => import("./spreadsheet_sort_dialog");
|
||||
async function sortQuick(desc: boolean): Promise<void> {
|
||||
(await sorting()).sortSelection(ctx, desc);
|
||||
back();
|
||||
}
|
||||
async function sortDialog(): Promise<void> {
|
||||
const m = await sorting();
|
||||
closeSort?.();
|
||||
closeSort = m.openSortDialog(ctx);
|
||||
}
|
||||
function evalSteps(): void {
|
||||
closeSteps?.();
|
||||
closeSteps = openEvalSteps(ctx);
|
||||
}
|
||||
|
||||
function openMenu(anchor: HTMLElement): void {
|
||||
const r = anchor.getBoundingClientRect();
|
||||
const items: MapContextMenuItem[] = [
|
||||
[TEXT.sort, () => ((closeSort = openSortDialog(ctx)), undefined)],
|
||||
[TEXT.sort, () => void sortDialog()],
|
||||
[TEXT.filterItem, () => (toggleFilter(ctx), back())],
|
||||
[TEXT.condfmt, () => openPanel(TEXT.condfmt, createCondFmtPanel)],
|
||||
[TEXT.validation, () => openPanel(TEXT.validation, createValidationPanel)],
|
||||
[TEXT.names, () => openPanel(TEXT.names, createNameManagerPanel)],
|
||||
[TEXT.sheets, () => openPanel(TEXT.sheets, createSheetExtraPanel)],
|
||||
[
|
||||
TEXT.condfmt,
|
||||
() =>
|
||||
void openPanel(TEXT.condfmt, () =>
|
||||
import("./spreadsheet_condfmt").then((m) => m.createCondFmtPanel),
|
||||
),
|
||||
],
|
||||
[TEXT.validation, () => void openPanel(TEXT.validation, async () => createValidationPanel)],
|
||||
[TEXT.names, () => void openPanel(TEXT.names, async () => createNameManagerPanel)],
|
||||
[
|
||||
TEXT.sheets,
|
||||
() =>
|
||||
void openPanel(TEXT.sheets, () =>
|
||||
import("./spreadsheet_sheet_extra").then((m) => m.createSheetExtraPanel),
|
||||
),
|
||||
],
|
||||
[TEXT.grid, () => (toggleGridlines(), back())],
|
||||
{
|
||||
label: TEXT.audit,
|
||||
@@ -132,7 +161,7 @@ export function mountDataMenu(ctx: SpreadsheetContext, back: () => void): DataMe
|
||||
[TEXT.prec, () => traced(trace.precedents())],
|
||||
[TEXT.dep, () => traced(trace.dependents())],
|
||||
[TEXT.clear, () => (trace.clear(), back())],
|
||||
[TEXT.steps, () => (closeSteps?.(), (closeSteps = openEvalSteps(ctx)))],
|
||||
[TEXT.steps, evalSteps],
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -201,8 +230,8 @@ export function mountDataMenu(ctx: SpreadsheetContext, back: () => void): DataMe
|
||||
const buttons = ctx.readOnly
|
||||
? []
|
||||
: [
|
||||
button("↑", TEXT.asc, () => sortSelection(ctx, false)),
|
||||
button("↓", TEXT.desc, () => sortSelection(ctx, true)),
|
||||
button("↑", TEXT.asc, () => void sortQuick(false), true),
|
||||
button("↓", TEXT.desc, () => void sortQuick(true), true),
|
||||
button("필터", TEXT.filter, () => toggleFilter(ctx)),
|
||||
button("Σ", TEXT.sum, autosum, true),
|
||||
button(TEXT.menu, TEXT.menu, openMenu, true),
|
||||
|
||||
@@ -12,7 +12,6 @@ import { attachComments, getComment, setComment } from "./spreadsheet_comments";
|
||||
import { mountDataMenu } from "./spreadsheet_data_menu";
|
||||
import type { Editor } from "./spreadsheet_editor";
|
||||
import { mountFindPanel } from "./spreadsheet_find_panel";
|
||||
import { openFormatDialog } from "./spreadsheet_format_dialog";
|
||||
import { createFormatPainter } from "./spreadsheet_format_painter";
|
||||
import type { KeyHooks } from "./spreadsheet_keys";
|
||||
import type { MouseHooks } from "./spreadsheet_mouse";
|
||||
@@ -116,9 +115,9 @@ export function attachExtras(
|
||||
attrs: { type: "button", title: TEXT.format },
|
||||
});
|
||||
/** 창이 닫히면(확인 · 취소) 초점을 격자로 */
|
||||
function openFormat(): void {
|
||||
async function openFormat(): Promise<void> {
|
||||
if (ctx.readOnly) return;
|
||||
openFormatDialog(ctx);
|
||||
(await import("./spreadsheet_format_dialog")).openFormatDialog(ctx); // 늦게 — 크기 예산
|
||||
const watch = new MutationObserver(() => {
|
||||
if (document.querySelector(".ss-fmtdlg")) return;
|
||||
watch.disconnect();
|
||||
@@ -126,7 +125,7 @@ export function attachExtras(
|
||||
});
|
||||
watch.observe(document.body, { childList: true });
|
||||
}
|
||||
fmt.addEventListener("click", openFormat);
|
||||
fmt.addEventListener("click", () => void openFormat());
|
||||
if (!ctx.readOnly) ed.bar.prepend(fmt, brush);
|
||||
|
||||
// ── 데이터 단추 · 메뉴(정렬 · 필터 · 조건부 서식 · 유효성 · 이름 · 눈금선) ─────────
|
||||
@@ -207,7 +206,7 @@ export function attachExtras(
|
||||
find: (replace) => find.open(replace),
|
||||
pasteSpecial: () => (armed = true),
|
||||
comment: editMemo,
|
||||
formatDialog: openFormat,
|
||||
formatDialog: () => void openFormat(),
|
||||
...data.keys,
|
||||
escape() {
|
||||
painter.clear();
|
||||
|
||||
Reference in New Issue
Block a user