feat(M02-흐름도): 공용 단위 고르기 UnitPick · 끝수 줄 · 함수 판 단위 고르기로 바꿈
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D2nUMUMTsqm93PbQtipo6c
This commit is contained in:
@@ -15,6 +15,9 @@ import type {
|
||||
Workbook,
|
||||
} from "../../A00_Common/spreadsheet/spreadsheet";
|
||||
import type { CfBox, CfFunc, CfLogic, CfVariable } from "./M02_DF_Model";
|
||||
import { parseRound, wrapRound, type RoundSpec } from "./M02_DF_Round";
|
||||
import { createRoundRow } from "./M02_DF_RoundRow";
|
||||
import { createUnitPick, suggestPlaces } from "./M02_DF_UnitPick";
|
||||
import "./M02_DF_FuncPanel.css";
|
||||
|
||||
const TEXT = {
|
||||
@@ -126,6 +129,8 @@ interface State {
|
||||
json: string;
|
||||
cell: string;
|
||||
form: VarForm | null;
|
||||
/** 단위 표준이 제안한 출력 소수자리 */
|
||||
suggest: number | null;
|
||||
parts: {
|
||||
head: HTMLElement;
|
||||
got: HTMLElement;
|
||||
@@ -317,20 +322,19 @@ function applyMarks(st: State): void {
|
||||
|
||||
function drawHead(st: State): void {
|
||||
const box = boxOf(st);
|
||||
const unit = el("input", {
|
||||
className: "ui-input m02-dfpanel-unit",
|
||||
attrs: { type: "text", "aria-label": tf("Unit") },
|
||||
});
|
||||
unit.value = box?.unit ?? "-";
|
||||
if (st.readOnly) unit.readOnly = true;
|
||||
unit.addEventListener("change", () => {
|
||||
const v = unit.value.trim() || "-";
|
||||
unit.value = v;
|
||||
patchBox(st, (b) => ({
|
||||
...b,
|
||||
unit: v,
|
||||
func: b.func ? { ...b.func, output: { ...b.func.output, unit: v } } : b.func,
|
||||
}));
|
||||
const unit = createUnitPick({
|
||||
value: box?.unit ?? "-",
|
||||
readOnly: st.readOnly,
|
||||
extra: st.lg.resultUnit ? [st.lg.resultUnit] : [],
|
||||
ariaLabel: tf("Unit"),
|
||||
onPick: (v) => {
|
||||
patchBox(st, (x) => ({
|
||||
...x,
|
||||
unit: v,
|
||||
func: x.func ? { ...x.func, output: { ...x.func.output, unit: v } } : x.func,
|
||||
}));
|
||||
void suggestPlaces(v).then((n) => ((st.suggest = n), drawBar(st)));
|
||||
},
|
||||
});
|
||||
st.parts.head.replaceChildren(
|
||||
el("strong", { className: "m02-dfpanel-title", text: box?.name ?? "" }),
|
||||
@@ -372,8 +376,21 @@ function formField(
|
||||
cls = "",
|
||||
): HTMLElement {
|
||||
const form = st.form!;
|
||||
if (key === "unit") {
|
||||
return el("label", {
|
||||
className: "m02-dfpanel-fieldbox",
|
||||
children: [
|
||||
el("span", { className: "m02-dfpanel-note", text: tf(label) }),
|
||||
createUnitPick({
|
||||
value: form.unit || "-",
|
||||
ariaLabel: tf(label),
|
||||
onPick: (u) => ((form.unit = u), drawVars(st)),
|
||||
}),
|
||||
],
|
||||
});
|
||||
}
|
||||
const input = el("input", {
|
||||
className: `ui-input m02-dfpanel-field ${cls}`,
|
||||
className: `ui-input ui-input--sm m02-dfpanel-field ${cls}`,
|
||||
attrs: { type: "text", "aria-label": tf(label) },
|
||||
});
|
||||
input.value = form[key];
|
||||
@@ -443,7 +460,7 @@ function drawVars(st: State): void {
|
||||
);
|
||||
} else {
|
||||
const type = el("select", {
|
||||
className: "ui-select m02-dfpanel-field",
|
||||
className: "ui-select ui-select--sm m02-dfpanel-field",
|
||||
attrs: { "aria-label": tf("VarType") },
|
||||
});
|
||||
for (const [v, k] of [
|
||||
@@ -520,6 +537,7 @@ function drawBar(st: State): void {
|
||||
el("span", { className: "m02-dfpanel-note", text: tf("OutOnly") }),
|
||||
],
|
||||
}),
|
||||
...[roundRow(st)].filter((x): x is HTMLElement => !!x),
|
||||
el("div", {
|
||||
className: "m02-dfpanel-row",
|
||||
children: [
|
||||
@@ -538,6 +556,34 @@ function drawBar(st: State): void {
|
||||
);
|
||||
}
|
||||
|
||||
/** 출력 칸 수식에 끝수 씌움(칸 값만 있으면 그 값을 감쌈) */
|
||||
function writeRound(st: State, spec: RoundSpec | null): void {
|
||||
const f = funcOf(st);
|
||||
const cell = f?.sheet.칸[f.output.cell];
|
||||
if (!f || !cell) return;
|
||||
const text = cell.식 ?? String(cell.값 ?? "");
|
||||
const inner = parseRound(text)?.inner ?? text;
|
||||
patchFunc(st, (x) => {
|
||||
const sheet = structuredClone(x.sheet);
|
||||
sheet.칸[x.output.cell] = { 식: wrapRound(inner, spec) };
|
||||
return { ...x, sheet };
|
||||
});
|
||||
}
|
||||
|
||||
function roundRow(st: State): HTMLElement | null {
|
||||
const f = funcOf(st);
|
||||
const cell = f?.sheet.칸[f.output.cell];
|
||||
const formula = cell
|
||||
? (cell.식 ?? (cell.값 === undefined ? undefined : String(cell.값)))
|
||||
: undefined;
|
||||
return createRoundRow({
|
||||
formula,
|
||||
suggest: st.suggest,
|
||||
readOnly: st.readOnly,
|
||||
onApply: (spec) => writeRound(st, spec),
|
||||
});
|
||||
}
|
||||
|
||||
/** 출력 칸 하나 정하기 — 다시 고르면 바뀜 */
|
||||
function setOutput(st: State, cell: string): void {
|
||||
const f = funcOf(st);
|
||||
@@ -681,6 +727,7 @@ export function renderFuncPanel(
|
||||
json: "",
|
||||
cell: "A1",
|
||||
form: null,
|
||||
suggest: null,
|
||||
parts,
|
||||
observer: null,
|
||||
redraw: () => {
|
||||
|
||||
Reference in New Issue
Block a user