Merge remote-tracking branch 'origin/sub_laptop_5' into main_laptop_1

This commit is contained in:
2026-11-02 13:08:10 +09:00
2 changed files with 62 additions and 0 deletions
@@ -437,6 +437,16 @@ export function createGrid(ctx: SpreadsheetContext): GridHandle {
};
}
/** 굴리는 영역 밖 테두리 자르기(`overlay` 좌표) — 고정 머리 칸 · 모서리 · 스크롤바 위로 안 나가게(요구 566). */
function clipOf(b: CellBox, inFrozenCol: boolean, inFrozenRow: boolean): string {
const pad = (n: number): number => Math.max(0, Math.ceil(n));
const top = inFrozenRow ? 0 : pad(frozenH - b.y);
const left = inFrozenCol ? 0 : pad(frozenW - b.x);
const bottom = pad(b.y + b.h - (frozenH + paneBR.clientHeight));
const right = pad(b.x + b.w - (frozenW + paneBR.clientWidth));
return `inset(${top}px ${right}px ${bottom}px ${left}px)`;
}
function renderSelection(): void {
let selLayer = overlay.querySelector<HTMLElement>(".aislo-grid__sel-layer");
if (!selLayer) {
@@ -470,6 +480,7 @@ export function createGrid(ctx: SpreadsheetContext): GridHandle {
node.style.height = `${screen.h}px`;
node.style.borderColor = "var(--aislo-grid-selected)";
node.style.borderWidth = i === 0 ? "2px" : "1px";
node.style.clipPath = clipOf(screen, inFrozenCol, inFrozenRow);
selLayer!.append(node);
}
// 활성 칸 테두리 — 칸 다시 그리기(`renderRowOfCells`) 없이 고름만 바뀌어도 옛 칸에 남지 않게.
@@ -487,6 +498,17 @@ export function createGrid(ctx: SpreadsheetContext): GridHandle {
handle.className = "aislo-grid__fill-handle";
handle.style.left = `${corner.x + corner.w - 4}px`;
handle.style.top = `${corner.y + corner.h - 4}px`;
const hx = corner.x + corner.w;
const hy = corner.y + corner.h;
const hFC = handleAt.c < frozenCols;
const hFR = handleAt.r < frozenRows;
if (
(!hFC && hx < frozenW) ||
(!hFR && hy < frozenH) ||
hx > frozenW + paneBR.clientWidth ||
hy > frozenH + paneBR.clientHeight
)
handle.style.display = "none";
selLayer!.append(handle);
}
@@ -525,6 +547,16 @@ export function createGrid(ctx: SpreadsheetContext): GridHandle {
node.style.width = `${merged.w}px`;
node.style.height = `${merged.h}px`;
node.style.borderColor = REF_COLORS[ref.색번호 % REF_COLORS.length];
node.style.clipPath = clipOf(
{
x: parseFloat(node.style.left),
y: parseFloat(node.style.top),
w: merged.w,
h: merged.h,
},
inFrozenCol,
inFrozenRow,
);
refLayer!.append(node);
}
}
@@ -0,0 +1,30 @@
"""730-1 지킴 — 엑셀 격자 고른 범위 · 참조 테두리 · 채우기 손잡이는 굴리는 영역 밖으로 안 나감(요구 566).
화면 수치 판정은 tmp 의 playwright 일회 검증 · 여기서는 자르기 길이 빠지지 않았는지만 지킴."""
import re
from pathlib import Path
SRC = (Path(__file__).parents[2] / "A00_Common/spreadsheet/spreadsheet_grid.ts").read_text(
encoding="utf-8"
)
def body(name: str) -> str:
m = re.search(rf"function {name}\(.*?\n }}\n", SRC, re.S)
assert m, name
return m.group(0)
def test_clip_helper_uses_frozen_and_pane_size():
h = body("clipOf")
assert "frozenH" in h and "frozenW" in h
assert "paneBR.clientHeight" in h and "paneBR.clientWidth" in h
def test_selection_and_ref_borders_are_clipped():
assert "clipPath = clipOf(" in body("renderSelection")
assert "clipPath = clipOf(" in body("setRefHighlights")
def test_fill_handle_hidden_outside_view():
assert 'handle.style.display = "none"' in body("renderSelection")