Files
Aislo/ui_template/ui_template_general_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

96 lines
3.6 KiB
TypeScript

/* =============================================================================
* ui_template_general_layout.ts
* 일반 화면 틀 `page-frame`(552-4 틀) — 프로젝트 밖 화면(대시보드 세부 · 설정 · B02 · 결제) 몸통: 페이지 머리 + 몸.
* 꼴 = createPageFrame — 머리(제목 20 · 설명 13 · 오른쪽 주 단추 자리) + 몸(세로 쌓음) · 대시보드 세부 페이지 꼴
* createGeneralLayout — 바탕 · 가운데 폭(--page-max-width) · 큰 제목(옛 꼴 그대로)
* 크기 = 폭 1120(대시보드 세부) · 머리 · 몸 사이 16 · 몸 안 사이 12
* 상태 = 없음
* 쓰는 법 = const f = createPageFrame(host, "구성원", "회사 사람 · 역할"); f.setAction(addBtn); f.body.append(table)
* 대신하는 옛 변종 = B01 `pageFrame`(`.b01-pg__head`) · `.b01-proj-head` · M01 `m01-head` · `.ui-wf`(안 씀)
* ========================================================================== */
import "./ui_template_general_layout.css";
export interface GeneralLayoutOptions {
pageClass?: string;
title?: string;
subtitle?: string;
content: HTMLElement | readonly HTMLElement[];
}
export interface GeneralLayoutHandle {
root: HTMLElement;
content: HTMLElement;
}
export function createGeneralLayout(options: GeneralLayoutOptions): GeneralLayoutHandle {
const root = document.createElement("div");
root.className = "ui-general-layout";
if (options.pageClass) root.classList.add(options.pageClass);
const inner = document.createElement("div");
inner.className = "ui-general-layout__inner";
if (options.title) {
const header = document.createElement("header");
header.className = "ui-general-layout__header";
const title = document.createElement("h1");
title.className = "ui-general-layout__title";
title.textContent = options.title;
header.append(title);
if (options.subtitle) {
const subtitle = document.createElement("p");
subtitle.className = "ui-general-layout__subtitle";
subtitle.textContent = options.subtitle;
header.append(subtitle);
}
inner.append(header);
}
const content = document.createElement("main");
content.className = "ui-general-layout__content";
content.append(...(Array.isArray(options.content) ? options.content : [options.content]));
inner.append(content);
root.append(inner);
return { root, content };
}
export interface PageFrame {
root: HTMLElement;
body: HTMLElement;
/** 머리 오른쪽 주 단추 — null = 비움 */
setAction: (action: HTMLElement | null) => void;
}
/** 일반 화면 틀 — host 에 붙임(null = 안 붙임) */
export function createPageFrame(host: HTMLElement | null, title: string, desc = ""): PageFrame {
const root = document.createElement("div");
root.className = "ui-page-frame";
const head = document.createElement("header");
head.className = "ui-page-frame__head";
const text = document.createElement("div");
text.className = "ui-page-frame__title-wrap";
const h = document.createElement("h2");
h.className = "ui-page-frame__title";
h.textContent = title;
text.append(h);
if (desc) {
const p = document.createElement("p");
p.className = "ui-page-frame__desc";
p.textContent = desc;
text.append(p);
}
const slot = document.createElement("div");
slot.className = "ui-page-frame__action";
head.append(text, slot);
const body = document.createElement("div");
body.className = "ui-page-frame__body";
root.append(head, body);
host?.append(root);
return {
root,
body,
setAction: (action) => slot.replaceChildren(...(action ? [action] : [])),
};
}