- 새 부품 파일: 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>
69 lines
3.1 KiB
TypeScript
69 lines
3.1 KiB
TypeScript
/* =============================================================================
|
|
* ui_template_card.ts
|
|
* 부품 「카드」(552-3 · 목록 14) — 내용을 담는 흰 판.
|
|
* 꼴 = 선 카드(기본 · 1 px 선 · 둥글기 10 · 그림자 0) · 떠 있는 카드(`raised`) · 머리 카드(`actions` — 제목 줄 + 오른쪽 조각 · 아래 선)
|
|
* · 고르는 카드(`onSelect` — 큰 단추 꼴 · 누르면 고름)
|
|
* 크기 = 여백 `pad: 12 | 16`(→ data-pad · 없으면 24)
|
|
* 상태 = 고르는 카드만 마우스 · 눌림 · 고름(aria-pressed · .is-active) · 막힘(disabled)
|
|
* 쓰는 법 = `createCard({ title: "개요", body: [table], pad: 16 })` · `createCard({ title: "새 노선", onSelect: go })`
|
|
* 대신하는 옛 변종 = `.b01-pg-card` · `.b01-proj-card` · `.b01-new-project__card` · `b03-file__card` · `e02-card` · `m01lab__box` …(목록 4장)
|
|
* 옛 이름 `ui-card` · `ui-card--raised` · `ui-card__title` · `ui-card__body` 그대로 냄 · 바탕 모양은 `ui_template_elements_styles.ts`.
|
|
* ========================================================================== */
|
|
|
|
import { el } from "./ui_template_elements_base";
|
|
import "./ui_template_card.css";
|
|
|
|
export interface CardOptions {
|
|
title?: string;
|
|
/** 본문 자식 요소들 */
|
|
body?: (HTMLElement | string)[];
|
|
/** 그림자 강조 여부 (shadow-lg 사용) */
|
|
raised?: boolean;
|
|
/** 머리 카드 — 제목 줄 오른쪽 조각(단추 · 배지) */
|
|
actions?: HTMLElement[];
|
|
/** 안 여백(px) — 없으면 24 */
|
|
pad?: 12 | 16;
|
|
/** 고르는 카드 — 누르면 부름 */
|
|
onSelect?: () => void;
|
|
/** 고르는 카드가 지금 골라졌는지 */
|
|
selected?: boolean;
|
|
}
|
|
|
|
export function createCard(opts: CardOptions & { onSelect: () => void }): HTMLButtonElement;
|
|
export function createCard(opts: CardOptions): HTMLDivElement;
|
|
export function createCard(opts: CardOptions): HTMLDivElement | HTMLButtonElement {
|
|
const pick = opts.onSelect;
|
|
const card = el(pick ? "button" : "div", {
|
|
className: `ui-card${opts.raised ? " ui-card--raised" : ""}${pick ? " ui-card--select" : ""}`,
|
|
});
|
|
if (opts.pad) card.dataset.pad = String(opts.pad);
|
|
const title = opts.title ? el("h3", { className: "ui-card__title", text: opts.title }) : null;
|
|
if (opts.actions?.length) {
|
|
card.classList.add("ui-card--head");
|
|
card.append(
|
|
el("div", {
|
|
className: "ui-card__head",
|
|
children: [
|
|
title ?? el("span"),
|
|
el("div", { className: "ui-card__actions", children: opts.actions }),
|
|
],
|
|
}),
|
|
);
|
|
} else if (title) card.append(title);
|
|
if (opts.body) {
|
|
card.append(el("div", { className: "ui-card__body", children: opts.body }));
|
|
}
|
|
if (pick && card instanceof HTMLButtonElement) {
|
|
card.type = "button";
|
|
setCardSelected(card, !!opts.selected);
|
|
card.addEventListener("click", pick);
|
|
}
|
|
return card;
|
|
}
|
|
|
|
/** 고르는 카드 고름 표시 */
|
|
export function setCardSelected(card: HTMLElement, on: boolean): void {
|
|
card.classList.toggle("is-active", on);
|
|
card.setAttribute("aria-pressed", String(on));
|
|
}
|