/* ============================================================================= * ui_template_segment.ts * 부품 「분할 고르기」(552-2 · 부품 모음 `#/b01-account?view=ui-kit`) — 붙은 칸 둘 ~ 다섯 중 하나 * * 꼴 = 글 · 아이콘(+ title) · 글 + 아이콘 * 크기 = data-size 20 · 24 · 28 · 32(기본 28) * 상태 = 마우스 `: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; }): 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); 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 }; }