/* ============================================================================= * 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)); }