Files
Aislo/ui_template/ui_template_public_layout.ts
T
eomsangdonandClaude Opus 5.5 f941ddc3f5 feat(ui-kit): 틀 부품 여섯 — 작업 화면 틀 겉 · 일반 화면 틀 · 공개 화면 틀 · 단계 줄 · 패널 머리 · 목록 줄 (PLAN 552-4)
- 작업 화면 틀(overlay): 왼쪽 패널 = 흰 판 + 1 px 선 · 그림자 없음 · 덮개 = --color-scrim · 손잡이 강조색 그대로 · 자리 · 폭 그대로
- 일반 화면 틀 createPageFrame(대시보드 세부 꼴) · 공개 화면 틀 createPublicFrame(A01 hero · section 꼴)
- 단계 줄 data-size 28 · 40 · 상태 = 공통 값 · 패널 머리 createPanelHead · 목록 줄 createListRow(옛 .ui-sidebar-row 겉 함께)
- 부품 모음: 떠 있는 판 · 서랍 · 도구줄 · 단계 줄 · 패널 머리 · 목록 줄 여섯 줄을 frame 묶음으로 옮김 · 견본 = ui_template_ui_kit_frames.ts
- 지킴 시험 test_552_4_frames.py · B02~B09 · D · E · M02 전후 자리 수치 같음

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 21:28:17 +09:00

64 lines
2.6 KiB
TypeScript

/* =============================================================================
* ui_template_public_layout.ts
* 공개 화면 틀 `public-frame`(552-4 틀) — 로그인 전 공개 페이지(A01 ~ A09) 몸통: 머리 띠(hero) · 구역 · 본문.
* 꼴 = 머리 띠(제목 · 설명 · 주 단추 줄 · 가운데 / 왼쪽 맞춤) · 구역(제목 + 몸) 여럿
* 공개 머리(로고 · 메뉴)와 바닥글(`.app-footer`)은 앱 셸 몫 — 이 틀은 그 사이 본문만
* 크기 = 폭 = --page-max-width · 제목 = --text-heading-lg(좁으면 --text-heading) · 구역 제목 = --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";
}
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";
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 };
}