Files
Aislo/ui_template/ui_template_stat.ts
T
eomsangdonandClaude Opus 5.5 7e584c1e7b feat(ui-kit): 묶음 부품 열 — 카드 · 접이 카드 · 빈 상태 · 알림 · 띠 알림 · 숫자 카드 · 값 목록 · 진행 막대 · 작은 그래프 · 범례 (PLAN 552-3)
- 새 부품 파일: 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>
2026-10-26 21:28:29 +09:00

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 });
}