- 새 부품 파일: ui_template_table · setting_row · drop · createRowMenu(context_menu) · 모달 폭 단 · askConfirm · askText(window.prompt 대신) · confirmPanel - 단추 = 552-2 단추 부품(⋯ 아이콘 단추 28 · 띠 알림 닫기 20 · 놓기 칸 [파일 고르기] 28) - 대시보드 PageKit 의 dataTable · tableShell · tableRow · rowMenu · settingRow · settingCard · valueText = 부품을 다시 내보냄(한 벌 · 부름 꼴 그대로) · B01 옛 CSS 걷음 - showConfirmDialog 는 모달 부품으로 옮기고 본체가 다시 내보냄 · 모달 가림막 옛 보라 → --color-scrim - 시험: test_552_3_* 다섯 더함 · 옮긴 함수 자리를 읽던 test_290_1 · test_505_2 고침 · 부품 CSS import 를 못 읽던 시험 도우미 넷(130 · 153 · 280_5 · 311)이 .css 를 건너뜀 - 전후 촬영: B01 여덟 화면 자리 같음 · ⋯ 아이콘만 1 px 왼쪽(단추 부품 가운데 맞춤) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
64 lines
2.7 KiB
TypeScript
64 lines
2.7 KiB
TypeScript
/* =============================================================================
|
|
* ui_template_banner.ts
|
|
* 부품 「띠 알림」(552-3 · 목록 25) — 화면 안에 머무는 알림 줄(토스트처럼 사라지지 않음).
|
|
* 꼴 = 왼쪽 색 띠 + 옅은 바탕 · 갈래 넷(정보 · 경고 · 위험 · 성공 — 성공은 ✓ 같이) · 제목(굵게) · 펼침(`details` → 「자세히」)
|
|
* · 안 단추(`actions`) · 닫기(`onClose` → ✕ 아이콘 단추 20)
|
|
* 크기 = 글 13 · 줄 최소 32 · 여백 8 / 12
|
|
* 상태 = 기본만
|
|
* 쓰는 법 = `createBanner({ tone: "warning", text: "저장 안 한 고침이 있음", actions: [createButton(…)] })`
|
|
* 대신하는 옛 변종 = B01 `.b01-home__stale` · B03 `b03-file__resume` · `__error-message` · B06 `b06-section__notice-bar` · E05 · E06 `__stale`
|
|
* · M01 `m01-master__notice` · `m01lab__warn` · M02 `m02-main__notice` · `m02-sod__banner` …(약 20 벌 · 목록 4장)
|
|
* ========================================================================== */
|
|
|
|
import { createIconButton } from "./ui_template_button";
|
|
import { el } from "./ui_template_elements_base";
|
|
import "./ui_template_banner.css";
|
|
|
|
export type BannerTone = "info" | "warning" | "danger" | "success";
|
|
|
|
export interface BannerOptions {
|
|
tone?: BannerTone;
|
|
text: string;
|
|
title?: string;
|
|
/** 펼쳐 보는 자세한 글 · 목록 */
|
|
details?: string | HTMLElement;
|
|
actions?: HTMLElement[];
|
|
/** 주면 오른쪽 ✕ — 누르면 띠를 지우고 부름 */
|
|
onClose?: () => void;
|
|
}
|
|
|
|
export function createBanner(opts: BannerOptions): HTMLElement {
|
|
const tone = opts.tone ?? "info";
|
|
const root = el("div", {
|
|
className: `ui-banner ui-banner--${tone}`,
|
|
attrs: { role: tone === "danger" ? "alert" : "status" },
|
|
});
|
|
const body = el("div", { className: "ui-banner__body" });
|
|
if (opts.title) body.append(el("strong", { className: "ui-banner__title", text: opts.title }));
|
|
body.append(
|
|
el("span", {
|
|
className: "ui-banner__text",
|
|
text: `${tone === "success" ? "✓ " : ""}${opts.text}`,
|
|
}),
|
|
);
|
|
if (opts.details) {
|
|
const more = el("details", { className: "ui-banner__details" });
|
|
more.append(el("summary", { text: "자세히" }), opts.details);
|
|
body.append(more);
|
|
}
|
|
root.append(body);
|
|
if (opts.actions?.length)
|
|
root.append(el("div", { className: "ui-banner__actions", children: opts.actions }));
|
|
if (opts.onClose) {
|
|
const onClose = opts.onClose;
|
|
const close = createIconButton({ icon: "x", title: "닫기", size: 20 });
|
|
close.classList.add("ui-banner__close");
|
|
close.addEventListener("click", () => {
|
|
root.remove();
|
|
onClose();
|
|
});
|
|
root.append(close);
|
|
}
|
|
return root;
|
|
}
|