feat(spreadsheet): 우클릭 메뉴에 붙여넣기 · 삽입/삭제 ▸ · 크기 · 정렬 · 필터 · 고정 · 그룹 · 더보기 붙임 · 읽기 전용 복사(81-3)
- spreadsheet_menu.ts — 칸 · 행 머리 · 열 머리 메뉴에 spreadsheet_menu_items 펼침 · 구분선 - 잘라내기 · 복사 — 초점을 격자로 되돌린 뒤 execCommand(메뉴가 닫히며 초점이 빠져 빈 복사되던 흠) - 읽기 전용 · 미리보기 시트 우클릭 = 「복사」 한 줄(spreadsheet.ts 메뉴 늘 붙임) - 시험 test_stage4_menu_items.ts 34 · 크기 화면 16.3 KB(예산 72) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UoSr2sqvYtBf1dtQdus88s
This commit is contained in:
@@ -110,7 +110,7 @@ export function createSpreadsheet(
|
||||
): SpreadsheetHandle {
|
||||
const readOnly = !!opts.readOnly;
|
||||
const noTabs = opts.tabs === false;
|
||||
const bare = readOnly || !!opts.preview; // 도구 모음 · 메뉴 없음
|
||||
const bare = readOnly || !!opts.preview; // 도구 모음 없음 · 우클릭은 「복사」 한 줄
|
||||
const root = el("div", {
|
||||
className: `ss${readOnly ? " ss--readonly" : ""}${noTabs ? " ss--notabs" : ""}${opts.preview ? " ss--preview" : ""}`,
|
||||
});
|
||||
@@ -142,7 +142,7 @@ export function createSpreadsheet(
|
||||
ctx.editor = ed;
|
||||
const toolbar: PartHandle | null = bare ? null : mountToolbar(ctx);
|
||||
const tabs: PartHandle | null = noTabs ? null : mountTabs(ctx);
|
||||
const menu: PartHandle | null = bare ? null : attachMenu(ctx);
|
||||
const menu: PartHandle = attachMenu(ctx); // 읽기 전용 · 미리보기는 「복사」 한 줄(81-3)
|
||||
const clip = attachClipboard(ctx);
|
||||
const status = createStatusBar(ctx);
|
||||
const others = [toolbar, tabs, menu, clip, status].filter((p): p is PartHandle => !!p);
|
||||
|
||||
@@ -12,10 +12,21 @@
|
||||
* ========================================================================== */
|
||||
|
||||
import { createMapContextMenu, type MapContextMenuItem } from "@ui/ui_template_context_menu";
|
||||
import { createButton, el, showToast } from "@ui/ui_template_elements";
|
||||
import { createButton, el } from "@ui/ui_template_elements";
|
||||
import { rangeToA1 } from "./spreadsheet_address";
|
||||
import { confirmMerge, dialogKeys } from "./spreadsheet_actions";
|
||||
import { deleteComment, getComment, setComment } from "./spreadsheet_comments";
|
||||
import {
|
||||
cellInsertItems,
|
||||
cellMoreItems,
|
||||
colInsertItems,
|
||||
colMoreItems,
|
||||
copyCut,
|
||||
copyOnlyItems,
|
||||
pasteItems,
|
||||
rowInsertItems,
|
||||
rowMoreItems,
|
||||
} from "./spreadsheet_menu_items";
|
||||
import { st } from "./spreadsheet_text";
|
||||
import { MAX_COLS, MAX_ROWS, type CellRange } from "./spreadsheet_types";
|
||||
import type { PartHandle, SpreadsheetContext } from "./spreadsheet_view_types";
|
||||
@@ -28,7 +39,8 @@ function within(range: CellRange, r: number, c: number): boolean {
|
||||
|
||||
/** `ctx.root` 의 contextmenu 를 받음(root null) */
|
||||
export function attachMenu(ctx: SpreadsheetContext): PartHandle {
|
||||
if (ctx.readOnly) return { root: null, refresh() {}, destroy() {} };
|
||||
// 읽기 전용 · 미리보기 = 「복사」 한 줄(81-3)
|
||||
const bare = ctx.readOnly || ctx.root.classList.contains("ss--preview");
|
||||
|
||||
const menu = createMapContextMenu("ss");
|
||||
ctx.root.append(menu.element);
|
||||
@@ -39,7 +51,7 @@ export function attachMenu(ctx: SpreadsheetContext): PartHandle {
|
||||
}
|
||||
|
||||
function cutCopy(kind: "cut" | "copy"): void {
|
||||
document.execCommand(kind);
|
||||
copyCut(ctx, kind);
|
||||
}
|
||||
|
||||
/** 메모 글 입력 — 작은 오버레이(native prompt 안 씀, 자동화 창이 native 창을 자동 취소하는
|
||||
@@ -79,7 +91,10 @@ export function attachMenu(ctx: SpreadsheetContext): PartHandle {
|
||||
return [
|
||||
[st("MenuCut"), () => cutCopy("cut")],
|
||||
[st("MenuCopy"), () => cutCopy("copy")],
|
||||
[st("MenuPasteHint"), () => showToast(st("MenuPasteHint"), "info")],
|
||||
...pasteItems(ctx),
|
||||
"-",
|
||||
...cellInsertItems(ctx, range),
|
||||
"-",
|
||||
[
|
||||
st("MenuClearContent"),
|
||||
() => ctx.dispatch({ 종류: "내용지움", 시트: ctx.selection.시트, 범위: [range] }),
|
||||
@@ -107,6 +122,7 @@ export function attachMenu(ctx: SpreadsheetContext): PartHandle {
|
||||
...(note
|
||||
? ([[st("MenuCommentDelete"), () => deleteComment(ctx, r, c)]] as MapContextMenuItem[])
|
||||
: []),
|
||||
...cellMoreItems(ctx, range),
|
||||
...(ctx.cellMenuExtra?.(r, c) ?? []),
|
||||
];
|
||||
}
|
||||
@@ -117,11 +133,9 @@ export function attachMenu(ctx: SpreadsheetContext): PartHandle {
|
||||
return [
|
||||
[st("MenuCut"), () => cutCopy("cut")],
|
||||
[st("MenuCopy"), () => cutCopy("copy")],
|
||||
[st("MenuPasteHint"), () => showToast(st("MenuPasteHint"), "info")],
|
||||
[
|
||||
st("MenuInsertRow"),
|
||||
() => ctx.dispatch({ 종류: "행넣기", 시트: ctx.selection.시트, at, 수 }),
|
||||
],
|
||||
...pasteItems(ctx),
|
||||
"-",
|
||||
...rowInsertItems(ctx, at, 수),
|
||||
[
|
||||
st("MenuDeleteRow"),
|
||||
() => ctx.dispatch({ 종류: "행지우기", 시트: ctx.selection.시트, at, 수 }),
|
||||
@@ -148,6 +162,7 @@ export function attachMenu(ctx: SpreadsheetContext): PartHandle {
|
||||
숨김: false,
|
||||
}),
|
||||
],
|
||||
...rowMoreItems(ctx, rows),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -157,11 +172,9 @@ export function attachMenu(ctx: SpreadsheetContext): PartHandle {
|
||||
return [
|
||||
[st("MenuCut"), () => cutCopy("cut")],
|
||||
[st("MenuCopy"), () => cutCopy("copy")],
|
||||
[st("MenuPasteHint"), () => showToast(st("MenuPasteHint"), "info")],
|
||||
[
|
||||
st("MenuInsertCol"),
|
||||
() => ctx.dispatch({ 종류: "열넣기", 시트: ctx.selection.시트, at, 수 }),
|
||||
],
|
||||
...pasteItems(ctx),
|
||||
"-",
|
||||
...colInsertItems(ctx, at, 수),
|
||||
[
|
||||
st("MenuDeleteCol"),
|
||||
() => ctx.dispatch({ 종류: "열지우기", 시트: ctx.selection.시트, at, 수 }),
|
||||
@@ -188,6 +201,7 @@ export function attachMenu(ctx: SpreadsheetContext): PartHandle {
|
||||
숨김: false,
|
||||
}),
|
||||
],
|
||||
...colMoreItems(ctx, cols),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -217,7 +231,7 @@ export function attachMenu(ctx: SpreadsheetContext): PartHandle {
|
||||
활성: { r: hit.r, c: 0 },
|
||||
기준: { r: hit.r, c: 0 },
|
||||
});
|
||||
menu.open(x, y, rowMenuItems(rows));
|
||||
menu.open(x, y, bare ? copyOnlyItems(ctx) : rowMenuItems(rows));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -235,7 +249,7 @@ export function attachMenu(ctx: SpreadsheetContext): PartHandle {
|
||||
활성: { r: 0, c: hit.c },
|
||||
기준: { r: 0, c: hit.c },
|
||||
});
|
||||
menu.open(x, y, colMenuItems(cols));
|
||||
menu.open(x, y, bare ? copyOnlyItems(ctx) : colMenuItems(cols));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -250,7 +264,13 @@ export function attachMenu(ctx: SpreadsheetContext): PartHandle {
|
||||
});
|
||||
}
|
||||
const active = ctx.selection.범위[0] ?? range(hit.r, hit.c, hit.r, hit.c);
|
||||
menu.open(x, y, cellMenuItems(active, hit.r, hit.c));
|
||||
menu.open(
|
||||
x,
|
||||
y,
|
||||
bare
|
||||
? [...copyOnlyItems(ctx), ...(ctx.cellMenuExtra?.(hit.r, hit.c) ?? [])]
|
||||
: cellMenuItems(active, hit.r, hit.c),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user