- 작업 화면 틀(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>
77 lines
3.2 KiB
TypeScript
77 lines
3.2 KiB
TypeScript
/* =============================================================================
|
|
* ui_template_list_row.ts
|
|
* 목록 줄 `list-row`(552-4 틀) — 패널 · 목록 안 고르는 줄 하나 · 왼쪽 글 · 오른쪽 덧붙임.
|
|
* 꼴 = 고르는 줄 · 두 줄(sub) · 끌기 손잡이(grip) · 왼쪽 색 띠(stripe) · 번호 원(no)
|
|
* 크기 = data-size 28 · 32 · 36 (기본 32)
|
|
* 상태 = 마우스 · 눌림 · 고름(`is-active` + aria-selected) · 막힘(disabled)
|
|
* 쓰는 법 = list.append(createListRow({ label: "B1 배수관", active: true, onClick: pick }))
|
|
* 대신하는 옛 변종 = `.ui-sidebar-row`(이 이름도 그대로 냄) · `.ui-tree__row` · `.ui-find__row` ·
|
|
* `b07-plan-manage__row` + `__grip` · `b05-drainage__basin` · `d02-points__row` · `m02-pick__item` …
|
|
* ========================================================================== */
|
|
|
|
import "./ui_template_list_row.css";
|
|
|
|
export interface ListRowOptions {
|
|
label: string;
|
|
/** 둘째 줄(흐린 글) */
|
|
sub?: string;
|
|
/** 오른쪽 끝 덧붙임(값 · 배지 · 단추) */
|
|
trailing?: HTMLElement | string;
|
|
/** 왼쪽 번호 원 */
|
|
no?: number | string;
|
|
/** 왼쪽 색 띠 — 공통 값 이름(예: "var(--color-success)") */
|
|
stripe?: string;
|
|
/** 끌기 손잡이 — 끌기 동작은 부르는 쪽 몫 */
|
|
grip?: boolean;
|
|
active?: boolean;
|
|
disabled?: boolean;
|
|
size?: 28 | 32 | 36;
|
|
title?: string;
|
|
onClick?: (event: Event) => void;
|
|
}
|
|
|
|
function span(className: string, text?: string): HTMLSpanElement {
|
|
const n = document.createElement("span");
|
|
n.className = className;
|
|
if (text !== undefined) n.textContent = text;
|
|
return n;
|
|
}
|
|
|
|
/** 줄 하나 — onClick 이 있으면 <button> · 없으면 <div> */
|
|
export function createListRow(opts: ListRowOptions): HTMLElement {
|
|
const row = document.createElement(opts.onClick ? "button" : "div");
|
|
if (row instanceof HTMLButtonElement) row.type = "button";
|
|
row.className = "ui-list-row ui-sidebar-row";
|
|
row.dataset.size = String(opts.size ?? 32);
|
|
row.setAttribute("role", "option");
|
|
if (opts.title) row.title = opts.title;
|
|
if (opts.stripe) {
|
|
row.classList.add("ui-list-row--stripe");
|
|
row.style.setProperty("--ui-list-row-stripe", opts.stripe);
|
|
}
|
|
if (opts.grip) row.append(span("ui-list-row__grip"));
|
|
if (opts.no !== undefined) row.append(span("ui-list-row__no", String(opts.no)));
|
|
const text = span("ui-list-row__text");
|
|
text.append(span("ui-list-row__label", opts.label));
|
|
if (opts.sub) text.append(span("ui-list-row__sub", opts.sub));
|
|
row.append(text);
|
|
if (opts.trailing !== undefined) {
|
|
const tail = span("ui-list-row__trailing");
|
|
tail.append(opts.trailing);
|
|
row.append(tail);
|
|
}
|
|
setListRowActive(row, Boolean(opts.active));
|
|
if (opts.disabled) {
|
|
if (row instanceof HTMLButtonElement) row.disabled = true;
|
|
row.setAttribute("aria-disabled", "true");
|
|
}
|
|
if (opts.onClick) row.addEventListener("click", opts.onClick);
|
|
return row;
|
|
}
|
|
|
|
/** 고름 켜고 끄기 — 클래스 · aria 한 번에 */
|
|
export function setListRowActive(row: HTMLElement, active: boolean): void {
|
|
row.classList.toggle("is-active", active);
|
|
row.setAttribute("aria-selected", String(active));
|
|
}
|