refactor(M02): 띠 알림 · 빈 상태 · 보조 글 · 배지 · 탭 · 표 · 목록 줄 · 도구줄 · 체크를 부품으로 (PLAN 553-5)
- DataFlow: 표 넷 = 데이터표 · 함수 판 알림 · 선/알약 경고 · 끊긴 곳 = 띠 알림 · 알약 · 칸 종류 = 배지 · 고르는 줄 = 목록 줄 · 입력 넷 = 입력 · 도구줄 여섯 · 날 색 → 공통 값 - 구조물 옵션 · 구조물 · 도면 · 면적 · 품목 고르기: 판 띠 = 띠 알림 · 한눈/종류별/부품 = 탭 · 표 둘 = 데이터표 · 체크 둘 = 체크 · 카드 · 번호 = 카드 · 배지 · 도면 도구줄 - 일위대가 · 호표 · 실무자료 · 본 화면 · 서고: 알림 = 띠 알림 · 빈 상태 · 보조 글 · 도구줄 여섯 · 옛 보라 별칭 0 - M01 로직 입력칸 = 입력 부품(작은 칸) · 일위대가 상세 줄 수 고정 시험 693 · 지킴 시험 M02 몫 더함 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,8 @@ import { currentLanguageIndex } from "@ui/ui_template_locale";
|
||||
import { createButton, el } from "@ui/ui_template_elements";
|
||||
import type { CfBox, CfLogic } from "./M02_DF_Model";
|
||||
import { portText } from "./M02_DF_Detail";
|
||||
import "@ui/ui_template_badge.css";
|
||||
import "@ui/ui_template_table.css";
|
||||
|
||||
const TEXT = {
|
||||
Title: ["칸 연결 표", "Cell connections"],
|
||||
@@ -103,7 +105,8 @@ export function renderCellTable(
|
||||
el("td", {
|
||||
children: [
|
||||
el("span", {
|
||||
className: "m02-dfcells__kind",
|
||||
className: `ui-badge ui-badge--pill ui-badge--${r.kind === "in" ? "info" : r.kind === "var" ? "warning" : "success"} m02-dfcells__kind`,
|
||||
attrs: { "data-size": "20" },
|
||||
text: tt(r.kind === "in" ? "In" : r.kind === "var" ? "Var" : "Out"),
|
||||
}),
|
||||
],
|
||||
@@ -128,7 +131,7 @@ export function renderCellTable(
|
||||
host.replaceChildren(
|
||||
el("strong", { className: "m02-dfcells__title", text: tt("Title") }),
|
||||
el("table", {
|
||||
className: "m02-dfcells__table",
|
||||
className: "ui-table ui-table--data m02-dfcells__table",
|
||||
children: [el("thead", { children: [head] }), el("tbody", { children: body })],
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -48,15 +48,6 @@
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.m02-dfdg__note {
|
||||
color: var(--color-danger);
|
||||
}
|
||||
|
||||
.m02-dfdg__hint {
|
||||
margin: 0;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
/* 판 — 화면 위쪽 큰 영역 */
|
||||
.m02-dfdg__view {
|
||||
position: relative;
|
||||
|
||||
@@ -38,6 +38,8 @@ import {
|
||||
type TEXT,
|
||||
} from "./M02_DF_Diagram_Parts";
|
||||
import "./M02_DF_Diagram.css";
|
||||
import "@ui/ui_template_text.css";
|
||||
import "@ui/ui_template_toolbar.css";
|
||||
|
||||
export * from "./M02_DF_Diagram_Parts";
|
||||
|
||||
@@ -395,7 +397,7 @@ export function renderDiagram(
|
||||
: [];
|
||||
|
||||
const bar = el("div", {
|
||||
className: "m02-dfdg__bar",
|
||||
className: "ui-toolbar m02-dfdg__bar",
|
||||
children: [
|
||||
el("strong", { className: "m02-dfdg__title", text: tt("Title") }),
|
||||
...(ro
|
||||
@@ -425,12 +427,12 @@ export function renderDiagram(
|
||||
children: [
|
||||
bar,
|
||||
el("div", {
|
||||
className: "m02-dfdg__tools",
|
||||
className: "ui-toolbar m02-dfdg__tools",
|
||||
children: [
|
||||
...tools,
|
||||
el("span", { className: "m02-dfdg__note", text: st.note }),
|
||||
el("span", { className: "ui-text ui-text--error", text: st.note }),
|
||||
el("span", {
|
||||
className: "m02-dfdg__hint",
|
||||
className: "ui-text ui-text--muted",
|
||||
text: tools.length || st.note ? "" : tt("Hint"),
|
||||
}),
|
||||
],
|
||||
|
||||
@@ -12,6 +12,7 @@ import type { CfAnswer, CfQuery } from "./M02_DF_Api";
|
||||
import { fillTemplate } from "./M02_DF_InputPanel_Build";
|
||||
import type { CfBreak, CfValues } from "./M02_DF_Eval";
|
||||
import type { CfElementRef, CfLogic, CfPort } from "./M02_DF_Model";
|
||||
import "@ui/ui_template_text.css";
|
||||
|
||||
const TEXT = {
|
||||
Detail: ["상세 내용", "Details"],
|
||||
@@ -120,7 +121,7 @@ export function drawWarnings(d: DetailParts, pick: DfPick, all: CfBreak[]): void
|
||||
d.warn.replaceChildren(
|
||||
...(mine.length
|
||||
? [...new Set(mine.map((k) => k.text))].map((w) => el("li", { text: w }))
|
||||
: [el("li", { className: "m02-df__muted", text: tt("WarnNone") })]),
|
||||
: [el("li", { className: "ui-text ui-text--muted", text: tt("WarnNone") })]),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import { recalcWorkbook } from "../../A00_Common/spreadsheet/spreadsheet_recalc"
|
||||
import { ifBody, splitArgs } from "../../A00_Common/spreadsheet/spreadsheet_condition_text";
|
||||
import type { CalcValue } from "../../A00_Common/spreadsheet/spreadsheet_types";
|
||||
import type { CfBox } from "./M02_DF_Model";
|
||||
import { createEmpty } from "@ui/ui_template_empty";
|
||||
|
||||
export type CellScalar = number | string | boolean | null;
|
||||
|
||||
@@ -259,7 +260,7 @@ function fromCalc(v: CalcValue): CellScalar {
|
||||
|
||||
/** 식 보기 그리기 — 줄마다 이름 식 · 값 식 · 갈래(지금 갈래는 ▶ 와 「지금」 글) */
|
||||
export function renderFormulaView(host: HTMLElement, lines: FormulaLine[]): void {
|
||||
host.classList.add("m02-df-formula");
|
||||
host.classList.add("ui-card", "m02-df-formula");
|
||||
host.replaceChildren(
|
||||
el("strong", { className: "m02-df-formula__title", text: tv("Title") }),
|
||||
...(lines.length
|
||||
@@ -285,6 +286,6 @@ export function renderFormulaView(host: HTMLElement, lines: FormulaLine[]): void
|
||||
],
|
||||
}),
|
||||
)
|
||||
: [el("p", { className: "m02-df-formula__empty", text: tv("Empty") })]),
|
||||
: [createEmpty({ text: tv("Empty"), small: true })]),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -34,28 +34,14 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.m02-dfpanel-cell {
|
||||
padding: 2px var(--spacing-12);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-pills);
|
||||
background: var(--color-surface-raised);
|
||||
}
|
||||
|
||||
.m02-dfpanel-label {
|
||||
font-weight: var(--font-weight-bold);
|
||||
}
|
||||
|
||||
.m02-dfpanel-note {
|
||||
color: var(--color-text-muted);
|
||||
font-size: var(--text-body-sm);
|
||||
}
|
||||
|
||||
.m02-dfpanel-form {
|
||||
/* 겉 = 카드 부품 · 여기는 아래 맞춤 · 안 여백만 */
|
||||
.m02-dfpanel-form.ui-card {
|
||||
align-items: flex-end;
|
||||
padding: var(--spacing-8) var(--spacing-12);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-cards);
|
||||
background: var(--color-surface-raised);
|
||||
}
|
||||
|
||||
.m02-dfpanel-fieldbox {
|
||||
@@ -72,26 +58,18 @@
|
||||
width: 6em;
|
||||
}
|
||||
|
||||
.m02-dfpanel-why,
|
||||
/* 알림 = 띠 알림 부품 — 숨김은 부품 display 를 이김 */
|
||||
.m02-dfpanel-msg {
|
||||
margin: 0;
|
||||
padding: var(--spacing-8) var(--spacing-12);
|
||||
border-left: 4px solid var(--color-warning);
|
||||
background: var(--color-surface-raised);
|
||||
font-weight: var(--font-weight-medium);
|
||||
}
|
||||
|
||||
.m02-dfpanel-msg[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 받음 · 변수 · 출력 알약 = 배지 부품(info · warning · success) — 안 놓인 받음은 점선 */
|
||||
.m02-dfpanel-chip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-4);
|
||||
padding: var(--spacing-4) var(--spacing-12);
|
||||
border: 2px solid;
|
||||
border-radius: var(--radius-pills);
|
||||
background: var(--color-surface);
|
||||
color: inherit;
|
||||
font: inherit;
|
||||
font-weight: var(--font-weight-medium);
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
button.m02-dfpanel-chip {
|
||||
@@ -102,22 +80,11 @@ button.m02-dfpanel-chip:focus-visible {
|
||||
outline: 2px solid var(--color-focus-ring);
|
||||
}
|
||||
|
||||
.m02-dfpanel-chip.is-in {
|
||||
border-color: #3b82f6;
|
||||
}
|
||||
|
||||
.m02-dfpanel-chip.is-in:not(.is-placed) {
|
||||
border-color: var(--badge-tone);
|
||||
border-style: dashed;
|
||||
}
|
||||
|
||||
.m02-dfpanel-chip.is-out {
|
||||
border-color: #27ae60;
|
||||
}
|
||||
|
||||
.m02-dfpanel-chip.is-var {
|
||||
border-color: #d99a00;
|
||||
}
|
||||
|
||||
/* 판 높이 크게 — 안쪽 세로 스크롤 없이 보이게 */
|
||||
.m02-dfpanel-sheet {
|
||||
position: relative;
|
||||
@@ -129,15 +96,15 @@ button.m02-dfpanel-chip:focus-visible {
|
||||
|
||||
/* 칸 위 표시 — 색 + 글자(받음 · 변수 · 출력) 둘 다 */
|
||||
.m02-dfpanel .aislo-cell[data-cf-kind="in"] {
|
||||
box-shadow: inset 0 0 0 2px #3b82f6;
|
||||
box-shadow: inset 0 0 0 2px var(--color-info);
|
||||
}
|
||||
|
||||
.m02-dfpanel .aislo-cell[data-cf-kind="var"] {
|
||||
box-shadow: inset 0 0 0 2px #d99a00;
|
||||
box-shadow: inset 0 0 0 2px var(--color-warning);
|
||||
}
|
||||
|
||||
.m02-dfpanel .aislo-cell[data-cf-kind="out"] {
|
||||
box-shadow: inset 0 0 0 2px #27ae60;
|
||||
box-shadow: inset 0 0 0 2px var(--color-success);
|
||||
}
|
||||
|
||||
.m02-dfpanel .aislo-cell[data-cf-kind]::after {
|
||||
@@ -196,20 +163,6 @@ button.m02-dfpanel-chip:focus-visible {
|
||||
font-weight: var(--font-weight-bold);
|
||||
}
|
||||
|
||||
.m02-dfcells__table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: var(--text-body-sm);
|
||||
}
|
||||
|
||||
.m02-dfcells__table th,
|
||||
.m02-dfcells__table td {
|
||||
padding: var(--spacing-4);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
text-align: left;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.m02-dfcells__cell {
|
||||
width: 5em;
|
||||
}
|
||||
@@ -219,34 +172,15 @@ button.m02-dfpanel-chip:focus-visible {
|
||||
border-style: dashed;
|
||||
}
|
||||
|
||||
.m02-dfcells__kind {
|
||||
padding: 0 var(--spacing-8);
|
||||
border: 2px solid;
|
||||
border-radius: var(--radius-pills);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.m02-dfcells__row.is-in .m02-dfcells__kind {
|
||||
border-color: #3b82f6;
|
||||
}
|
||||
|
||||
.m02-dfcells__row.is-var .m02-dfcells__kind {
|
||||
border-color: #d99a00;
|
||||
}
|
||||
|
||||
.m02-dfcells__row.is-out .m02-dfcells__kind {
|
||||
border-color: #27ae60;
|
||||
}
|
||||
/* 칸 종류 = 배지 부품(받음 info · 변수 warning · 출력 success) */
|
||||
|
||||
/* 식 보기 */
|
||||
.m02-df-formula {
|
||||
/* 겉 = 카드 부품 · 여기는 쌓기 · 안 여백만 */
|
||||
.m02-df-formula.ui-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-4);
|
||||
padding: var(--spacing-8) var(--spacing-12);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-cards);
|
||||
background: var(--color-surface-raised);
|
||||
}
|
||||
|
||||
.m02-df-formula__title {
|
||||
@@ -274,8 +208,3 @@ button.m02-dfpanel-chip:focus-visible {
|
||||
.m02-df-formula__branches .is-now {
|
||||
font-weight: var(--font-weight-bold);
|
||||
}
|
||||
|
||||
.m02-df-formula__empty {
|
||||
margin: 0;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,9 @@ import { createRoundRow } from "./M02_DF_RoundRow";
|
||||
import { createUnitPick, suggestPlaces } from "./M02_DF_UnitPick";
|
||||
import { ERR_KEY, FRAMES, TEXT, tf } from "./M02_DF_FuncText";
|
||||
import "./M02_DF_FuncPanel.css";
|
||||
import "@ui/ui_template_text.css";
|
||||
import "@ui/ui_template_banner.css";
|
||||
import "@ui/ui_template_badge.css";
|
||||
|
||||
type Handlers = { change(lg: CfLogic): void };
|
||||
|
||||
@@ -261,10 +264,14 @@ function drawHead(st: State): void {
|
||||
});
|
||||
st.parts.head.replaceChildren(
|
||||
el("strong", { className: "m02-dfpanel-title", text: box?.name ?? "" }),
|
||||
el("span", { className: "m02-dfpanel-cell", text: `${tf("Cell")} ${st.cell}` }),
|
||||
el("span", {
|
||||
className: "ui-badge ui-badge--pill ui-badge--neutral",
|
||||
attrs: { "data-size": "24" },
|
||||
text: `${tf("Cell")} ${st.cell}`,
|
||||
}),
|
||||
el("label", {
|
||||
className: "m02-dfpanel-unitbox",
|
||||
children: [el("span", { className: "m02-dfpanel-note", text: tf("Unit") }), unit],
|
||||
children: [el("span", { className: "ui-text ui-text--muted", text: tf("Unit") }), unit],
|
||||
}),
|
||||
);
|
||||
}
|
||||
@@ -275,9 +282,9 @@ function drawGot(st: State): void {
|
||||
const chips = items.map(({ port, unit }) => {
|
||||
const at = f?.inputs.find((i) => i.port === port)?.cell;
|
||||
const b = el("button", {
|
||||
className: `m02-dfpanel-chip is-in${at ? " is-placed" : ""}`,
|
||||
className: `ui-badge ui-badge--pill ui-badge--info m02-dfpanel-chip is-in${at ? " is-placed" : ""}`,
|
||||
text: `${port} (${unit}) · ${at ? `${tf("Placed")} ${at}` : tf("Free")}`,
|
||||
attrs: { type: "button", draggable: st.readOnly ? "false" : "true" },
|
||||
attrs: { type: "button", "data-size": "24", draggable: st.readOnly ? "false" : "true" },
|
||||
});
|
||||
b.addEventListener("click", () => placePort(st, port, st.cell));
|
||||
b.addEventListener("dragstart", (e) => e.dataTransfer?.setData("text/plain", port));
|
||||
@@ -285,9 +292,11 @@ function drawGot(st: State): void {
|
||||
});
|
||||
st.parts.got.replaceChildren(
|
||||
el("span", { className: "m02-dfpanel-label", text: tf("Got") }),
|
||||
...(chips.length ? chips : [el("span", { className: "m02-dfpanel-note", text: tf("NoGot") })]),
|
||||
...(chips.length
|
||||
? chips
|
||||
: [el("span", { className: "ui-text ui-text--muted", text: tf("NoGot") })]),
|
||||
...(chips.length && !st.readOnly
|
||||
? [el("span", { className: "m02-dfpanel-note", text: tf("GotHint") })]
|
||||
? [el("span", { className: "ui-text ui-text--muted", text: tf("GotHint") })]
|
||||
: []),
|
||||
);
|
||||
}
|
||||
@@ -303,7 +312,7 @@ function formField(
|
||||
return el("label", {
|
||||
className: "m02-dfpanel-fieldbox",
|
||||
children: [
|
||||
el("span", { className: "m02-dfpanel-note", text: tf(label) }),
|
||||
el("span", { className: "ui-text ui-text--muted", text: tf(label) }),
|
||||
createUnitPick({
|
||||
value: form.unit || "-",
|
||||
ariaLabel: tf(label),
|
||||
@@ -321,7 +330,7 @@ function formField(
|
||||
input.addEventListener("keydown", (e) => e.key === "Enter" && makeVariable(st));
|
||||
return el("label", {
|
||||
className: "m02-dfpanel-fieldbox",
|
||||
children: [el("span", { className: "m02-dfpanel-note", text: tf(label) }), input],
|
||||
children: [el("span", { className: "ui-text ui-text--muted", text: tf(label) }), input],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -330,7 +339,8 @@ function drawVars(st: State): void {
|
||||
const row: HTMLElement[] = [el("span", { className: "m02-dfpanel-label", text: tf("Vars") })];
|
||||
for (const v of f?.variables ?? []) {
|
||||
const chip = el("span", {
|
||||
className: "m02-dfpanel-chip is-var",
|
||||
className: "ui-badge ui-badge--pill ui-badge--warning m02-dfpanel-chip is-var",
|
||||
attrs: { "data-size": "24" },
|
||||
children: [`${v.name} (${v.unit}) · ${v.cell ?? ""}`],
|
||||
});
|
||||
if (!st.readOnly) {
|
||||
@@ -351,7 +361,7 @@ function drawVars(st: State): void {
|
||||
row.push(chip);
|
||||
}
|
||||
if (!f?.variables.length)
|
||||
row.push(el("span", { className: "m02-dfpanel-note", text: tf("NoVars") }));
|
||||
row.push(el("span", { className: "ui-text ui-text--muted", text: tf("NoVars") }));
|
||||
const parts: HTMLElement[] = [el("div", { className: "m02-dfpanel-row", children: row })];
|
||||
if (!st.readOnly) {
|
||||
const form = st.form;
|
||||
@@ -400,12 +410,15 @@ function drawVars(st: State): void {
|
||||
});
|
||||
parts.push(
|
||||
el("div", {
|
||||
className: "m02-dfpanel-row m02-dfpanel-form",
|
||||
className: "ui-card m02-dfpanel-row m02-dfpanel-form",
|
||||
children: [
|
||||
formField(st, "VarName", "name"),
|
||||
el("label", {
|
||||
className: "m02-dfpanel-fieldbox",
|
||||
children: [el("span", { className: "m02-dfpanel-note", text: tf("VarType") }), type],
|
||||
children: [
|
||||
el("span", { className: "ui-text ui-text--muted", text: tf("VarType") }),
|
||||
type,
|
||||
],
|
||||
}),
|
||||
formField(st, "VarUnit", "unit"),
|
||||
...(form.type === "number"
|
||||
@@ -413,7 +426,11 @@ function drawVars(st: State): void {
|
||||
: []),
|
||||
...(form.type === "choice" ? [formField(st, "VarChoices", "choices")] : []),
|
||||
formField(st, "VarExample", "example"),
|
||||
el("span", { className: "m02-dfpanel-cell", text: `${tf("VarCell")} ${st.cell}` }),
|
||||
el("span", {
|
||||
className: "ui-badge ui-badge--pill ui-badge--neutral",
|
||||
attrs: { "data-size": "24" },
|
||||
text: `${tf("VarCell")} ${st.cell}`,
|
||||
}),
|
||||
createButton({
|
||||
label: tf("Make"),
|
||||
variant: "filled",
|
||||
@@ -427,7 +444,7 @@ function drawVars(st: State): void {
|
||||
onClick: () => ((st.form = null), drawVars(st)),
|
||||
}),
|
||||
...(form.why
|
||||
? [el("span", { className: "m02-dfpanel-why", text: `⚠ ${form.why}` })]
|
||||
? [el("span", { className: "ui-text ui-text--warning", text: `⚠ ${form.why}` })]
|
||||
: []),
|
||||
],
|
||||
}),
|
||||
@@ -441,7 +458,7 @@ function drawBar(st: State): void {
|
||||
const f = funcOf(st);
|
||||
if (st.readOnly) {
|
||||
st.parts.bar.replaceChildren(
|
||||
el("span", { className: "m02-dfpanel-note", text: tf("ReadOnly") }),
|
||||
el("span", { className: "ui-text ui-text--muted", text: tf("ReadOnly") }),
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -456,8 +473,12 @@ function drawBar(st: State): void {
|
||||
size: "sm",
|
||||
onClick: () => setOutput(st, st.cell),
|
||||
}),
|
||||
el("span", { className: "m02-dfpanel-chip is-out", text: outNow }),
|
||||
el("span", { className: "m02-dfpanel-note", text: tf("OutOnly") }),
|
||||
el("span", {
|
||||
className: "ui-badge ui-badge--pill ui-badge--success m02-dfpanel-chip is-out",
|
||||
attrs: { "data-size": "24" },
|
||||
text: outNow,
|
||||
}),
|
||||
el("span", { className: "ui-text ui-text--muted", text: tf("OutOnly") }),
|
||||
],
|
||||
}),
|
||||
...(f?.output.cell
|
||||
@@ -482,7 +503,7 @@ function drawBar(st: State): void {
|
||||
onClick: () => putFormula(st, formula),
|
||||
}),
|
||||
),
|
||||
el("span", { className: "m02-dfpanel-note", text: tf("FrameHint") }),
|
||||
el("span", { className: "ui-text ui-text--muted", text: tf("FrameHint") }),
|
||||
],
|
||||
}),
|
||||
);
|
||||
@@ -647,7 +668,10 @@ export function renderFuncPanel(
|
||||
got: el("div", { className: "m02-dfpanel-row" }),
|
||||
vars: el("div", { className: "m02-dfpanel-vars" }),
|
||||
bar: el("div", { className: "m02-dfpanel-bar" }),
|
||||
msg: el("p", { className: "m02-dfpanel-msg", attrs: { role: "status" } }),
|
||||
msg: el("p", {
|
||||
className: "ui-banner ui-banner--warning m02-dfpanel-msg",
|
||||
attrs: { role: "status" },
|
||||
}),
|
||||
sheet: el("div", { className: "m02-dfpanel-sheet", text: tf("Loading") }),
|
||||
};
|
||||
const st: State = {
|
||||
|
||||
@@ -42,31 +42,9 @@
|
||||
flex-wrap: wrap;
|
||||
gap: var(--spacing-8);
|
||||
}
|
||||
.m02-dfip__chip,
|
||||
.m02-dfip__row {
|
||||
/* 고르는 줄 = 목록 줄 부품(ui-list-row) — 여기는 안 여백 · 두 칸 벌림만 */
|
||||
button.m02-dfip__row {
|
||||
padding: var(--spacing-8) var(--spacing-12);
|
||||
border: 2px solid var(--color-border);
|
||||
border-radius: var(--radius-sm);
|
||||
background: var(--color-surface);
|
||||
color: var(--color-text);
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
.m02-dfip__chip {
|
||||
border-radius: var(--radius-pills);
|
||||
padding: var(--spacing-4) var(--spacing-12);
|
||||
}
|
||||
.m02-dfip__chip.is-on {
|
||||
border-color: var(--color-accent);
|
||||
outline: 2px solid var(--color-accent);
|
||||
}
|
||||
.m02-dfip__chip:hover,
|
||||
.m02-dfip__chip:focus-visible,
|
||||
.m02-dfip__row:hover,
|
||||
.m02-dfip__row:focus-visible {
|
||||
border-color: var(--color-accent);
|
||||
}
|
||||
.m02-dfip__row {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
gap: var(--spacing-8);
|
||||
@@ -104,12 +82,9 @@
|
||||
.m02-dfip__value {
|
||||
color: var(--color-accent);
|
||||
}
|
||||
.m02-dfip__tag {
|
||||
/* 태그 = 배지 부품 — 이름 뒤 띄움만 */
|
||||
.m02-dfip__name .ui-badge {
|
||||
margin-left: var(--spacing-8);
|
||||
padding: 0 var(--spacing-8);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-pills);
|
||||
font-size: var(--text-caption);
|
||||
}
|
||||
.m02-dfip__new,
|
||||
.m02-dfip__form {
|
||||
@@ -124,19 +99,17 @@
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
}
|
||||
/* 미리 보기 = 표 부품 데이터표 — 여기는 줄바꿈 막기 · 가운데 · 찾은 줄만 */
|
||||
.m02-dfip__preview table {
|
||||
border-collapse: collapse;
|
||||
font-size: var(--text-body-sm);
|
||||
width: auto;
|
||||
}
|
||||
.m02-dfip__preview th,
|
||||
.m02-dfip__preview td {
|
||||
padding: 2px 8px;
|
||||
border: 1px solid var(--color-border);
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
}
|
||||
.m02-dfip__preview tr.is-hit td {
|
||||
background: rgba(240, 190, 40, 0.35);
|
||||
background: color-mix(in srgb, var(--color-warning) 35%, transparent);
|
||||
font-weight: 700;
|
||||
}
|
||||
.m02-dfip__preview {
|
||||
|
||||
@@ -38,6 +38,10 @@ import { renderMaterial } from "./M02_DF_InputPanel_Material";
|
||||
import { renderTablePick } from "./M02_DF_InputPanel_Table";
|
||||
import { renderVariables } from "./M02_DF_InputPanel_Vars";
|
||||
import "./M02_DF_InputPanel.css";
|
||||
import "@ui/ui_template_text.css";
|
||||
import "@ui/ui_template_badge.css";
|
||||
import "@ui/ui_template_list_row.css";
|
||||
import "@ui/ui_template_toolbar.css";
|
||||
|
||||
/** Api 모양 — 서버 Api 가 채워지면(사용자 요소 = Model 모양 · 값 물음 = ref) 그 모양을 그대로 씀 */
|
||||
interface Answer {
|
||||
@@ -125,7 +129,7 @@ export function renderInputPanel(
|
||||
host.className = "m02-dfip";
|
||||
const box = lg.boxes.find((b) => b.id === boxId);
|
||||
if (!box || box.kind !== "input") {
|
||||
host.replaceChildren(el("p", { className: "m02-dfip__muted", text: t("NotInput") }));
|
||||
host.replaceChildren(el("p", { className: "ui-text ui-text--muted", text: t("NotInput") }));
|
||||
return;
|
||||
}
|
||||
// 상자 단위가 고른 요소 · 변수 단위와 다르면(견본 등) 맞춰 다시 그림 — 맞으면 바로 지나감
|
||||
@@ -246,7 +250,15 @@ function drawChosen(
|
||||
el("span", {
|
||||
className: "m02-dfip__name",
|
||||
children: [
|
||||
...(rule ? [el("span", { className: "m02-dfip__tag", text: t("RuleTag") })] : []),
|
||||
...(rule
|
||||
? [
|
||||
el("span", {
|
||||
className: "ui-badge ui-badge--pill ui-badge--neutral",
|
||||
attrs: { "data-size": "20" },
|
||||
text: t("RuleTag"),
|
||||
}),
|
||||
]
|
||||
: []),
|
||||
el("strong", { text: ` ${e.name}` }),
|
||||
...(rule && e.rule
|
||||
? [
|
||||
@@ -274,7 +286,7 @@ function drawChosen(
|
||||
],
|
||||
});
|
||||
})
|
||||
: [el("p", { className: "m02-dfip__muted", text: t("NoneChosen") })]),
|
||||
: [el("p", { className: "ui-text ui-text--muted", text: t("NoneChosen") })]),
|
||||
);
|
||||
const items = els
|
||||
.filter((e) => e.mode !== "rule")
|
||||
@@ -331,7 +343,7 @@ async function drawFind(
|
||||
let seq = 0;
|
||||
const load = async (): Promise<void> => {
|
||||
const mine = ++seq;
|
||||
list.replaceChildren(el("p", { className: "m02-dfip__muted", text: t("Loading") }));
|
||||
list.replaceChildren(el("p", { className: "ui-text ui-text--muted", text: t("Loading") }));
|
||||
try {
|
||||
const word = q.input.value.trim();
|
||||
const page = await fetchRows(file, 1, 40, word, false, sub, detail);
|
||||
@@ -341,11 +353,11 @@ async function drawFind(
|
||||
list.replaceChildren(
|
||||
...(rows.length
|
||||
? rows.map((r) => rowOf(r))
|
||||
: [el("p", { className: "m02-dfip__muted", text: t("NoRow") })]),
|
||||
: [el("p", { className: "ui-text ui-text--muted", text: t("NoRow") })]),
|
||||
);
|
||||
} catch (e) {
|
||||
if (mine === seq)
|
||||
list.replaceChildren(el("p", { className: "m02-dfip__muted", text: plain(e) }));
|
||||
list.replaceChildren(el("p", { className: "ui-text ui-text--muted", text: plain(e) }));
|
||||
}
|
||||
};
|
||||
const rowOf = (r: M01Row): HTMLElement => {
|
||||
@@ -361,7 +373,7 @@ async function drawFind(
|
||||
const v = valueOf(group, r, field.select.value || "가격");
|
||||
const unitText = group === "기계" ? "" : String(r["단위"] ?? "");
|
||||
const b = el("button", {
|
||||
className: "m02-dfip__row",
|
||||
className: "m02-dfip__row ui-list-row ui-sidebar-row",
|
||||
attrs: { type: "button" },
|
||||
children: [
|
||||
el("span", {
|
||||
@@ -390,7 +402,7 @@ async function drawFind(
|
||||
subBox.root.hidden = !subs.length;
|
||||
bar.push(subBox.root, detailBox.root);
|
||||
} catch (e) {
|
||||
host.replaceChildren(el("p", { className: "m02-dfip__muted", text: plain(e) }));
|
||||
host.replaceChildren(el("p", { className: "ui-text ui-text--muted", text: plain(e) }));
|
||||
return;
|
||||
}
|
||||
let timer = 0;
|
||||
@@ -399,7 +411,7 @@ async function drawFind(
|
||||
() => (window.clearTimeout(timer), (timer = window.setTimeout(load, 250))),
|
||||
);
|
||||
host.replaceChildren(
|
||||
el("div", { className: "m02-dfip__bar", children: [...bar, q.root] }),
|
||||
el("div", { className: "ui-toolbar m02-dfip__bar", children: [...bar, q.root] }),
|
||||
count,
|
||||
list,
|
||||
);
|
||||
|
||||
@@ -35,6 +35,10 @@ import {
|
||||
wouldCycle,
|
||||
type MasterLogicBrief,
|
||||
} from "./M02_DF_InputPanel_Build";
|
||||
import "@ui/ui_template_text.css";
|
||||
import "@ui/ui_template_badge.css";
|
||||
import "@ui/ui_template_list_row.css";
|
||||
import "@ui/ui_template_toolbar.css";
|
||||
|
||||
const TEXT = {
|
||||
Help: [
|
||||
@@ -183,7 +187,7 @@ export function renderLogicInput(
|
||||
...(shown.length
|
||||
? shown.map((i) => {
|
||||
const b = el("button", {
|
||||
className: "m02-dfip__row",
|
||||
className: "m02-dfip__row ui-list-row ui-sidebar-row",
|
||||
attrs: {
|
||||
type: "button",
|
||||
...(i.blocked ? { disabled: "true", title: (i.reasons ?? []).join(" · ") } : {}),
|
||||
@@ -200,7 +204,8 @@ export function renderLogicInput(
|
||||
text: ` ${aliasNote(matchLogic(q.input.value, i).alias)}`,
|
||||
}),
|
||||
el("span", {
|
||||
className: "m02-dfip__tag",
|
||||
className: "ui-badge ui-badge--pill ui-badge--neutral",
|
||||
attrs: { "data-size": "20" },
|
||||
text: i.blocked ? t("Blocked") : i.상세구분,
|
||||
}),
|
||||
],
|
||||
@@ -211,7 +216,7 @@ export function renderLogicInput(
|
||||
b.addEventListener("click", () => void pick(i));
|
||||
return b;
|
||||
})
|
||||
: [el("p", { className: "m02-dfip__muted", text: t("None") })]),
|
||||
: [el("p", { className: "ui-text ui-text--muted", text: t("None") })]),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -253,10 +258,13 @@ export function renderLogicInput(
|
||||
window.clearTimeout(timer);
|
||||
timer = window.setTimeout(() => ((page = 1), draw()), 200);
|
||||
});
|
||||
list.replaceChildren(el("p", { className: "m02-dfip__muted", text: t("Loading") }));
|
||||
list.replaceChildren(el("p", { className: "ui-text ui-text--muted", text: t("Loading") }));
|
||||
host.replaceChildren(
|
||||
el("p", { className: "m02-dfip__muted", text: t("Help") }),
|
||||
el("div", { className: "m02-dfip__bar", children: [bookBox.root, chapterBox.root, q.root] }),
|
||||
el("p", { className: "ui-text ui-text--muted", text: t("Help") }),
|
||||
el("div", {
|
||||
className: "ui-toolbar m02-dfip__bar",
|
||||
children: [bookBox.root, chapterBox.root, q.root],
|
||||
}),
|
||||
info,
|
||||
list,
|
||||
el("div", { className: "m02-dfip__chips", children: [prev, next] }),
|
||||
@@ -268,7 +276,7 @@ export function renderLogicInput(
|
||||
fillChapters();
|
||||
draw();
|
||||
},
|
||||
(e) => list.replaceChildren(el("p", { className: "m02-dfip__muted", text: plain(e) })),
|
||||
(e) => list.replaceChildren(el("p", { className: "ui-text ui-text--muted", text: plain(e) })),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -282,7 +290,7 @@ function showChosen(
|
||||
): void {
|
||||
const read = readNotes.get(ref.key);
|
||||
const values = new Map<string, HTMLElement>();
|
||||
const errors = el("p", { className: "m02-dfip__muted is-bad" });
|
||||
const errors = el("p", { className: "ui-text ui-text--error" });
|
||||
const line = (name: string, unit: string, valueNode?: HTMLElement, extra = ""): HTMLElement =>
|
||||
el("div", {
|
||||
className: "m02-dfip__item",
|
||||
@@ -300,7 +308,7 @@ function showChosen(
|
||||
el("h5", { text: `${t("Chosen")} — ${ref.name ?? ref.key}` }),
|
||||
...(read?.converted
|
||||
? [
|
||||
el("p", { className: "m02-dfip__muted", text: t("Converted") }),
|
||||
el("p", { className: "ui-text ui-text--muted", text: t("Converted") }),
|
||||
...(read.notes.length
|
||||
? [
|
||||
el("details", {
|
||||
@@ -320,14 +328,14 @@ function showChosen(
|
||||
values.set(o.name, v);
|
||||
return line(o.name, o.unit, v);
|
||||
})
|
||||
: [el("p", { className: "m02-dfip__muted", text: t("NoOut") })]),
|
||||
: [el("p", { className: "ui-text ui-text--muted", text: t("NoOut") })]),
|
||||
errors,
|
||||
el("h5", { text: `${t("Designs")} · ${ref.designs.length}` }),
|
||||
...(ref.designs.length
|
||||
? ref.designs.map((d) =>
|
||||
line(d.name, d.unit, undefined, String(ref.examples?.[d.name] ?? "")),
|
||||
)
|
||||
: [el("p", { className: "m02-dfip__muted", text: t("NoDesign") })]),
|
||||
: [el("p", { className: "ui-text ui-text--muted", text: t("NoDesign") })]),
|
||||
el("div", {
|
||||
className: "m02-dfip__chips",
|
||||
children: [
|
||||
|
||||
@@ -30,6 +30,10 @@ import {
|
||||
variablePills,
|
||||
type MatItem,
|
||||
} from "./M02_DF_InputPanel_Build";
|
||||
import "@ui/ui_template_text.css";
|
||||
import "@ui/ui_template_badge.css";
|
||||
import "@ui/ui_template_list_row.css";
|
||||
import "@ui/ui_template_toolbar.css";
|
||||
|
||||
const TEXT = {
|
||||
Chosen: ["넣은 재료 — 알약마다 이름 · 값 · 단위", "Chosen materials"],
|
||||
@@ -159,7 +163,10 @@ function scopeBoxes(
|
||||
() => undefined,
|
||||
);
|
||||
return {
|
||||
root: el("div", { className: "m02-dfip__bar", children: [subBox.root, detailBox.root] }),
|
||||
root: el("div", {
|
||||
className: "ui-toolbar m02-dfip__bar",
|
||||
children: [subBox.root, detailBox.root],
|
||||
}),
|
||||
get: () => ({ ...state }),
|
||||
};
|
||||
}
|
||||
@@ -190,7 +197,7 @@ function itemList(
|
||||
});
|
||||
const load = async (): Promise<void> => {
|
||||
const mine = ++seq;
|
||||
list.replaceChildren(el("p", { className: "m02-dfip__muted", text: t("Loading") }));
|
||||
list.replaceChildren(el("p", { className: "ui-text ui-text--muted", text: t("Loading") }));
|
||||
try {
|
||||
const r = await searchMaterials({ q: q.input.value.trim(), ...scope(), page, size: 12 });
|
||||
if (mine !== seq) return;
|
||||
@@ -208,7 +215,7 @@ function itemList(
|
||||
...(r.items.length
|
||||
? r.items.map((it) => {
|
||||
const b = el("button", {
|
||||
className: "m02-dfip__row",
|
||||
className: "m02-dfip__row ui-list-row ui-sidebar-row",
|
||||
attrs: { type: "button" },
|
||||
children: [
|
||||
el("span", {
|
||||
@@ -227,11 +234,11 @@ function itemList(
|
||||
b.addEventListener("click", () => onPick(it));
|
||||
return b;
|
||||
})
|
||||
: [el("p", { className: "m02-dfip__muted", text: t("NoRow") })]),
|
||||
: [el("p", { className: "ui-text ui-text--muted", text: t("NoRow") })]),
|
||||
);
|
||||
} catch {
|
||||
if (mine === seq)
|
||||
list.replaceChildren(el("p", { className: "m02-dfip__muted", text: t("Failed") }));
|
||||
list.replaceChildren(el("p", { className: "ui-text ui-text--muted", text: t("Failed") }));
|
||||
}
|
||||
};
|
||||
let timer = 0;
|
||||
@@ -398,9 +405,13 @@ export function renderMaterial(
|
||||
el("span", {
|
||||
className: "m02-dfip__name",
|
||||
children: [
|
||||
el("span", { className: "m02-dfip__tag", text: kind }),
|
||||
el("span", {
|
||||
className: "ui-badge ui-badge--pill ui-badge--neutral",
|
||||
attrs: { "data-size": "20" },
|
||||
text: kind,
|
||||
}),
|
||||
el("strong", { text: ` ${e.name}` }),
|
||||
el("div", { className: "m02-dfip__muted", text: summaryOf(e, lg) }),
|
||||
el("div", { className: "ui-text ui-text--muted", text: summaryOf(e, lg) }),
|
||||
note,
|
||||
],
|
||||
}),
|
||||
@@ -435,7 +446,7 @@ export function renderMaterial(
|
||||
);
|
||||
return row;
|
||||
})
|
||||
: [el("p", { className: "m02-dfip__muted", text: t("None") })]),
|
||||
: [el("p", { className: "ui-text ui-text--muted", text: t("None") })]),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -455,7 +466,7 @@ export function renderMaterial(
|
||||
const drawBody = (): void => {
|
||||
if (mode === "fixed") {
|
||||
body.replaceChildren(
|
||||
el("p", { className: "m02-dfip__muted", text: t("FixedHelp") }),
|
||||
el("p", { className: "ui-text ui-text--muted", text: t("FixedHelp") }),
|
||||
itemList((it) =>
|
||||
on.change(
|
||||
addEl(lg, {
|
||||
@@ -520,7 +531,7 @@ export function renderMaterial(
|
||||
onChange: (v) => ((how = v as "plain" | "template"), drawBody()),
|
||||
});
|
||||
const tpl = templateBox(lg, () => void refresh());
|
||||
const defNote = el("p", { className: "m02-dfip__muted" });
|
||||
const defNote = el("p", { className: "ui-text ui-text--muted" });
|
||||
const build = (): CfElementRef => {
|
||||
const sc = scope.get();
|
||||
if (mode === "rule" && howBox.select.value === "template") {
|
||||
@@ -603,7 +614,7 @@ export function renderMaterial(
|
||||
? [tpl.root]
|
||||
: pills.length
|
||||
? [fieldBox.root, opBox.root, pillBox.root]
|
||||
: [el("p", { className: "m02-dfip__muted is-bad", text: t("NoPill") })]),
|
||||
: [el("p", { className: "ui-text ui-text--error", text: t("NoPill") })]),
|
||||
]
|
||||
: [
|
||||
el("h5", { text: t("Default") }),
|
||||
|
||||
@@ -21,6 +21,10 @@ import {
|
||||
variablePills,
|
||||
type GroupRuleField,
|
||||
} from "./M02_DF_InputPanel_Build";
|
||||
import "@ui/ui_template_text.css";
|
||||
import "@ui/ui_template_badge.css";
|
||||
import "@ui/ui_template_list_row.css";
|
||||
import "@ui/ui_template_toolbar.css";
|
||||
|
||||
const TEXT = {
|
||||
Help: [
|
||||
@@ -128,11 +132,11 @@ export function renderGroupRule(
|
||||
},
|
||||
});
|
||||
host.replaceChildren(
|
||||
el("p", { className: "m02-dfip__muted", text: t("Help") }),
|
||||
el("p", { className: "ui-text ui-text--muted", text: t("Help") }),
|
||||
name.root,
|
||||
...(pills.length
|
||||
? [field.root, pill.root, note, add]
|
||||
: [el("p", { className: "m02-dfip__muted is-bad", text: t("NoPill") })]),
|
||||
: [el("p", { className: "ui-text ui-text--error", text: t("NoPill") })]),
|
||||
);
|
||||
if (pills.length) void refresh();
|
||||
}
|
||||
|
||||
@@ -15,6 +15,11 @@ import {
|
||||
} from "@ui/ui_template_elements";
|
||||
import type { CfGroup, CfLogic } from "./M02_DF_Model";
|
||||
import { setTable } from "./M02_DF_InputPanel_Build";
|
||||
import "@ui/ui_template_text.css";
|
||||
import "@ui/ui_template_badge.css";
|
||||
import "@ui/ui_template_list_row.css";
|
||||
import "@ui/ui_template_toolbar.css";
|
||||
import "@ui/ui_template_table.css";
|
||||
|
||||
const TEXT = {
|
||||
Book: ["적용 품셈", "Standard"],
|
||||
@@ -120,6 +125,7 @@ function previewOf(tb: RawTable, row?: number): HTMLElement {
|
||||
className: "m02-dfip__preview",
|
||||
children: [
|
||||
el("table", {
|
||||
className: "ui-table ui-table--data",
|
||||
children: [
|
||||
el("tr", { children: cols.map((c) => el("th", { text: c })) }),
|
||||
...body.map((r, i) =>
|
||||
@@ -131,7 +137,7 @@ function previewOf(tb: RawTable, row?: number): HTMLElement {
|
||||
],
|
||||
}),
|
||||
...(tb.줄.length > body.length
|
||||
? [el("p", { className: "m02-dfip__muted", text: `… ${tb.줄.length} 줄` })]
|
||||
? [el("p", { className: "ui-text ui-text--muted", text: `… ${tb.줄.length} 줄` })]
|
||||
: []),
|
||||
...(tb.주?.length
|
||||
? [
|
||||
@@ -172,7 +178,7 @@ export function renderTablePick(
|
||||
let seq = 0;
|
||||
const load = async (): Promise<void> => {
|
||||
const mine = ++seq;
|
||||
list.replaceChildren(el("p", { className: "m02-dfip__muted", text: t("Loading") }));
|
||||
list.replaceChildren(el("p", { className: "ui-text ui-text--muted", text: t("Loading") }));
|
||||
try {
|
||||
const r = await get<{ sections: SectionItem[] }>("/sections", {
|
||||
book,
|
||||
@@ -184,7 +190,7 @@ export function renderTablePick(
|
||||
...(r.sections.length
|
||||
? r.sections.map((s) => {
|
||||
const b = el("button", {
|
||||
className: "m02-dfip__row",
|
||||
className: "m02-dfip__row ui-list-row ui-sidebar-row",
|
||||
attrs: { type: "button" },
|
||||
children: [
|
||||
el("strong", { text: `${s.section} ${s.title}` }),
|
||||
@@ -197,7 +203,7 @@ export function renderTablePick(
|
||||
b.addEventListener("click", () => void pickSection(s));
|
||||
return b;
|
||||
})
|
||||
: [el("p", { className: "m02-dfip__muted", text: t("NoSection") })]),
|
||||
: [el("p", { className: "ui-text ui-text--muted", text: t("NoSection") })]),
|
||||
);
|
||||
} catch (e) {
|
||||
if (mine === seq) showToast(e instanceof Error ? e.message : t("Failed"), "error");
|
||||
@@ -218,7 +224,7 @@ export function renderTablePick(
|
||||
...(heads.length
|
||||
? heads.map((h) => {
|
||||
const b = el("button", {
|
||||
className: "m02-dfip__row",
|
||||
className: "m02-dfip__row ui-list-row ui-sidebar-row",
|
||||
attrs: { type: "button" },
|
||||
children: [
|
||||
el("strong", { text: h.이름 }),
|
||||
@@ -242,7 +248,7 @@ export function renderTablePick(
|
||||
});
|
||||
return b;
|
||||
})
|
||||
: [el("p", { className: "m02-dfip__muted", text: t("NoTable") })]),
|
||||
: [el("p", { className: "ui-text ui-text--muted", text: t("NoTable") })]),
|
||||
);
|
||||
} catch (e) {
|
||||
showToast(e instanceof Error ? e.message : t("Failed"), "error");
|
||||
|
||||
@@ -8,6 +8,10 @@ import { currentLanguageIndex } from "@ui/ui_template_locale";
|
||||
import { createInputField, createSelectField, el } from "@ui/ui_template_elements";
|
||||
import type { CfLogic, CfPort } from "./M02_DF_Model";
|
||||
import { templateSlots, variablePills } from "./M02_DF_InputPanel_Build";
|
||||
import "@ui/ui_template_text.css";
|
||||
import "@ui/ui_template_badge.css";
|
||||
import "@ui/ui_template_list_row.css";
|
||||
import "@ui/ui_template_toolbar.css";
|
||||
|
||||
const TEXT = {
|
||||
Template: ["검색어 틀 — 자리는 {이름} 으로", "Search template — slots as {name}"],
|
||||
@@ -68,8 +72,8 @@ export function templateBox(lg: CfLogic, onChange: () => void): TemplateBox {
|
||||
picks.set(n, sel.select);
|
||||
return sel.root;
|
||||
})
|
||||
: [el("p", { className: "m02-dfip__muted is-bad", text: t("NoPill") })]
|
||||
: [el("p", { className: "m02-dfip__muted", text: t("NoSlot") })]),
|
||||
: [el("p", { className: "ui-text ui-text--error", text: t("NoPill") })]
|
||||
: [el("p", { className: "ui-text ui-text--muted", text: t("NoSlot") })]),
|
||||
);
|
||||
};
|
||||
tpl.input.addEventListener("input", () => (draw(), onChange()));
|
||||
@@ -77,7 +81,11 @@ export function templateBox(lg: CfLogic, onChange: () => void): TemplateBox {
|
||||
return {
|
||||
root: el("div", {
|
||||
className: "m02-dfip__stack",
|
||||
children: [el("p", { className: "m02-dfip__muted", text: t("Help") }), tpl.root, slotBox],
|
||||
children: [
|
||||
el("p", { className: "ui-text ui-text--muted", text: t("Help") }),
|
||||
tpl.root,
|
||||
slotBox,
|
||||
],
|
||||
}),
|
||||
get: () => ({
|
||||
template: tpl.input.value.trim(),
|
||||
|
||||
@@ -9,6 +9,10 @@ import { createButton, createInputField, createSelectField, el } from "@ui/ui_te
|
||||
import type { CfLogic, CfVariable } from "./M02_DF_Model";
|
||||
import { NO_UNIT, createUnitPick } from "./M02_DF_UnitPick";
|
||||
import { checkVariable, putVariable, removeVariable } from "./M02_DF_InputPanel_Build";
|
||||
import "@ui/ui_template_text.css";
|
||||
import "@ui/ui_template_badge.css";
|
||||
import "@ui/ui_template_list_row.css";
|
||||
import "@ui/ui_template_toolbar.css";
|
||||
|
||||
const TEXT = {
|
||||
List: ["변수 — 알약마다 하나", "Variables — one pill each"],
|
||||
@@ -201,7 +205,7 @@ export function renderVariables(
|
||||
],
|
||||
}),
|
||||
)
|
||||
: [el("p", { className: "m02-dfip__muted", text: t("None") })];
|
||||
: [el("p", { className: "ui-text ui-text--muted", text: t("None") })];
|
||||
host.replaceChildren(el("h5", { text: t("List") }), ...list, form());
|
||||
};
|
||||
draw();
|
||||
|
||||
@@ -24,24 +24,13 @@
|
||||
font-size: var(--text-body-sm);
|
||||
}
|
||||
|
||||
.m02-dflink-value {
|
||||
padding: 2px var(--spacing-12);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-pills);
|
||||
background: var(--color-surface-raised);
|
||||
font-weight: var(--font-weight-medium);
|
||||
}
|
||||
|
||||
.m02-dflink-num {
|
||||
width: 7em;
|
||||
}
|
||||
|
||||
/* 겉 = 띠 알림 부품 */
|
||||
.m02-dflink-warn {
|
||||
margin: 0;
|
||||
padding: var(--spacing-8) var(--spacing-12);
|
||||
border-left: 4px solid var(--color-warning);
|
||||
background: var(--color-surface-raised);
|
||||
font-weight: var(--font-weight-medium);
|
||||
}
|
||||
|
||||
/* 알약 판 */
|
||||
@@ -72,11 +61,3 @@
|
||||
gap: var(--spacing-8);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.m02-dfpill-rule {
|
||||
padding: 0 var(--spacing-8);
|
||||
border: 1px dashed var(--color-border);
|
||||
border-radius: var(--radius-pills);
|
||||
color: var(--color-text-secondary);
|
||||
font-size: var(--text-body-sm);
|
||||
}
|
||||
|
||||
@@ -36,6 +36,9 @@ import {
|
||||
} from "./M02_DF_Detail";
|
||||
import { suggestPlaces } from "./M02_DF_UnitPick";
|
||||
import "./M02_DF_LinkPanel.css";
|
||||
import "@ui/ui_template_text.css";
|
||||
import "@ui/ui_template_banner.css";
|
||||
import "@ui/ui_template_badge.css";
|
||||
|
||||
const TEXT = {
|
||||
Title: ["선 규칙", "Line rule"],
|
||||
@@ -248,7 +251,8 @@ function lookupEditor(ctx: Ctx, rule: Extract<CfRule, { kind: "lookup" }>): HTML
|
||||
select(ctx, colOpts, rule.col, (v) => put({ col: v }), tk("Take")),
|
||||
),
|
||||
);
|
||||
if (!cols.length) out.push(el("p", { className: "m02-dflink-note", text: tk("NoHeader") }));
|
||||
if (!cols.length)
|
||||
out.push(el("p", { className: "ui-text ui-text--muted", text: tk("NoHeader") }));
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -289,7 +293,7 @@ function gateValue(ctx: Ctx, c: CfGateCond, onPick: (v: number | string) => void
|
||||
if (range && Number.isFinite(n) && (n < range[0] || n > range[1])) {
|
||||
out.push(
|
||||
el("span", {
|
||||
className: "m02-dflink-warn",
|
||||
className: "ui-text ui-text--warning",
|
||||
text: `⚠ ${tk("OutRange", `${range[0]} ~ ${range[1]}`)}`,
|
||||
}),
|
||||
);
|
||||
@@ -302,7 +306,9 @@ function gateEditor(ctx: Ctx, rule: Extract<CfRule, { kind: "gate" }>): HTMLElem
|
||||
const put = (conds: CfGateCond[], join = g.join): void => setRule(ctx, makeGate(conds, join));
|
||||
const edit = (i: number, patch: Partial<CfGateCond>): void =>
|
||||
put(g.conds.map((c, j) => (j === i ? { ...c, ...patch } : c)));
|
||||
const out: HTMLElement[] = [el("p", { className: "m02-dflink-note", text: tk("GateHint") })];
|
||||
const out: HTMLElement[] = [
|
||||
el("p", { className: "ui-text ui-text--muted", text: tk("GateHint") }),
|
||||
];
|
||||
g.conds.forEach((c, i) => {
|
||||
out.push(
|
||||
row(
|
||||
@@ -380,7 +386,7 @@ function gateEditor(ctx: Ctx, rule: Extract<CfRule, { kind: "gate" }>): HTMLElem
|
||||
|
||||
function scaleEditor(ctx: Ctx, rule: Extract<CfRule, { kind: "scale" }>): HTMLElement[] {
|
||||
return [
|
||||
el("p", { className: "m02-dflink-note", text: tk("ScaleHint") }),
|
||||
el("p", { className: "ui-text ui-text--muted", text: tk("ScaleHint") }),
|
||||
row(
|
||||
select(
|
||||
ctx,
|
||||
@@ -502,10 +508,18 @@ export function renderLinkPanel(
|
||||
parts.push(
|
||||
row(
|
||||
el("span", { className: "m02-dflink-label", text: tk("Before") }),
|
||||
el("span", { className: "m02-dflink-value", text: pv.before }),
|
||||
el("span", {
|
||||
className: "ui-badge ui-badge--pill ui-badge--neutral",
|
||||
attrs: { "data-size": "20" },
|
||||
text: pv.before,
|
||||
}),
|
||||
"→",
|
||||
el("span", { className: "m02-dflink-label", text: tk("After") }),
|
||||
el("span", { className: "m02-dflink-value", text: pv.after }),
|
||||
el("span", {
|
||||
className: "ui-badge ui-badge--pill ui-badge--neutral",
|
||||
attrs: { "data-size": "20" },
|
||||
text: pv.after,
|
||||
}),
|
||||
),
|
||||
row(
|
||||
el("span", { className: "m02-dflink-label", text: tk("Label") }),
|
||||
@@ -518,6 +532,10 @@ export function renderLinkPanel(
|
||||
if (!rule.conds.length) warns.push(tk("WarnLookup"));
|
||||
if (!rule.col) warns.push(tk("WarnTake"));
|
||||
}
|
||||
parts.push(...warns.map((w) => el("p", { className: "m02-dflink-warn", text: `⚠ ${w}` })));
|
||||
parts.push(
|
||||
...warns.map((w) =>
|
||||
el("p", { className: "ui-banner ui-banner--warning m02-dflink-warn", text: `⚠ ${w}` }),
|
||||
),
|
||||
);
|
||||
host.replaceChildren(...parts);
|
||||
}
|
||||
|
||||
@@ -53,23 +53,8 @@
|
||||
}
|
||||
|
||||
.m02-dfout__input {
|
||||
box-sizing: border-box;
|
||||
width: 160px;
|
||||
max-width: 100%;
|
||||
height: var(--control-height-sm);
|
||||
padding: 3px 6px;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-sm);
|
||||
background: var(--color-canvas);
|
||||
color: var(--color-text-body);
|
||||
font: inherit;
|
||||
font-size: var(--text-body-sm);
|
||||
}
|
||||
|
||||
.m02-dfout__warn {
|
||||
margin: var(--spacing-4) 0 0;
|
||||
color: var(--color-danger);
|
||||
font-size: var(--text-body-sm);
|
||||
}
|
||||
|
||||
.m02-dfout__muted {
|
||||
@@ -78,12 +63,6 @@
|
||||
font-size: var(--text-caption);
|
||||
}
|
||||
|
||||
.m02-dfout__msg {
|
||||
margin: var(--spacing-4) 0 0;
|
||||
color: var(--color-danger);
|
||||
font-size: var(--text-caption);
|
||||
}
|
||||
|
||||
.m02-dfout__round {
|
||||
margin: var(--spacing-8) 0;
|
||||
color: var(--color-text-body);
|
||||
|
||||
@@ -13,6 +13,7 @@ import { portsOut, type CfBox, type CfCost, type CfLogic, type CfRound } from ".
|
||||
import { defaultItemRound, roundText } from "./M02_DF_Round";
|
||||
import { createUnitPick, suggestPlaces } from "./M02_DF_UnitPick";
|
||||
import "./M02_DF_OutputPanel.css";
|
||||
import "@ui/ui_template_text.css";
|
||||
|
||||
const TEXT = {
|
||||
Title: ["출력", "Output"],
|
||||
@@ -83,7 +84,7 @@ export function renderOutputPanel(
|
||||
host.replaceChildren();
|
||||
return;
|
||||
}
|
||||
const msg = el("p", { className: "m02-dfout__msg" });
|
||||
const msg = el("p", { className: "ui-text ui-text--error" });
|
||||
const emit = (make: () => CfLogic): void => {
|
||||
msg.textContent = "";
|
||||
try {
|
||||
@@ -133,14 +134,14 @@ export function renderOutputPanel(
|
||||
} else {
|
||||
got.replaceChildren(
|
||||
el("strong", { text: to("Got") }),
|
||||
el("p", { className: "m02-dfout__warn", text: to("NoLink") }),
|
||||
el("p", { className: "ui-text ui-text--error", text: to("NoLink") }),
|
||||
);
|
||||
}
|
||||
|
||||
/* 이름 · 비용 종류 · 단위 */
|
||||
const nameBox = el("input", {
|
||||
className: "m02-dfout__input",
|
||||
attrs: { type: "text", "aria-label": to("Name") },
|
||||
className: "ui-input m02-dfout__input",
|
||||
attrs: { "data-size": "32", type: "text", "aria-label": to("Name") },
|
||||
});
|
||||
nameBox.value = box.name;
|
||||
nameBox.addEventListener("change", () => {
|
||||
@@ -283,7 +284,9 @@ export function renderOutputPanel(
|
||||
],
|
||||
}),
|
||||
roundBlock,
|
||||
...(cost === "값" ? [el("p", { className: "m02-dfout__muted", text: to("PlainHint") })] : []),
|
||||
...(cost === "값"
|
||||
? [el("p", { className: "ui-text ui-text--muted", text: to("PlainHint") })]
|
||||
: []),
|
||||
msg,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import type { CfLogic } from "./M02_DF_Model";
|
||||
import { createPaper } from "./M02_DF_Paper";
|
||||
import { renderStandards } from "./M02_DF_Standards";
|
||||
import "./M02_DF_Panel.css";
|
||||
import "@ui/ui_template_toolbar.css";
|
||||
|
||||
const TEXT = {
|
||||
Big: ["크게 보기", "Full screen"],
|
||||
@@ -156,7 +157,7 @@ export function mountFlowPanel(host: HTMLElement, opts: FlowPanelOpts): FlowPane
|
||||
attrs: { open: "" },
|
||||
children: [el("summary", { text: tf("Cost") })],
|
||||
});
|
||||
const tools = el("div", { className: "m02-dfp__tools", children: [undo] });
|
||||
const tools = el("div", { className: "ui-toolbar m02-dfp__tools", children: [undo] });
|
||||
const open = el("div", {
|
||||
className: "m02-dfp__open",
|
||||
children: [head, tools, note, diagram, detail, costBox],
|
||||
|
||||
@@ -32,6 +32,7 @@ import {
|
||||
type DfPick,
|
||||
} from "./M02_DF_Entry_Detail";
|
||||
import "./M02_DF_Paper.css";
|
||||
import "@ui/ui_template_text.css";
|
||||
|
||||
const TEXT = {
|
||||
Undo: ["실행 취소", "Undo"],
|
||||
@@ -133,7 +134,8 @@ export function createPaper(opts: PaperOpts): Paper {
|
||||
});
|
||||
lock.disabled = readOnly;
|
||||
detail.body.append(lock);
|
||||
if (readOnly) detail.root.prepend(el("p", { className: "m02-df__muted", text: tp("ReadOnly") }));
|
||||
if (readOnly)
|
||||
detail.root.prepend(el("p", { className: "ui-text ui-text--muted", text: tp("ReadOnly") }));
|
||||
|
||||
const evalNow = (): CfEvalResult => {
|
||||
try {
|
||||
|
||||
@@ -22,6 +22,9 @@ import {
|
||||
type DetailOptions,
|
||||
} from "./M02_DF_Detail";
|
||||
import "./M02_DF_LinkPanel.css";
|
||||
import "@ui/ui_template_text.css";
|
||||
import "@ui/ui_template_banner.css";
|
||||
import "@ui/ui_template_badge.css";
|
||||
|
||||
const TEXT = {
|
||||
Name: ["이름", "Name"],
|
||||
@@ -55,7 +58,7 @@ function steps(
|
||||
empty: string,
|
||||
onBox?: (id: string) => void,
|
||||
): HTMLElement {
|
||||
if (!list.length) return el("p", { className: "m02-dflink-note", text: empty });
|
||||
if (!list.length) return el("p", { className: "ui-text ui-text--muted", text: empty });
|
||||
const pill = (box: string, name: string): HTMLElement | string =>
|
||||
onBox
|
||||
? createButton({
|
||||
@@ -75,7 +78,14 @@ function steps(
|
||||
pill(link.from.box, link.from.name),
|
||||
"→",
|
||||
...(s.rule
|
||||
? [el("span", { className: "m02-dfpill-rule", text: `(${labelOf(s.rule)})` }), "→"]
|
||||
? [
|
||||
el("span", {
|
||||
className: "ui-badge ui-badge--pill ui-badge--neutral",
|
||||
attrs: { "data-size": "20" },
|
||||
text: `(${labelOf(s.rule)})`,
|
||||
}),
|
||||
"→",
|
||||
]
|
||||
: []),
|
||||
pill(link.to.box, link.to.name),
|
||||
]
|
||||
@@ -121,7 +131,14 @@ export function renderPillPanel(
|
||||
],
|
||||
}),
|
||||
line(tp("Name"), port),
|
||||
line(tp("Value"), el("span", { className: "m02-dflink-value", text: showValue(value) })),
|
||||
line(
|
||||
tp("Value"),
|
||||
el("span", {
|
||||
className: "ui-badge ui-badge--pill ui-badge--neutral",
|
||||
attrs: { "data-size": "20" },
|
||||
text: showValue(value),
|
||||
}),
|
||||
),
|
||||
line(tp("Unit"), unit || "-"),
|
||||
el("div", {
|
||||
children: [
|
||||
@@ -139,8 +156,13 @@ export function renderPillPanel(
|
||||
children: [
|
||||
el("div", { className: "m02-dflink-label", text: tp("Breaks") }),
|
||||
...(breaks.length
|
||||
? breaks.map((b) => el("p", { className: "m02-dflink-warn", text: `⚠ ${b}` }))
|
||||
: [el("p", { className: "m02-dflink-note", text: tp("NoBreak") })]),
|
||||
? breaks.map((b) =>
|
||||
el("p", {
|
||||
className: "ui-banner ui-banner--warning m02-dflink-warn",
|
||||
text: `⚠ ${b}`,
|
||||
}),
|
||||
)
|
||||
: [el("p", { className: "ui-text ui-text--muted", text: tp("NoBreak") })]),
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import { currentLanguageIndex } from "@ui/ui_template_locale";
|
||||
import { createButton, el } from "@ui/ui_template_elements";
|
||||
import type { CfRound } from "./M02_DF_Model";
|
||||
import "@ui/ui_template_text.css";
|
||||
|
||||
const TEXT = {
|
||||
Label: ["끝수", "Rounding"],
|
||||
@@ -65,7 +66,7 @@ export function createRoundRow(opts: RoundRowOptions): HTMLElement {
|
||||
});
|
||||
if (opts.suggest !== null && !now && !opts.readOnly) {
|
||||
row.append(
|
||||
el("span", { className: "m02-dfpanel-note", text: tr("Suggest", opts.suggest) }),
|
||||
el("span", { className: "ui-text ui-text--muted", text: tr("Suggest", opts.suggest) }),
|
||||
createButton({
|
||||
label: tr("Apply"),
|
||||
variant: "ghost",
|
||||
|
||||
@@ -16,30 +16,13 @@
|
||||
margin: 0 auto 0 0;
|
||||
}
|
||||
|
||||
.m02-df-std__state,
|
||||
.m02-df-std__hint,
|
||||
.m02-df-std__line {
|
||||
color: var(--color-text-muted, #6b7280);
|
||||
}
|
||||
|
||||
.m02-df-std__hint {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.m02-df-std__scroll {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.m02-df-std__table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
/* 겉 = 표 부품 데이터표(ui-table-wrap) · 여기는 줄바꿈 막기 · 누르는 칸만 */
|
||||
.m02-df-std__table th,
|
||||
.m02-df-std__table td {
|
||||
border: 1px solid var(--color-border, #e5e7eb);
|
||||
padding: 2px 6px;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@@ -47,10 +30,6 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.m02-df-std__table th {
|
||||
background: var(--color-surface-muted, rgba(127, 127, 127, 0.08));
|
||||
}
|
||||
|
||||
.m02-df-std__notes {
|
||||
margin: 0;
|
||||
padding-left: 0;
|
||||
|
||||
@@ -15,6 +15,8 @@ import { cfStandards, cfStandardsReset, cfStandardsSave, type CfStandards } from
|
||||
import unitDefault from "./_standard/단위표준.json";
|
||||
import moneyDefault from "./_standard/금액단위표준.json";
|
||||
import "./M02_DF_Standards.css";
|
||||
import "@ui/ui_template_text.css";
|
||||
import "@ui/ui_template_table.css";
|
||||
|
||||
const TEXT = {
|
||||
Title: ["표준 표", "Standards"],
|
||||
@@ -198,7 +200,7 @@ export function renderStandards(
|
||||
): void {
|
||||
let work = clone(current);
|
||||
let dirty = false;
|
||||
const state = el("span", { className: "m02-df-std__state" });
|
||||
const state = el("span", { className: "ui-text ui-text--muted m02-df-std__state" });
|
||||
const save = createButton({ label: tx("Save"), size: "sm", onClick: () => void doSave() });
|
||||
const reset = createButton({
|
||||
label: tx("Reset"),
|
||||
@@ -250,10 +252,10 @@ export function renderStandards(
|
||||
|
||||
const table = (heads: string[], rows: HTMLElement[][]): HTMLElement =>
|
||||
el("div", {
|
||||
className: "m02-df-std__scroll",
|
||||
className: "ui-table-wrap m02-df-std__scroll",
|
||||
children: [
|
||||
el("table", {
|
||||
className: "m02-df-std__table",
|
||||
className: "ui-table ui-table--data m02-df-std__table",
|
||||
children: [
|
||||
el("thead", {
|
||||
children: [el("tr", { children: heads.map((h) => el("th", { text: h })) })],
|
||||
@@ -350,7 +352,7 @@ export function renderStandards(
|
||||
save,
|
||||
],
|
||||
}),
|
||||
el("p", { className: "m02-df-std__hint", text: `${tx("Source")} · ${tx("Hint")}` }),
|
||||
el("p", { className: "ui-text ui-text--muted", text: `${tx("Source")} · ${tx("Hint")}` }),
|
||||
body,
|
||||
],
|
||||
}),
|
||||
|
||||
@@ -41,30 +41,12 @@
|
||||
|
||||
.m02-dfsum__scroll {
|
||||
max-width: 100%;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.m02-dfsum__table {
|
||||
width: 100%;
|
||||
min-width: 360px;
|
||||
margin-top: var(--spacing-4);
|
||||
border-collapse: collapse;
|
||||
font-size: var(--text-body-sm);
|
||||
}
|
||||
|
||||
.m02-dfsum__table th,
|
||||
.m02-dfsum__table td {
|
||||
padding: var(--spacing-4) var(--spacing-8);
|
||||
border: 1px solid var(--color-border);
|
||||
text-align: left;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.m02-dfsum__table th {
|
||||
background: var(--color-surface);
|
||||
color: var(--color-text-secondary);
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
/* 겉 = 표 부품 데이터표(ui-table-wrap) · 여기는 최소 폭 · 수 칸 오른쪽만 */
|
||||
.m02-dfsum__table {
|
||||
min-width: 360px;
|
||||
}
|
||||
|
||||
.m02-dfsum__table td.m02-dfsum__num {
|
||||
@@ -91,42 +73,3 @@
|
||||
color: var(--color-text-secondary);
|
||||
font-size: var(--text-body-sm);
|
||||
}
|
||||
|
||||
.m02-dfsum__input {
|
||||
box-sizing: border-box;
|
||||
width: 140px;
|
||||
height: var(--control-height-sm);
|
||||
padding: 3px 6px;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-sm);
|
||||
background: var(--color-canvas);
|
||||
color: var(--color-text-body);
|
||||
font: inherit;
|
||||
font-size: var(--text-body-sm);
|
||||
}
|
||||
|
||||
.m02-dfsum__muted {
|
||||
margin: 0;
|
||||
color: var(--color-text-muted);
|
||||
font-size: var(--text-caption);
|
||||
}
|
||||
|
||||
.m02-dfsum__msg {
|
||||
margin: var(--spacing-4) 0 0;
|
||||
color: var(--color-danger);
|
||||
font-size: var(--text-caption);
|
||||
}
|
||||
|
||||
.m02-dfsum__problems {
|
||||
margin: 0 0 var(--spacing-12);
|
||||
padding: var(--spacing-8) var(--spacing-12);
|
||||
border-left: 4px solid var(--color-danger);
|
||||
background: var(--color-surface);
|
||||
color: var(--color-text-body);
|
||||
font-size: var(--text-body-sm);
|
||||
}
|
||||
|
||||
.m02-dfsum__problems ul {
|
||||
margin: var(--spacing-4) 0 0;
|
||||
padding-left: var(--spacing-16);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ import {
|
||||
} from "./M02_DF_Round";
|
||||
import { renderVerify, type CfSel } from "./M02_DF_Verify";
|
||||
import "./M02_DF_Summary.css";
|
||||
import "@ui/ui_template_text.css";
|
||||
import "@ui/ui_template_table.css";
|
||||
|
||||
const TEXT = {
|
||||
Per: ["{per} 당", "per {per}"],
|
||||
@@ -115,10 +117,10 @@ export function renderSummary(
|
||||
children: [
|
||||
el("strong", { text: title }),
|
||||
el("div", {
|
||||
className: "m02-dfsum__scroll",
|
||||
className: "ui-table-wrap m02-dfsum__scroll",
|
||||
children: [
|
||||
el("table", {
|
||||
className: "m02-dfsum__table",
|
||||
className: "ui-table ui-table--data m02-dfsum__table",
|
||||
children: [
|
||||
el("thead", {
|
||||
children: [
|
||||
@@ -162,14 +164,14 @@ export function renderSummary(
|
||||
children: [
|
||||
el("strong", { text: ts("Plain") }),
|
||||
...plainValues.map(([k, v]) =>
|
||||
el("p", { className: "m02-dfsum__muted", text: `${k} · ${showValue(v)}` }),
|
||||
el("p", { className: "ui-text ui-text--muted", text: `${k} · ${showValue(v)}` }),
|
||||
),
|
||||
],
|
||||
}),
|
||||
]
|
||||
: []),
|
||||
el("p", {
|
||||
className: "m02-dfsum__muted",
|
||||
className: "ui-text ui-text--muted",
|
||||
text: `${ts("RoundTotal")}: ${roundText(sumRound)}`,
|
||||
}),
|
||||
verifyHost,
|
||||
|
||||
@@ -27,30 +27,15 @@
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* 단위 줄 = 목록 줄 부품 · 화살표 키로 고른 줄(is-on)만 마우스 꼴 */
|
||||
.m02-df-unitpick__item {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: var(--spacing-4) var(--spacing-8);
|
||||
border: 0;
|
||||
border-radius: var(--radius-sm);
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
font: inherit;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.m02-df-unitpick__item.is-on,
|
||||
.m02-df-unitpick__item:hover {
|
||||
background: var(--color-surface-raised);
|
||||
.m02-df-unitpick__item.is-on {
|
||||
background: var(--color-hover);
|
||||
}
|
||||
|
||||
.m02-df-unitpick__item.is-now {
|
||||
font-weight: var(--font-weight-bold);
|
||||
}
|
||||
|
||||
.m02-df-unitpick__empty {
|
||||
padding: var(--spacing-8);
|
||||
color: var(--color-text-muted);
|
||||
font-size: var(--text-body-sm);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import { currentLanguageIndex } from "@ui/ui_template_locale";
|
||||
import { createButton, el } from "@ui/ui_template_elements";
|
||||
import { cfStandards } from "./M02_DF_Api";
|
||||
import "./M02_DF_UnitPick.css";
|
||||
import { createEmpty } from "@ui/ui_template_empty";
|
||||
import "@ui/ui_template_list_row.css";
|
||||
|
||||
const TEXT = {
|
||||
None: ["없음", "none"],
|
||||
@@ -139,14 +141,14 @@ export function createUnitPick(opts: UnitPickOptions): HTMLElement {
|
||||
...(shown.length
|
||||
? shown.map((u, i) => {
|
||||
const b = el("button", {
|
||||
className: `m02-df-unitpick__item${i === at ? " is-on" : ""}${u === (opts.value || NO_UNIT) ? " is-now" : ""}`,
|
||||
className: `ui-list-row ui-sidebar-row m02-df-unitpick__item${i === at ? " is-on" : ""}${u === (opts.value || NO_UNIT) ? " is-now" : ""}`,
|
||||
text: label(u),
|
||||
attrs: { type: "button", role: "option" },
|
||||
});
|
||||
b.addEventListener("click", () => pick(u));
|
||||
return el("li", { children: [b] });
|
||||
})
|
||||
: [el("li", { className: "m02-df-unitpick__empty", text: tu("Empty") })]),
|
||||
: [el("li", { children: [createEmpty({ text: tu("Empty"), small: true })] })]),
|
||||
);
|
||||
};
|
||||
const close = (): void => {
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
color: var(--color-text-body);
|
||||
}
|
||||
|
||||
/* 끊긴 곳 = 띠 알림 부품(위험) · 여기는 제목 · 목록 쌓기만 */
|
||||
.m02-dfver__breaks {
|
||||
padding: var(--spacing-8) var(--spacing-12);
|
||||
border-left: 4px solid var(--color-danger);
|
||||
background: var(--color-surface);
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.m02-dfver__title {
|
||||
@@ -33,17 +32,8 @@
|
||||
}
|
||||
|
||||
.m02-dfver__input {
|
||||
box-sizing: border-box;
|
||||
width: 160px;
|
||||
max-width: 100%;
|
||||
height: var(--control-height-sm);
|
||||
padding: 3px 6px;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-sm);
|
||||
background: var(--color-canvas);
|
||||
color: var(--color-text-body);
|
||||
font: inherit;
|
||||
font-size: var(--text-body-sm);
|
||||
}
|
||||
|
||||
.m02-dfver__item {
|
||||
@@ -111,12 +101,6 @@
|
||||
font-size: var(--text-caption);
|
||||
}
|
||||
|
||||
.m02-dfver__msg {
|
||||
margin: var(--spacing-4) 0 0;
|
||||
color: var(--color-danger);
|
||||
font-size: var(--text-caption);
|
||||
}
|
||||
|
||||
/* 쉬는 갈래 — 문제가 아니라 회색으로 */
|
||||
.m02-dfver__rest {
|
||||
padding: var(--spacing-8) var(--spacing-12);
|
||||
|
||||
@@ -20,6 +20,9 @@ import {
|
||||
type CfVariable,
|
||||
} from "./M02_DF_Model";
|
||||
import "./M02_DF_Verify.css";
|
||||
import "@ui/ui_template_text.css";
|
||||
import "@ui/ui_template_banner.css";
|
||||
import "@ui/ui_template_toolbar.css";
|
||||
|
||||
const TEXT = {
|
||||
Breaks: ["끊긴 곳", "Broken spots"],
|
||||
@@ -133,8 +136,9 @@ function sampleField(
|
||||
}).root;
|
||||
} else {
|
||||
const box = el("input", {
|
||||
className: "m02-dfver__input",
|
||||
className: "ui-input m02-dfver__input",
|
||||
attrs: {
|
||||
"data-size": "32",
|
||||
type: "text",
|
||||
inputmode: v.type === "number" ? "decimal" : "text",
|
||||
"aria-label": v.name,
|
||||
@@ -168,15 +172,20 @@ function slotRow(box: CfBox, e: CfElementRef, on: CfVerifyOn, lg: CfLogic): HTML
|
||||
const panel = el("div", { className: "m02-dfver__panel" });
|
||||
panel.hidden = true;
|
||||
const q = el("input", {
|
||||
className: "m02-dfver__input",
|
||||
attrs: { type: "text", placeholder: tv("Search"), "aria-label": tv("Search") },
|
||||
className: "ui-input m02-dfver__input",
|
||||
attrs: {
|
||||
"data-size": "32",
|
||||
type: "text",
|
||||
placeholder: tv("Search"),
|
||||
"aria-label": tv("Search"),
|
||||
},
|
||||
});
|
||||
q.value = e.scope?.찾는말 ?? "";
|
||||
const list = el("ul", { className: "m02-dfver__list" });
|
||||
const pager = el("div", { className: "m02-dfver__pager" });
|
||||
const pager = el("div", { className: "ui-toolbar m02-dfver__pager" });
|
||||
let page = 1;
|
||||
const load = async (): Promise<void> => {
|
||||
list.replaceChildren(el("li", { className: "m02-dfver__muted", text: tv("Loading") }));
|
||||
list.replaceChildren(el("li", { className: "ui-text ui-text--muted", text: tv("Loading") }));
|
||||
const got = await findMaterials({
|
||||
q: q.value.trim(),
|
||||
sub: e.scope?.구분,
|
||||
@@ -199,7 +208,7 @@ function slotRow(box: CfBox, e: CfElementRef, on: CfVerifyOn, lg: CfLogic): HTML
|
||||
],
|
||||
}),
|
||||
)
|
||||
: [el("li", { className: "m02-dfver__muted", text: tv("NoHit") })]),
|
||||
: [el("li", { className: "ui-text ui-text--muted", text: tv("NoHit") })]),
|
||||
);
|
||||
pager.replaceChildren(
|
||||
createButton({
|
||||
@@ -247,7 +256,7 @@ function slotRow(box: CfBox, e: CfElementRef, on: CfVerifyOn, lg: CfLogic): HTML
|
||||
});
|
||||
panel.append(
|
||||
el("div", {
|
||||
className: "m02-dfver__search",
|
||||
className: "ui-toolbar m02-dfver__search",
|
||||
children: [
|
||||
q,
|
||||
createButton({
|
||||
@@ -326,7 +335,7 @@ export function renderVerify(
|
||||
on: CfVerifyOn,
|
||||
opts: { values?: CfValues; logics?: CfEvalOptions["logics"] } = {},
|
||||
): void {
|
||||
const msg = el("p", { className: "m02-dfver__msg" });
|
||||
const msg = el("p", { className: "ui-text ui-text--error" });
|
||||
const safe = (make: () => CfLogic): void => {
|
||||
msg.textContent = "";
|
||||
try {
|
||||
@@ -355,7 +364,7 @@ export function renderVerify(
|
||||
}),
|
||||
),
|
||||
}),
|
||||
el("p", { className: "m02-dfver__muted", text: tv(hint) }),
|
||||
el("p", { className: "ui-text ui-text--muted", text: tv(hint) }),
|
||||
];
|
||||
const problems = spots.filter((s) => s.level !== "쉼");
|
||||
const resting = spots.filter((s) => s.level === "쉼");
|
||||
@@ -363,7 +372,7 @@ export function renderVerify(
|
||||
...(problems.length
|
||||
? [
|
||||
el("div", {
|
||||
className: "m02-dfver__block m02-dfver__breaks",
|
||||
className: "ui-banner ui-banner--danger m02-dfver__block m02-dfver__breaks",
|
||||
children: [el("strong", { text: tv("Breaks") }), ...spotList(problems, "BreaksHint")],
|
||||
}),
|
||||
]
|
||||
@@ -427,8 +436,13 @@ export function renderVerify(
|
||||
const logics = designs.flatMap((d) => {
|
||||
if (d.kind !== "다른 로직") return [];
|
||||
const input = el("input", {
|
||||
className: "m02-dfver__input",
|
||||
attrs: { type: "text", placeholder: tv("OwnSample"), "aria-label": d.port },
|
||||
className: "ui-input m02-dfver__input",
|
||||
attrs: {
|
||||
"data-size": "32",
|
||||
type: "text",
|
||||
placeholder: tv("OwnSample"),
|
||||
"aria-label": d.port,
|
||||
},
|
||||
});
|
||||
input.value = d.example === null || d.example === undefined ? "" : String(d.example);
|
||||
input.addEventListener("change", () => safe(() => putLogicExample(d.box, d.port, input.value)));
|
||||
@@ -479,7 +493,7 @@ export function renderVerify(
|
||||
children: [
|
||||
el("strong", { className: "m02-dfver__title", text: tv("Design") }),
|
||||
...design,
|
||||
el("p", { className: "m02-dfver__muted", text: tv("DesignHint") }),
|
||||
el("p", { className: "ui-text ui-text--muted", text: tv("DesignHint") }),
|
||||
msg,
|
||||
],
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user