- A01~A05 hero 다섯 벌 · 구역 제목 복제 CSS 걷고 공개 화면 틀 한 벌(wide 옵션 · 구역 제목 가운데 · 머리 아랫줄은 자리 안 먹는 그림자) - 카드 = 카드 부품(로그인 · 가입 · 지원 · 약관 · 기능 카드 · 소식 줄 · B11 단계 카드) · 지원 성공 · B10 안내 = 띠 알림 · 태그 = 배지 - A07 약관 날 체크 · 날 details = 체크 + 접이 부품 · A08 날 textarea = 입력 여러 줄 · 빈 소식 = 빈 상태 - 죽은 A07_Register_UI_Page · 쓰이지 않는 CSS 걷음 · 띠 알림 hidden 받음 - 지킴 시험 test_553_7_public_pages Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
67 lines
2.8 KiB
TypeScript
67 lines
2.8 KiB
TypeScript
/* =============================================================================
|
|
* ui_template_public_layout.ts
|
|
* 공개 화면 틀 `public-frame`(552-4 틀) — 로그인 전 공개 페이지(A01 ~ A09) 몸통: 머리 띠(hero) · 구역 · 본문.
|
|
* 꼴 = 머리 띠(제목 · 설명 · 주 단추 줄 · 가운데 / 왼쪽 맞춤) · 구역(제목 + 몸) 여럿
|
|
* 공개 머리(로고 · 메뉴)와 바닥글(`.app-footer`)은 앱 셸 몫 — 이 틀은 그 사이 본문만
|
|
* 크기 = 폭 = --page-max-width · 제목 = --text-heading-lg(좁으면 --text-heading · `wide` = 18 자) · 구역 제목 = --text-heading-sm(가운데)
|
|
* 상태 = 없음
|
|
* 쓰는 법 = const f = createPublicFrame({ title: "임도 설계", lead: "…", actions: [btn] }); f.addSection("기능").append(grid)
|
|
* 대신하는 옛 변종 = A01 ~ A05 `.a0N-hero` · `__inner` · `__title` · `__subtitle` · `__ctas` 다섯 벌 · `.a0N-section(__title)`
|
|
* ========================================================================== */
|
|
|
|
import "./ui_template_public_layout.css";
|
|
|
|
export interface PublicFrameOptions {
|
|
title: string;
|
|
lead?: string;
|
|
actions?: HTMLElement[];
|
|
/** 머리 띠 맞춤 — 기본 가운데 */
|
|
align?: "center" | "start";
|
|
/** 제목 18 자 · 설명 56 자 폭(기본 14 · 52) */
|
|
wide?: boolean;
|
|
}
|
|
|
|
export interface PublicFrame {
|
|
root: HTMLElement;
|
|
hero: HTMLElement;
|
|
/** 구역 하나 더함 → 그 구역 몸(여기에 내용을 담음) */
|
|
addSection: (title?: string) => HTMLElement;
|
|
}
|
|
|
|
function node<K extends keyof HTMLElementTagNameMap>(
|
|
tag: K,
|
|
className: string,
|
|
text?: string,
|
|
): HTMLElementTagNameMap[K] {
|
|
const n = document.createElement(tag);
|
|
n.className = className;
|
|
if (text !== undefined) n.textContent = text;
|
|
return n;
|
|
}
|
|
|
|
export function createPublicFrame(opts: PublicFrameOptions): PublicFrame {
|
|
const root = node("div", "ui-public-frame");
|
|
const hero = node("section", "ui-public-frame__hero");
|
|
hero.dataset.align = opts.align ?? "center";
|
|
if (opts.wide) hero.dataset.wide = "";
|
|
const inner = node("div", "ui-public-frame__hero-inner");
|
|
inner.append(node("h1", "ui-public-frame__title", opts.title));
|
|
if (opts.lead) inner.append(node("p", "ui-public-frame__lead", opts.lead));
|
|
if (opts.actions?.length) {
|
|
const ctas = node("div", "ui-public-frame__actions");
|
|
ctas.append(...opts.actions);
|
|
inner.append(ctas);
|
|
}
|
|
hero.append(inner);
|
|
root.append(hero);
|
|
const addSection = (title?: string): HTMLElement => {
|
|
const section = node("section", "ui-public-frame__section");
|
|
if (title) section.append(node("h2", "ui-public-frame__section-title", title));
|
|
const body = node("div", "ui-public-frame__section-body");
|
|
section.append(body);
|
|
root.append(section);
|
|
return body;
|
|
};
|
|
return { root, hero, addSection };
|
|
}
|