- 위험 채움 토큰 밝음 #e5484d → #d6363c(흰 글 3.91 → 4.72) · 어두움 5.6 · 위험 글 #c0392b 그대로 - 새 부품 계산 줄(ui_template_calc_row) — B08 수리집수면적표 b08-hydro__row · 식 칸 배치를 대신함 - 표 부품 칸 램프(ui-data-table__lamp · --only · ✓) — B08 집계표 · 거리이정표 · B09 설계내역 램프 CSS 세 벌을 걷음(표지 class 는 풍선 · 가이드용으로 남김) - 모달 넓은 중간 창(wide + width 1100px · 1100 × 680) — B09 운반 창 손 인라인 크기를 걷음 - 값 목록 규칙 꼴(rule) — ☰ 설정 규칙 줄 ul/li 를 걷음 - 접이 구역 머리(createCollapsibleHead = 패널 머리 + 접는 제목) — B08 구조물도 「조합 연결」 제목(옛 b08-sheets__title)을 대신함 - 일반 화면 틀 좁은 폭 · 입력 칸 2열 · 끝 단추 줄 — D01 · E01 이 B02 CSS 를 빌리던 것을 끊음(가이드 장면 선택자 맞춤) - 부품 모음 견본 · 지킴 시험 test_557_2 · 낡은 시험(198_1 · 247_1 · 251_1 · 257_1 · 276_1 · 551_1)은 부품 CSS · 새 class 로 맞춤 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
108 lines
4.3 KiB
TypeScript
108 lines
4.3 KiB
TypeScript
/* =============================================================================
|
|
* ui_template_general_layout.ts
|
|
* 일반 화면 틀 `page-frame`(552-4 틀) — 프로젝트 밖 화면(대시보드 세부 · 설정 · B02 · 결제) 몸통: 페이지 머리 + 몸.
|
|
* 꼴 = createPageFrame — 머리(제목 20 · 설명 13 · 오른쪽 주 단추 자리) + 몸(세로 쌓음) · 대시보드 세부 페이지 꼴
|
|
* createGeneralLayout — 바탕 · 가운데 폭(--page-max-width) · 큰 제목(옛 꼴 그대로) · 좁은 폭(`narrow` · 720 · 557-2)
|
|
* createFormGrid — 입력 칸 2열 배치(좁은 화면 1열 · 사이 16 · 557-2) · 끝 단추 줄 = `ui-general-block__actions ui-general-block__actions--end`(오른쪽 · 위 16)
|
|
* 크기 = 폭 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`(안 씀) · D01 · E01 이 빌려 쓰던 B02 `b02-proj` · `b02-proj__grid` · `b02-proj__actions`
|
|
* ========================================================================== */
|
|
|
|
import "./ui_template_general_layout.css";
|
|
|
|
export interface GeneralLayoutOptions {
|
|
pageClass?: string;
|
|
/** 좁은 폭 720 — 입력 칸 두 줄짜리 양식 */
|
|
narrow?: boolean;
|
|
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);
|
|
if (options.narrow) root.classList.add("ui-general-layout--narrow");
|
|
|
|
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 };
|
|
}
|
|
|
|
/** 입력 칸 2열 배치(557-2) — 좁은 화면(640 아래) 1열 */
|
|
export function createFormGrid(fields: readonly HTMLElement[]): HTMLElement {
|
|
const grid = document.createElement("div");
|
|
grid.className = "ui-form-grid";
|
|
grid.append(...fields);
|
|
return grid;
|
|
}
|
|
|
|
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] : [])),
|
|
};
|
|
}
|