Merge remote-tracking branch 'origin/sub_laptop_6' into sub_laptop_7
This commit is contained in:
@@ -183,6 +183,19 @@
|
||||
color: #c00;
|
||||
}
|
||||
|
||||
/* 오류 칸 — 엑셀 오류 검사 초록 세모(왼 위 · sub3 오류 까닭은 title 풍선). */
|
||||
.aislo-cell.is-error::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-width: 6px 6px 0 0;
|
||||
border-color: #2e7d32 transparent transparent transparent;
|
||||
}
|
||||
|
||||
.aislo-cell.is-selected {
|
||||
outline: 2px solid var(--aislo-grid-selected);
|
||||
outline-offset: -1px;
|
||||
|
||||
@@ -34,6 +34,7 @@ import {
|
||||
type LineGeometry,
|
||||
type OutlineRun,
|
||||
} from "./spreadsheet_headers";
|
||||
import { resolveCondFmtStyle, type CondFmtValue } from "./spreadsheet_condfmt";
|
||||
import { formatValue } from "./spreadsheet_numfmt";
|
||||
import { MAX_COLS, MAX_ROWS } from "./spreadsheet_types";
|
||||
import type {
|
||||
@@ -150,6 +151,23 @@ interface CellDisplay {
|
||||
color?: string;
|
||||
}
|
||||
|
||||
/** 칸 하나 값 — 식이면 엔진 값 · 아니면 입력 값(수는 Frac로) · 둘 다 없으면 빈 칸. */
|
||||
function scalarAt(ctx: SpreadsheetContext, sheet: Sheet, r: number, c: number): Scalar {
|
||||
const cell = sheet.칸[toA1(r, c)];
|
||||
return cell?.식 !== undefined
|
||||
? ctx.engine.value(sheet.id, r, c)
|
||||
: cell?.값 !== undefined
|
||||
? toScalar(cell.값)
|
||||
: null;
|
||||
}
|
||||
|
||||
/** 조건부 서식(sub4) 이 값을 보는 형 — Frac 는 근사 수로(조건 비교용 · 오류는 조건 대상 아님). */
|
||||
function toCondFmtValue(scalar: Scalar): CondFmtValue {
|
||||
if (scalar === null || typeof scalar === "boolean" || typeof scalar === "string") return scalar;
|
||||
if ("error" in scalar) return null;
|
||||
return Number(scalar.n) / Number(scalar.d);
|
||||
}
|
||||
|
||||
function cellDisplay(
|
||||
ctx: SpreadsheetContext,
|
||||
sheet: Sheet,
|
||||
@@ -158,13 +176,7 @@ function cellDisplay(
|
||||
hAlign0: HAlign,
|
||||
code?: string,
|
||||
): CellDisplay {
|
||||
const cell = sheet.칸[toA1(r, c)];
|
||||
const scalar: Scalar =
|
||||
cell?.식 !== undefined
|
||||
? ctx.engine.value(sheet.id, r, c)
|
||||
: cell?.값 !== undefined
|
||||
? toScalar(cell.값)
|
||||
: null;
|
||||
const scalar = scalarAt(ctx, sheet, r, c);
|
||||
const formatted = formatValue(scalar, code);
|
||||
const isError = typeof scalar === "object" && scalar !== null && "error" in scalar;
|
||||
const hAlign: HAlign = hAlign0 !== "general" ? hAlign0 : formatted.정렬;
|
||||
@@ -365,7 +377,13 @@ export function createGrid(ctx: SpreadsheetContext): GridHandle {
|
||||
cellEl.dataset.c = String(c0);
|
||||
const addr = toA1(r0, c0);
|
||||
cellEl.dataset.addr = addr;
|
||||
const style = cellStyleAt(book, sheet, r0, c0);
|
||||
const baseStyle = cellStyleAt(book, sheet, r0, c0);
|
||||
const condStyle = sheet.조건부서식?.length
|
||||
? resolveCondFmtStyle(sheet, r0, c0, {
|
||||
value: (rr, cc) => toCondFmtValue(scalarAt(ctx, sheet, rr, cc)),
|
||||
})
|
||||
: null;
|
||||
const style = condStyle ? { ...baseStyle, ...condStyle } : baseStyle;
|
||||
const borders: ResolvedBorders = resolveBoxBorders(
|
||||
book,
|
||||
sheet,
|
||||
@@ -378,7 +396,8 @@ export function createGrid(ctx: SpreadsheetContext): GridHandle {
|
||||
);
|
||||
const display = cellDisplay(ctx, sheet, r0, c0, style.가로 ?? "general", style.형식);
|
||||
applyCellStyle(cellEl, style, borders, display.hAlign, zoom);
|
||||
if (display.color) cellEl.style.color = display.color;
|
||||
// 조건부 서식 글자색이 이기고(엑셀과 같음) · 없으면 숫자 형식([Red] 등)이 정한 색.
|
||||
if (display.color && !condStyle?.글자색) cellEl.style.color = display.color;
|
||||
const comment = sheet.comments?.[addr];
|
||||
setCellText(cellEl, display.text, display.title || comment || undefined);
|
||||
cellEl.classList.toggle("is-error", display.isError);
|
||||
|
||||
@@ -35,9 +35,18 @@ const sheet: Sheet = {
|
||||
A6: { 값: "선택 영역 가운데(centerContinuous) 보기", 서식: 5 },
|
||||
A8: { 값: "hair 테두리 칸", 서식: 3 },
|
||||
B8: { 값: 3.14159, 서식: 7 },
|
||||
G9: { 식: "1/0" },
|
||||
J10000: { 값: "맨 끝 칸(1만 행 스크롤 확인용)" },
|
||||
},
|
||||
comments: { H4: "메모 — ROUNDDOWN 끝수 확인" },
|
||||
조건부서식: [
|
||||
{
|
||||
id: "cf1",
|
||||
범위: [{ r0: 3, c0: 7, r1: 3, c1: 7 }],
|
||||
조건: { 종류: "비교", 연산: "보다작음", 값: 0 },
|
||||
스타일: { 채움: "#ffe0e0", 글자색: "#c00000", 굵게: true },
|
||||
},
|
||||
],
|
||||
병합: ["A1:H1", "B8:C9"],
|
||||
열: {
|
||||
A: { 폭: 14 },
|
||||
@@ -96,7 +105,8 @@ function noopEngine(): CalcEngine {
|
||||
return {
|
||||
update: () => [],
|
||||
rebuild: () => {},
|
||||
value: () => null,
|
||||
value: (_sheet, r, c) =>
|
||||
r === 8 && c === 6 ? { error: "#DIV/0!", why: "0 으로 나눔(시험 칸 G9)" } : null,
|
||||
precedents: () => [],
|
||||
snapshot: () => ({}),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user