Merge remote-tracking branch 'origin/sub_laptop_5' into main_laptop_1
This commit is contained in:
@@ -72,6 +72,9 @@ export interface SpreadsheetOptions {
|
||||
conditions?: ConditionOptions;
|
||||
/** 그림 열쇠 → 주소(요구 347-5 · 시트 `그림`) — 없으면 이름 적힌 빈 상자 */
|
||||
figureSrc?: FigureSrc;
|
||||
/** 칸 칠(요구 621-5) — 시트 id · 행 · 열(0 부터) → 꼴 이름 `success|warning|info|danger|muted`(흐림) + `mine`(왼쪽 띠) ·
|
||||
* 공백으로 여럿 · 칸 `data-tone` 으로 나감 · 보이는 칸만 부름 · 안 주면 화면 그대로 */
|
||||
칠?: (시트: string, r: number, c: number) => string | null | undefined;
|
||||
}
|
||||
|
||||
export interface SpreadsheetHandle {
|
||||
@@ -93,6 +96,8 @@ export interface SpreadsheetHandle {
|
||||
/** HTML 표를 지금 시트 고른 칸(왼위)부터 붙임(105-1 도면 → 면적) — 붙여넣기와 같은 길(병합 · 되돌리기 한 번) ·
|
||||
* `check` = 덮을 자리의 값 칸 · 알약 칸 수 · 범위 → false 면 안 붙임 · 붙인 범위 A1 · 읽기만 · 못 하면 null */
|
||||
pasteTable(html: string, check?: PasteCheck): Promise<string | null>;
|
||||
/** 보이는 칸만 다시 그림(`칠` 결과가 바뀐 뒤) — 문서는 안 읽음 */
|
||||
repaint(): void;
|
||||
/** 범위 고름 · 보이게 굴림(329-2 엑셀 보기 창) — `시트` = id 나 이름(없으면 지금 시트 · 다르면 그 탭으로) ·
|
||||
* 범위 여럿 = 여러 고름 · 시트가 없거나 주소가 틀리면 false(고름 그대로) */
|
||||
select(범위: string | string[], 시트?: string): boolean;
|
||||
@@ -138,6 +143,7 @@ export function createSpreadsheet(
|
||||
root,
|
||||
book,
|
||||
readOnly,
|
||||
fill: opts.칠,
|
||||
engine: createCalcEngine(book),
|
||||
history: createHistory(),
|
||||
selection: selectCell(firstSheet(book), 0, 0),
|
||||
@@ -369,6 +375,7 @@ export function createSpreadsheet(
|
||||
return 이름;
|
||||
},
|
||||
pasteTable: (html, check) => pasteTableAt(ctx, html, check),
|
||||
repaint: () => grid.render(),
|
||||
select(range, sheetKey) {
|
||||
const target = sheetKey
|
||||
? ctx.book.시트.find((s) => s.id === sheetKey || s.이름 === sheetKey)
|
||||
|
||||
@@ -276,3 +276,40 @@ html[data-touch="on"] .aislo-grid__fill-handle {
|
||||
touch-action: pan-x pan-y;
|
||||
}
|
||||
}
|
||||
|
||||
/* 칸 칠(옵션 `칠` · 요구 621-5) — 칸 원래 채움(인라인 background-color) 위에 겹침 · 어두움은 --color-* 가 따라감. */
|
||||
.aislo-cell[data-tone~="success"] {
|
||||
background-image: linear-gradient(
|
||||
color-mix(in srgb, var(--color-success) 18%, transparent),
|
||||
color-mix(in srgb, var(--color-success) 18%, transparent)
|
||||
);
|
||||
}
|
||||
.aislo-cell[data-tone~="warning"] {
|
||||
background-image: linear-gradient(
|
||||
color-mix(in srgb, var(--color-warning) 18%, transparent),
|
||||
color-mix(in srgb, var(--color-warning) 18%, transparent)
|
||||
);
|
||||
}
|
||||
.aislo-cell[data-tone~="info"] {
|
||||
background-image: linear-gradient(
|
||||
color-mix(in srgb, var(--color-info) 18%, transparent),
|
||||
color-mix(in srgb, var(--color-info) 18%, transparent)
|
||||
);
|
||||
}
|
||||
.aislo-cell[data-tone~="danger"] {
|
||||
background-image: linear-gradient(
|
||||
color-mix(in srgb, var(--color-danger) 18%, transparent),
|
||||
color-mix(in srgb, var(--color-danger) 18%, transparent)
|
||||
);
|
||||
}
|
||||
.aislo-cell[data-tone~="muted"] {
|
||||
color: var(--color-text-muted) !important;
|
||||
}
|
||||
.aislo-cell[data-tone~="mine"] {
|
||||
box-shadow: inset 3px 0 0 var(--color-accent);
|
||||
}
|
||||
|
||||
/* 읽기만 — 시트 탭 「+」 숨김 */
|
||||
.ss--readonly .ss-tabs__add {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -319,6 +319,9 @@ export function renderCells(
|
||||
if (need > w * 0.9) longs.push({ r: r0, c: c0, el: cellEl, own: w, need, align });
|
||||
}
|
||||
}
|
||||
const tone = ctx.fill?.(sheet.id, r0, c0);
|
||||
if (tone) cellEl.dataset.tone = tone;
|
||||
else delete cellEl.dataset.tone; // 재사용 div — 앞 칸 꼴을 지움
|
||||
cellEl.classList.toggle("is-error", display.isError);
|
||||
cellEl.classList.toggle("has-comment", !!comment);
|
||||
cellEl.classList.toggle(
|
||||
|
||||
@@ -94,6 +94,8 @@ export interface SpreadsheetContext {
|
||||
/** 지금 문서 — 명령만이 바꿈(직접 고치지 말 것) */
|
||||
book: Workbook;
|
||||
readOnly: boolean;
|
||||
/** 칸 칠(옵션 `칠`) — 시트 id · 행 · 열 → 꼴 이름(공백으로 여럿 · 없으면 칠 없음) · 보이는 칸만 부름 */
|
||||
fill?: (시트: string, r: number, c: number) => string | null | undefined;
|
||||
engine: CalcEngine;
|
||||
history: History;
|
||||
selection: Selection;
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
"""779-3 지킴 — 공용 격자 「칠」 옵션(요구 621-5): 안 주면 data-tone 없음 · 주면 보이는 칸만 · 색은 --color-* 만.
|
||||
화면 수치 판정은 tmp 의 playwright 일회 검증 · 여기서는 길이 빠지지 않았는지만 지킴."""
|
||||
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
SS = Path(__file__).parents[2] / "A00_Common/spreadsheet"
|
||||
|
||||
|
||||
def read(name: str) -> str:
|
||||
return (SS / name).read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def test_fill_option_flows_option_to_ctx_to_cell():
|
||||
assert "칠?:" in read("spreadsheet.ts") and "fill: opts.칠" in read("spreadsheet.ts")
|
||||
assert "fill?:" in read("spreadsheet_view_types.ts")
|
||||
|
||||
|
||||
def test_tone_set_only_in_visible_cell_loop_and_cleared_when_absent():
|
||||
cells = read("spreadsheet_grid_cells.ts")
|
||||
assert cells.count("ctx.fill?.(") == 1 # 칸 그리는 반복(보이는 칸) 안 한 곳뿐
|
||||
assert "cellEl.dataset.tone = tone" in cells
|
||||
assert "delete cellEl.dataset.tone" in cells # 재사용 div — 안 주면 data-tone 없음
|
||||
|
||||
|
||||
def test_repaint_handle_only_rerenders_grid():
|
||||
assert re.search(r"repaint:\s*\(\)\s*=>\s*grid\.render\(\)", read("spreadsheet.ts"))
|
||||
|
||||
|
||||
def test_css_tones_use_color_tokens_only_and_readonly_hides_add():
|
||||
css = read("spreadsheet_grid.css")
|
||||
tone = css[css.index('[data-tone~="success"]') :]
|
||||
for name in ("success", "warning", "info", "danger"):
|
||||
assert f"var(--color-{name}) 18%" in tone
|
||||
assert "--draw-" not in tone
|
||||
assert "var(--color-text-muted)" in tone and "var(--color-accent)" in tone
|
||||
assert ".ss--readonly .ss-tabs__add" in css
|
||||
Reference in New Issue
Block a user