- 새 D03_PlanAnalysis_UI_DrawPanel.ts — createDrawKindFields(노드 판 598-4 가 다시 씀) · 그리기 칸 몸 - 「둘 다」 → 「길이·기울기 고정」 · 칸 설명 글 걷음(요구 463-6) - 부품 마디 고름에 columns 덧(여러 줄 꼴) — 한 줄 꼴 그대로 - 지도 도구줄 연도 마커 단추 · 공용 표 줄 걷음 → 그리기 칸 끌기 단추 - 시험 553_4 · 568_1 고침(마커 자리 옮김 · 방식 칸 새 파일) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
80 lines
3.1 KiB
TypeScript
80 lines
3.1 KiB
TypeScript
/* =============================================================================
|
||
* ui_template_segment.ts
|
||
* 부품 「분할 고르기」(552-2 · 부품 모음 `#/b01-account?view=ui-kit`) — 붙은 칸 둘 ~ 다섯 중 하나
|
||
*
|
||
* 꼴 = 글 · 아이콘(+ title) · 글 + 아이콘
|
||
* 크기 = data-size 20 · 24 · 28 · 32(기본 28)
|
||
* 줄 = 한 줄(기본) · `columns: 2` = 2 × 2 처럼 여러 줄 칸(긴 이름 넷 · 599-1 D03 긋기 방식)
|
||
* 상태 = 마우스 `:hover` · 눌림 `:active` · 막힘 `disabled` · 고름 = aria-checked — CSS 는 `[data-state]` 로도 받음
|
||
* 쓰기 = `createSegment({ options: [{ value: "list", label: "목록" }, { value: "card", label: "카드" }], value: "list", onChange })`
|
||
* 대신 = B01 `.b01-sys-seg` · `.b01-home__seg` · `.b01-proj-seg` · B04 `b04-surface__sheet-method` · B05 `b05-routerec__pills` ·
|
||
* B06 `b06-design__btn(--active)` · CAD `.cad-inspector-tabs` · E04 · E06 · E07 `*-toggle` · M02 `m02-dfip__chips`
|
||
* ========================================================================== */
|
||
|
||
import { setUiSize, type UiSize } from "./ui_template_button";
|
||
import { icon, type IconName } from "./ui_template_icons";
|
||
import "./ui_template_segment.css";
|
||
|
||
export interface SegmentOption {
|
||
value: string;
|
||
label?: string;
|
||
icon?: IconName;
|
||
/** 아이콘만이면 필수 */
|
||
title?: string;
|
||
disabled?: boolean;
|
||
}
|
||
|
||
export interface SegmentHandle {
|
||
root: HTMLDivElement;
|
||
get: () => string;
|
||
/** 고름을 바꿈(onChange 는 안 부름) */
|
||
set: (value: string) => void;
|
||
}
|
||
|
||
export function createSegment(opts: {
|
||
options: SegmentOption[];
|
||
value: string;
|
||
onChange?: (value: string) => void;
|
||
/** 20 · 24 · 28 · 32 권함 */
|
||
size?: UiSize;
|
||
ariaLabel?: string;
|
||
/** 한 줄 칸 수 — 넘으면 다음 줄(없음 = 한 줄) */
|
||
columns?: number;
|
||
}): SegmentHandle {
|
||
const root = document.createElement("div");
|
||
root.className = "ui-segment";
|
||
root.setAttribute("role", "radiogroup");
|
||
if (opts.ariaLabel) root.setAttribute("aria-label", opts.ariaLabel);
|
||
setUiSize(root, opts.size ?? 28);
|
||
if (opts.columns) {
|
||
root.dataset.columns = String(opts.columns);
|
||
root.style.setProperty("--ui-segment-columns", String(opts.columns));
|
||
}
|
||
let current = opts.value;
|
||
const items = opts.options.map((o) => {
|
||
const b = document.createElement("button");
|
||
b.type = "button";
|
||
b.className = "ui-segment__item";
|
||
b.setAttribute("role", "radio");
|
||
b.dataset.value = o.value;
|
||
if (o.icon) b.append(icon(o.icon, 16));
|
||
if (o.label) b.append(o.label);
|
||
if (o.title) b.title = o.title;
|
||
if (o.title && !o.label) b.setAttribute("aria-label", o.title);
|
||
b.disabled = o.disabled ?? false;
|
||
b.addEventListener("click", () => {
|
||
if (current === o.value) return;
|
||
set(o.value);
|
||
opts.onChange?.(o.value);
|
||
});
|
||
return b;
|
||
});
|
||
const set = (value: string): void => {
|
||
current = value;
|
||
for (const b of items) b.setAttribute("aria-checked", String(b.dataset.value === value));
|
||
};
|
||
set(current);
|
||
root.append(...items);
|
||
return { root, get: () => current, set };
|
||
}
|