- 새 부품 파일: ui_template_card · empty · banner · stat · kv · toast · flow_legend(.ts) · 진행 막대 · 막대 · 원 그래프 덧붙임 - createCard · showToast · 로딩 가림막은 부품 파일로 옮기고 본체(ui_template_elements)가 다시 내보냄 — 부름 꼴 그대로 - 대시보드 emptyState = 빈 상태 부품을 씀(한 벌) · 선 카드 그림자 0 · 가림막 옛 보라 → --color-scrim - 부품 모음 화면 견본(밝음 · 어두움 · 상태) · 지킴 시험 test_552_3_* 열 - 전후 촬영: B01 여덟 화면 자리 · 화소 같음(실시간 CPU 값만 다름) · A01 · B08 카드 그림자만 다름 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
56 lines
2.5 KiB
TypeScript
56 lines
2.5 KiB
TypeScript
/* =============================================================================
|
|
* ui_template_stat.ts
|
|
* 부품 「숫자 카드」(552-3 · 목록 28) — 큰 숫자 하나를 이름 · 단위 · 변화와 함께 보임.
|
|
* 꼴 = 값 · 단위 · 변화(▲ 늘어남 · ▼ 줄어듦) · 게이지(`gauge` 0~1 → 막대 8) · 판정 색(`tone`: warn · bad)
|
|
* 크기 = 값 글 22 · 이름 12 · 카드 여백 12 / 16
|
|
* 상태 = 기본만(판정은 is-warn · is-bad)
|
|
* 쓰는 법 = `createStat({ label: "진행 중", value: 12, unit: "건", delta: "+3" })` · `createStat({ label: "디스크", value: "71 %", gauge: 0.71, tone: "warn" })`
|
|
* 여러 장은 `.ui-stat-grid` 에 담음(폭 맞춰 줄바꿈)
|
|
* 대신하는 옛 변종 = B01 `.b01-home__kpi` · `.b01-pd-kpi` · `.b01-sys-stat` · `.b01-sys-gauge` · `.b01-dashboard__metric` · E03 `e03-kpi`
|
|
* ========================================================================== */
|
|
|
|
import { el } from "./ui_template_elements_base";
|
|
import "./ui_template_stat.css";
|
|
|
|
export interface StatOptions {
|
|
label: string;
|
|
value: string | number;
|
|
unit?: string;
|
|
/** 변화 글 — 「+」로 시작하면 ▲ · 「-」면 ▼ */
|
|
delta?: string;
|
|
/** 게이지 비율 0~1 */
|
|
gauge?: number;
|
|
tone?: "warn" | "bad";
|
|
/** 작은 카드(여백 12 · 숫자 · 이름만 한 덩어리) */
|
|
compact?: boolean;
|
|
}
|
|
|
|
export function createStat(opts: StatOptions): HTMLElement {
|
|
const card = el("div", {
|
|
className: `ui-stat${opts.compact ? " ui-stat--compact" : ""}${opts.tone ? ` is-${opts.tone}` : ""}`,
|
|
});
|
|
const value = el("strong", { className: "ui-stat__value", text: String(opts.value) });
|
|
if (opts.unit) value.append(el("span", { className: "ui-stat__unit", text: opts.unit }));
|
|
card.append(el("span", { className: "ui-stat__label", text: opts.label }), value);
|
|
if (opts.delta) {
|
|
const down = opts.delta.startsWith("-");
|
|
card.append(
|
|
el("span", {
|
|
className: `ui-stat__delta ${down ? "is-down" : "is-up"}`,
|
|
text: `${down ? "▼" : "▲"} ${opts.delta}`,
|
|
}),
|
|
);
|
|
}
|
|
if (opts.gauge !== undefined) {
|
|
const fill = el("i", { className: "ui-stat__fill" });
|
|
fill.style.width = `${Math.round(Math.min(1, Math.max(0, opts.gauge)) * 100)}%`;
|
|
card.append(el("div", { className: "ui-stat__bar", children: [fill] }));
|
|
}
|
|
return card;
|
|
}
|
|
|
|
/** 숫자 카드 여러 장 — 폭에 맞춰 줄바꿈 */
|
|
export function statGrid(cards: HTMLElement[]): HTMLElement {
|
|
return el("div", { className: "ui-stat-grid", children: cards });
|
|
}
|