Files
Aislo/ui_template/ui_template_public_layout.ts
T
eomsangdonandClaude Sonnet 5.5 25adc2f0e7 refactor(공개화면): A01~A09 · B10 · B11 을 공개 화면 틀 · 카드 · 알림 · 배지 · 체크 · 접이 부품으로 (PLAN 553-7)
- 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>
2026-10-26 21:56:42 +09:00

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