feat(757-1): 그리기 칸 긋기 단추 걷음 · 방식 넷 켬끔 = 긋기 시작 · 끝

- 분할 고르기 부품에 풂 꼴(clearable) · 부품 모음 견본에 더함
- 방식 칸(map_draw_kind)에 켬끔 꼴(onActive · setActive) — 켬 = 긋기 시작 · 고른 방식 다시 누름 = 긋기 끝 · 긋는 중 다른 방식 = 방식만 바뀜
- D03 · B05 그리기 칸 [긋기] 단추 걷음 · 긋기가 Enter · Esc · 붙어 끝나도 칸 켬 맞춤 · 노드 판은 그대로
- 시험 757_1 새로

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-02 23:03:15 +09:00
co-authored by Claude Sonnet 5.5
parent 1288e21e55
commit 011046c2a2
7 changed files with 78 additions and 27 deletions
+18 -3
View File
@@ -3,7 +3,9 @@
* 공용 긋기 방식 칸(PLAN 626-3 · 599-1 · 625-1) — 예정노선(D03) 그리기 칸 · 노드 판 · B05 평면 예정노선 그리기가 같이 씀.
* 꼴 = 마디 고름 2 × 2(자유지정 · 길이·기울기 고정 / 길이 고정 · 기울기 고정) + 길이 · 기울기 두 열(기울기 아래 ≈ °) ·
* 방식에 안 쓰는 칸은 숨김(막힘 = 권한 없음만) · 설명 글 없음(요구 463-6).
* 쓰는 법 = `createDrawKindFields({ value, onChange })` → { root, get, set, setDisabled }.
* 쓰는 법 = `createDrawKindFields({ value, onChange })` → { root, get, set, setDisabled, setActive }.
* 켬끔 꼴(589-9) = `onActive` 를 주면 고른 방식을 다시 누르면 풀림 · 방식을 고르면 켜짐 — 켬 = 긋기 시작 · 끔 = 긋기 끝
* (지금 켬인지는 `setActive` 로 맞춤 · 노드 판처럼 `onActive` 없는 곳은 늘 하나 고름).
* ========================================================================== */
import type { UiSize } from "@ui/ui_template_button";
@@ -40,31 +42,39 @@ export interface DrawKindFields {
/** 값을 바꿈(onChange 는 안 부름). */
set: (value: Partial<DrawKindValue>) => void;
setDisabled: (disabled: boolean) => void;
/** 켬끔 꼴에서 지금 켬인지 맞춤(onActive 는 안 부름 · 끔 = 모두 풀린 모양). */
setActive: (on: boolean) => void;
}
/** 긋기 방식 칸 — 고름 · 길이 · 기울기가 바뀔 때마다 `onChange(지금 값)`(빈 · 틀린 수는 칸 오류만). */
export function createDrawKindFields(opts: {
value: DrawKindValue;
onChange: (value: DrawKindValue) => void;
/** 켬끔 꼴 — 방식 고름 = true · 고른 방식 다시 누름 = false. */
onActive?: (on: boolean) => void;
size?: UiSize;
}): DrawKindFields {
const size = opts.size ?? 24;
let value = { ...opts.value };
let disabled = false;
let active = !opts.onActive;
const changed = (): void => opts.onChange({ ...value });
const segment = createSegment({
options: (Object.keys(DRAW_KIND_LABELS) as DrawConstraint[]).map((kind) => ({
value: kind,
label: DRAW_KIND_LABELS[kind],
})),
value: value.kind,
value: active ? value.kind : "",
size,
columns: 2,
clearable: !!opts.onActive,
ariaLabel: "긋기 방식",
onChange: (next) => {
if (next === "") return void ((active = false), opts.onActive?.(false));
value.kind = next as DrawConstraint;
fieldsState();
changed();
if (opts.onActive && !active) ((active = true), opts.onActive(true));
},
});
segment.root.dataset.role = "draw-constraint";
@@ -130,7 +140,7 @@ export function createDrawKindFields(opts: {
get: () => ({ ...value }),
set(next) {
value = { ...value, ...next };
segment.set(value.kind);
segment.set(active ? value.kind : "");
lengthField.input.value = String(value.lengthM);
slopeField.input.value = String(value.slopePct);
lengthField.setError(undefined);
@@ -142,5 +152,10 @@ export function createDrawKindFields(opts: {
disabled = next;
fieldsState();
},
setActive(on) {
if (!opts.onActive) return;
active = on;
segment.set(active ? value.kind : "");
},
};
}