refactor(B05): 날 단추 · 작은 도구 단추를 부품 단추 · 아이콘 단추 · 켜기 칩 · 목록 줄로 (PLAN 553-2)
- 종단 도구 · [창 분할] = 단추 유리 · 보조 단 18 · ▲▼ = 아이콘 단추 선 18 · 배율 + − ⤢ = 아이콘 단추 22 - 배수 머리 단추 = 단추 22 · 층 단추 = 켜기 칩 20(색 점 = 층 색) · 유역 줄 = 목록 줄 32 - [추가] · [삭제] · [리셋] · [해제] · 확폭 = 단추 주 · 위험 고스트 · 보조 · [-][+] = 아이콘 단추 24 - 지도 도구줄 · 3D 보기 줄 = 단 32(34 에서) · 접기 ▾ = 아이콘 단추 18 · 잰 값 닫기 = 아이콘 단추 24 - 페이지 CSS 의 단추 꼴(테두리 · 바탕 · 글 · 둥글기) 지움 · 날 색 대체값(#d98a00 · #5b8def · #3a3f4a) 지움 - 시험 선택자 · 가짜 DOM(setAttribute) 같이 고침 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -55,16 +55,9 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
.b05-route-profile__tools > .b05-route-profile__popout {
|
||||
padding: var(--btn-bar-padding);
|
||||
font-size: var(--btn-bar-font-size);
|
||||
}
|
||||
|
||||
/* 유토곡선 · 배수유역 판 [창 분할](계획서 325-3) — 종단 [창 분할]과 같은 양식 · 유토는 판 좌상단에 띄움. */
|
||||
/* 유토곡선 · 배수유역 판 [창 분할](계획서 325-3) — 종단 [창 분할]과 같은 양식(부품 단추 단 18 · 553-2) · 유토는 판 좌상단에 띄움. */
|
||||
.b05-subpanel__popout {
|
||||
flex: none;
|
||||
padding: var(--btn-bar-padding);
|
||||
font-size: var(--btn-bar-font-size);
|
||||
}
|
||||
|
||||
.b05-profile__masshaul-overlay > .b05-subpanel__popout {
|
||||
|
||||
@@ -123,6 +123,7 @@ export function attachProfilePopout(
|
||||
button: HTMLButtonElement,
|
||||
): void {
|
||||
button.className = "ui-btn ui-btn--ghost b05-route-profile__popout";
|
||||
button.setAttribute("data-size", "18"); // 부품 단추 단 18(553-2) — 옆 도구 단추와 같은 키
|
||||
button.title = "종단 하단 패널을 별도 창으로 분할 · 다시 누르면 결합";
|
||||
attachPopout(profile, {
|
||||
piece: profile.root,
|
||||
@@ -139,6 +140,7 @@ export function attachSubPanelPopouts(profile: DesignProfile): void {
|
||||
const subButton = (title: string): HTMLButtonElement => {
|
||||
const button = document.createElement("button");
|
||||
button.className = "ui-btn ui-btn--ghost b05-subpanel__popout";
|
||||
button.setAttribute("data-size", "18");
|
||||
button.title = title;
|
||||
return button;
|
||||
};
|
||||
|
||||
@@ -283,7 +283,7 @@ export function createSpecForm(links: SpecLinks | null, hooks: SpecFormHooks = {
|
||||
if (!c.required && hooks.count?.(c) === undefined) {
|
||||
const remove = document.createElement("button");
|
||||
remove.type = "button";
|
||||
remove.className = "b05-route__irregular-btn";
|
||||
remove.className = "ui-btn ui-btn--danger-ghost b05-route__irregular-btn";
|
||||
remove.textContent = "삭제";
|
||||
remove.title = `${c.title} 상자 삭제`;
|
||||
remove.dataset.specRemove = c.id;
|
||||
@@ -333,7 +333,7 @@ export function createSpecForm(links: SpecLinks | null, hooks: SpecFormHooks = {
|
||||
if (c.required || (c.max && list.length >= c.max) || hooks.count?.(c) !== undefined) continue;
|
||||
const add = document.createElement("button");
|
||||
add.type = "button";
|
||||
add.className = "b05-route__irregular-btn b05-structure__spec-add";
|
||||
add.className = "ui-btn ui-btn--ghost b05-route__irregular-btn b05-structure__spec-add";
|
||||
add.textContent = `+ ${containerTitle(c, names, groupNames[c.link])}`;
|
||||
add.title = "추가";
|
||||
add.dataset.specAdd = c.id;
|
||||
|
||||
@@ -72,11 +72,15 @@ export function createDrainageChrome(
|
||||
|
||||
const updateButton = document.createElement("button");
|
||||
updateButton.type = "button";
|
||||
updateButton.className = "b05-drainage__analyze b05-drainage__update";
|
||||
// 머리 줄 단추 = 부품 「단추」 보조 · 단 22(553-2)
|
||||
updateButton.className = "ui-btn ui-btn--ghost b05-drainage__analyze b05-drainage__update";
|
||||
updateButton.setAttribute("data-size", "22");
|
||||
updateButton.textContent = "업데이트";
|
||||
const proposeButton = document.createElement("button");
|
||||
proposeButton.type = "button";
|
||||
proposeButton.className = "b05-drainage__analyze b05-drainage__tool b05-drainage__propose";
|
||||
proposeButton.className =
|
||||
"ui-btn ui-btn--ghost b05-drainage__analyze b05-drainage__tool b05-drainage__propose";
|
||||
proposeButton.setAttribute("data-size", "22");
|
||||
proposeButton.textContent = ui_locales.B05_Drainage_Btn_Propose[currentLanguageIndex];
|
||||
proposeButton.title = ui_locales.B05_Drainage_Btn_Propose_Tip[currentLanguageIndex];
|
||||
header.append(updateButton, proposeButton);
|
||||
|
||||
@@ -121,9 +121,12 @@ export function stepper(input: HTMLInputElement, stepM: number, decimals = 1): H
|
||||
const button = (label: string, delta: number): HTMLButtonElement => {
|
||||
const element = document.createElement("button");
|
||||
element.type = "button";
|
||||
element.className = "b05-structure__step";
|
||||
// 부품 「아이콘 단추」 단 24(553-2) · 폭은 덩어리 몫(28)
|
||||
element.className = "ui-icon-btn ui-icon-btn--ghost b05-structure__step";
|
||||
element.setAttribute("data-size", "24");
|
||||
element.textContent = label;
|
||||
element.title = `${stepM}m ${delta > 0 ? "늘리기" : "줄이기"}`;
|
||||
element.setAttribute("aria-label", element.title);
|
||||
element.addEventListener("click", nudge(delta));
|
||||
return element;
|
||||
};
|
||||
|
||||
@@ -10,6 +10,8 @@ import { stateKey } from "../A00_Common/b_page_state";
|
||||
import { currentLanguageIndex, ui_locales } from "@ui/ui_template_locale";
|
||||
import { themeColor } from "@ui/ui_template_palette";
|
||||
import { showToast } from "@ui/ui_template_elements";
|
||||
import { createToggle } from "@ui/ui_template_toggle";
|
||||
import { setListRowActive } from "@ui/ui_template_list_row";
|
||||
import {
|
||||
DRAINAGE_SHEET_LAYERS,
|
||||
fetchCachedSheetLayer,
|
||||
@@ -92,7 +94,7 @@ export function formatArea(areaM2: number): string {
|
||||
return areaM2 >= 10000 ? `${(areaM2 / 10000).toFixed(2)}ha` : `${Math.round(areaM2)}㎡`;
|
||||
}
|
||||
|
||||
/** 제목 우측 표시 토글 — 등고선·세류·흐름 화살표·상류 세류가 모두 같은 양식을 쓴다. */
|
||||
/** 제목 우측 표시 토글 — 등고선·세류·흐름 화살표·상류 세류가 모두 같은 양식(부품 「켜기」 칩 · 단 20 · 색 점 = 층 색 · 553-2). */
|
||||
export function addLayerToggle(
|
||||
container: HTMLElement,
|
||||
label: string,
|
||||
@@ -101,20 +103,20 @@ export function addLayerToggle(
|
||||
onToggle: (next: boolean) => void,
|
||||
title?: string,
|
||||
): HTMLButtonElement {
|
||||
const button = document.createElement("button");
|
||||
button.type = "button";
|
||||
button.className = "b05-drainage__layer-button" + (initial ? " is-active" : "");
|
||||
button.textContent = label;
|
||||
button.style.setProperty("--b05-layer-color", color);
|
||||
button.setAttribute("aria-pressed", String(initial));
|
||||
const button = createToggle({
|
||||
kind: "chip",
|
||||
label,
|
||||
checked: initial,
|
||||
dot: color,
|
||||
size: 20,
|
||||
onChange: (active) => {
|
||||
button.classList.toggle("is-active", active);
|
||||
onToggle(active);
|
||||
},
|
||||
}).root;
|
||||
button.classList.add("b05-drainage__layer-button");
|
||||
button.classList.toggle("is-active", initial);
|
||||
if (title) button.title = title;
|
||||
let active = initial;
|
||||
button.addEventListener("click", () => {
|
||||
active = !active;
|
||||
button.classList.toggle("is-active", active);
|
||||
button.setAttribute("aria-pressed", String(active));
|
||||
onToggle(active);
|
||||
});
|
||||
container.append(button);
|
||||
return button;
|
||||
}
|
||||
@@ -140,7 +142,12 @@ export function renderBasinRows(
|
||||
basins.forEach((basin) => {
|
||||
const row = document.createElement("button");
|
||||
row.type = "button";
|
||||
row.className = "b05-drainage__basin" + (selected === basin.index ? " is-selected" : "");
|
||||
// 목록 줄 = 부품 「목록 줄」 단 32(553-2) · 옛 이름(is-selected)은 자리 몫
|
||||
const picked = selected === basin.index;
|
||||
row.className =
|
||||
"ui-list-row ui-sidebar-row b05-drainage__basin" + (picked ? " is-selected" : "");
|
||||
row.setAttribute("data-size", "32");
|
||||
setListRowActive(row, picked);
|
||||
const badge = document.createElement("span");
|
||||
badge.className = "b05-drainage__basin-index";
|
||||
badge.textContent = String(basin.index);
|
||||
|
||||
@@ -58,12 +58,14 @@ export function createDrainagePropose(deps: {
|
||||
const title = document.createElement("span");
|
||||
const add = document.createElement("button");
|
||||
add.type = "button";
|
||||
add.className = "b05-drainage__analyze";
|
||||
add.className = "ui-btn ui-btn--filled b05-drainage__analyze";
|
||||
add.setAttribute("data-size", "22");
|
||||
add.textContent = "넣기";
|
||||
add.title = "고른 후보만 관으로 넣습니다 — 초안이라 [저장] 때 남습니다.";
|
||||
const shut = document.createElement("button");
|
||||
shut.type = "button";
|
||||
shut.className = "b05-drainage__analyze";
|
||||
shut.className = "ui-btn ui-btn--ghost b05-drainage__analyze";
|
||||
shut.setAttribute("data-size", "22");
|
||||
shut.textContent = "닫기";
|
||||
head.append(title, add, shut);
|
||||
const list = document.createElement("ul");
|
||||
|
||||
@@ -51,7 +51,8 @@ export function createDrainageSuggest(
|
||||
const title = document.createElement("span");
|
||||
const apply = document.createElement("button");
|
||||
apply.type = "button";
|
||||
apply.className = "b05-drainage__analyze";
|
||||
apply.className = "ui-btn ui-btn--filled b05-drainage__analyze";
|
||||
apply.setAttribute("data-size", "22");
|
||||
apply.textContent = "적용";
|
||||
const applyTitle =
|
||||
"관경 · 시설 제안을 관 초안에 한 번에 얹습니다 — [저장] 때 남습니다(관 자리는 [자동 제안]).";
|
||||
|
||||
@@ -233,14 +233,14 @@ export function createIrregularStationsSection(
|
||||
|
||||
const primary = document.createElement("button");
|
||||
primary.type = "button";
|
||||
primary.className = "b05-route__irregular-btn is-primary";
|
||||
primary.className = "ui-btn ui-btn--filled b05-route__irregular-btn is-primary";
|
||||
const remove = document.createElement("button");
|
||||
remove.type = "button";
|
||||
remove.className = "b05-route__irregular-btn is-danger";
|
||||
remove.className = "ui-btn ui-btn--danger-ghost b05-route__irregular-btn is-danger";
|
||||
remove.textContent = "삭제";
|
||||
const reset = document.createElement("button");
|
||||
reset.type = "button";
|
||||
reset.className = "b05-route__irregular-btn";
|
||||
reset.className = "ui-btn ui-btn--ghost b05-route__irregular-btn";
|
||||
reset.textContent = "리셋";
|
||||
const actions = document.createElement("div");
|
||||
actions.className = "b05-route__irregular-actions";
|
||||
|
||||
@@ -109,6 +109,10 @@ export function createViewControls(callbacks: ViewControlCallbacks): {
|
||||
separator3,
|
||||
corridorRefresh,
|
||||
);
|
||||
// 보기 줄 단추 = 부품 단추 단 32(553-2)
|
||||
viewControls
|
||||
.querySelectorAll<HTMLElement>(".ui-btn")
|
||||
.forEach((b) => b.setAttribute("data-size", "32"));
|
||||
|
||||
return {
|
||||
viewControls,
|
||||
|
||||
@@ -23,7 +23,7 @@ import { viewOf } from "../common_util/common_util_view_window";
|
||||
|
||||
/** 버튼 폭(21px)에 여유를 더한 값 — 이보다 가까우면 겹친 것으로 본다. */
|
||||
const BUTTON_CLEARANCE_PX = 23;
|
||||
const BUTTON_HALF_PX = 10;
|
||||
const BUTTON_HALF_PX = 9; // 부품 아이콘 단추 단 18 의 반(553-2)
|
||||
/** 길게 누르기: 이만큼 유지하면 반복이 시작되고, 그 뒤 초당 10회(0.1m씩)로 이어진다. */
|
||||
export const HOLD_DELAY_MS = 500;
|
||||
export const HOLD_INTERVAL_MS = 100;
|
||||
@@ -286,8 +286,11 @@ function overlayButton(
|
||||
): HTMLButtonElement {
|
||||
const button = document.createElement("button");
|
||||
button.type = "button";
|
||||
button.className = `b05-profile-edit__btn ${className}`;
|
||||
// 부품 「아이콘 단추」 선 꼴 · 단 18(553-2) · 글자 기호 그대로
|
||||
button.className = `ui-icon-btn ui-icon-btn--outline b05-profile-edit__btn ${className}`;
|
||||
button.setAttribute("data-size", "18");
|
||||
button.textContent = glyph;
|
||||
button.setAttribute("aria-label", title);
|
||||
button.title = `${title}\n(길게 누르면 0.5초 뒤부터 연속 조정)`;
|
||||
// 포인터로 누르면 즉시 1회 반응하고, 이어지는 click은 중복이므로 삼킨다.
|
||||
let swallowClick = false;
|
||||
|
||||
@@ -73,10 +73,12 @@ export interface ProfileTools {
|
||||
mountOverlay: (geom: FreeChartGeom) => void;
|
||||
}
|
||||
|
||||
/** 도구 단추 = 부품 「단추」 유리 · 단 18(553-2 · 클래스로 — 시험이 별칭 없이 이 파일을 돌림) */
|
||||
function toolButton(label: string, title: string, onClick: () => void): HTMLButtonElement {
|
||||
const button = document.createElement("button");
|
||||
button.type = "button";
|
||||
button.className = "b05-route-profile__tool";
|
||||
button.className = "ui-btn ui-btn--glass b05-route-profile__tool";
|
||||
button.setAttribute("data-size", "18");
|
||||
button.textContent = label;
|
||||
button.title = title;
|
||||
button.addEventListener("click", (event) => {
|
||||
|
||||
@@ -45,9 +45,12 @@ export function createProfileZoom(onChange: () => void): ProfileZoom {
|
||||
function add(label: string, title: string, action: () => void): HTMLButtonElement {
|
||||
const button = document.createElement("button");
|
||||
button.type = "button";
|
||||
button.className = "b05-profile__zoom-btn";
|
||||
// 부품 「아이콘 단추」 단 22(553-2) · 글자 기호 그대로
|
||||
button.className = "ui-icon-btn ui-icon-btn--ghost b05-profile__zoom-btn";
|
||||
button.setAttribute("data-size", "22");
|
||||
button.textContent = label;
|
||||
button.title = title;
|
||||
button.setAttribute("aria-label", title);
|
||||
button.addEventListener("click", (event) => {
|
||||
// 카드·측점 선택으로 번지면 그래프를 다시 그리며 방금 맞춘 배율이 날아간다.
|
||||
event.stopPropagation();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { createButton } from "@ui/ui_template_elements";
|
||||
import { createIconButton } from "@ui/ui_template_elements";
|
||||
import { createSidePanels } from "@ui/ui_template_side_panels";
|
||||
import { bindFootprintToggle } from "./B05_Profile_UI_RouteEdit_Footprint";
|
||||
import { bindMarkToggle } from "./B05_Profile_UI_RouteEdit_Marks";
|
||||
@@ -80,38 +80,38 @@ export function createRouteEditChrome(
|
||||
<div class="b05-routeedit__canvas-wrap" aria-label="계획노선 편집">
|
||||
<canvas class="b05-routeedit__canvas"></canvas>
|
||||
<div class="b05-route__view-controls b05-routeedit__tools">
|
||||
<button type="button" class="ui-btn ui-btn--glass b05-routeedit__hint-toggle"
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass b05-routeedit__hint-toggle"
|
||||
data-act="hint-toggle" aria-expanded="false" title="조작 도움말 펼치기 · 접기">?</button>
|
||||
<i class="b05-route__view-separator" aria-hidden="true"></i>
|
||||
<button type="button" class="ui-btn ui-btn--glass" data-act="undo"
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="undo"
|
||||
title="되돌리기 (Ctrl+Z)" aria-label="되돌리기" disabled>${HISTORY_ICON.undo}</button>
|
||||
<button type="button" class="ui-btn ui-btn--glass" data-act="redo"
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="redo"
|
||||
title="다시하기 (Ctrl+Y)" aria-label="다시하기" disabled>${HISTORY_ICON.redo}</button>
|
||||
<i class="b05-route__view-separator" aria-hidden="true"></i>
|
||||
<span data-slot="tools"></span>
|
||||
<i class="b05-route__view-separator" aria-hidden="true"></i>
|
||||
<button type="button" class="ui-btn ui-btn--glass" data-act="rotate-ccw"
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="rotate-ccw"
|
||||
title="반시계로 돌리기" aria-label="반시계로 돌리기">${HALF_TURN_ICON.ccw}</button>
|
||||
<button type="button" class="ui-btn ui-btn--glass" data-act="rotate-cw"
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="rotate-cw"
|
||||
title="시계로 돌리기" aria-label="시계로 돌리기">${HALF_TURN_ICON.cw}</button>
|
||||
<button type="button" class="ui-btn ui-btn--glass" data-act="contour-minor"
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="contour-minor"
|
||||
aria-pressed="false" disabled
|
||||
title="1m 간격 등고선을 얇고 옅게 겹칩니다 (확대하면 보임)">1m 등고선</button>
|
||||
<button type="button" class="ui-btn ui-btn--glass" data-act="stations"
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="stations"
|
||||
title="측점 눈금 · 번호를 평면에 보이기 · 숨기기 (시점 · 종점 이름표는 늘 보임)">측점</button>
|
||||
<button type="button" class="ui-btn ui-btn--glass" data-act="slopes"
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="slopes"
|
||||
title="측점 사이 기울기(%)를 평면에 보이기 · 숨기기 (확대해야 보임)">기울기</button>
|
||||
<button type="button" class="ui-btn ui-btn--glass" data-act="footprint"
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="footprint"
|
||||
title="도로 끝 · 비탈 끝(깎기 붉음 · 쌓기 청록)을 평면에 겹칩니다">절/성토선</button>
|
||||
<button type="button" class="ui-btn ui-btn--glass" data-act="measure"
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="measure"
|
||||
title="노선 위 두 점을 눌러 거리·기울기를 잽니다 (Shift+클릭도 같음)">거리 재기</button>
|
||||
<i class="b05-route__view-separator" aria-hidden="true"></i>
|
||||
<button type="button" class="ui-btn ui-btn--glass" data-act="station-snap"
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="station-snap"
|
||||
aria-pressed="false"
|
||||
title="켜면 고친 곡선의 가운데(MC)를 고른 간격 배수에 맞춥니다 — 일반측점(20 m)은 그대로 · MC 가 일반측점 위가 아니면 「No.N+10 (MC)」 특별측점을 더함 · 손대지 않은 곡선은 그 자리 유지 · 고정 교각점은 그대로 · 못 맞춘 곡선은 상태줄 「측점 밖 곡선」 · [저장] 때 저장">측점 스냅</button>
|
||||
<label class="b05-routeedit__terrain b05-routeedit__snap-step"
|
||||
title="측점 스냅 간격 — 곡선 가운데(MC)를 이 간격 배수에 맞춥니다(측점 No. = 측점 간격)">간격
|
||||
<select class="ui-select ui-select--sm" data-act="snap-step">
|
||||
<select class="ui-select ui-select--sm" data-size="32" data-act="snap-step">
|
||||
<option value="10">10 m</option>
|
||||
<option value="station">측점 No.</option>
|
||||
</select>
|
||||
@@ -140,7 +140,7 @@ export function createRouteEditChrome(
|
||||
<span><i class="is-planned"></i> 계획노선</span>
|
||||
</span>
|
||||
<span class="b05-routeedit__summary"></span>
|
||||
<button type="button" class="b05-routeedit__info-toggle" data-act="info-toggle"
|
||||
<button type="button" data-size="18" class="ui-icon-btn ui-icon-btn--ghost b05-routeedit__info-toggle" data-act="info-toggle"
|
||||
aria-expanded="true" title="상태 · 범례 글판 접기 · 펴기">▾</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -148,7 +148,10 @@ export function createRouteEditChrome(
|
||||
<aside class="b05-routeedit__side-wrap"></aside>`;
|
||||
parent.append(overlay);
|
||||
// 부른 쪽 단추([3D])도 같은 유리 단추로 — 지도 위에 떠 있는 도구줄.
|
||||
tools.forEach((tool) => tool.classList.replace("ui-btn--ghost", "ui-btn--glass"));
|
||||
tools.forEach((tool) => {
|
||||
tool.classList.replace("ui-btn--ghost", "ui-btn--glass");
|
||||
tool.setAttribute("data-size", "32"); // 도구줄 단 32(553-2)
|
||||
});
|
||||
overlay.querySelector('[data-slot="tools"]')!.replaceWith(...tools);
|
||||
|
||||
// 횡단 미리보기 = 패널 양식(382-1 · 손잡이 · 머리 · 폭 끌기 · 열림 · 폭 기억) · 자리는 지도 위 덮개 그대로 ·
|
||||
@@ -223,10 +226,8 @@ export function createRouteEditChrome(
|
||||
lift.observe(info);
|
||||
lift.observe(overlay.querySelector(".b05-routeedit__side-wrap")!);
|
||||
|
||||
const measureCloseButton = createButton({ label: "✕", variant: "ghost" });
|
||||
const measureCloseButton = createIconButton({ glyph: "✕", title: "닫기", size: 24 });
|
||||
measureCloseButton.classList.add("b05-routeedit__measure-close");
|
||||
measureCloseButton.setAttribute("aria-label", "닫기");
|
||||
measureCloseButton.title = "닫기";
|
||||
overlay.querySelector('[data-slot="measure-close"]')!.replaceWith(measureCloseButton);
|
||||
|
||||
const canvas = overlay.querySelector<HTMLCanvasElement>(".b05-routeedit__canvas")!;
|
||||
|
||||
@@ -31,9 +31,9 @@ const FIT_MARGIN_M = 30;
|
||||
export const RECOMMEND_MAP_HTML = `
|
||||
<canvas class="b05-routerec__map"></canvas>
|
||||
<div class="b05-routeedit__spin">
|
||||
<button type="button" class="ui-btn ui-btn--glass" data-act="rotate-ccw"
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="rotate-ccw"
|
||||
title="반시계로 돌리기" aria-label="반시계로 돌리기">${HALF_TURN_ICON.ccw}</button>
|
||||
<button type="button" class="ui-btn ui-btn--glass" data-act="rotate-cw"
|
||||
<button type="button" data-size="32" class="ui-btn ui-btn--glass" data-act="rotate-cw"
|
||||
title="시계로 돌리기" aria-label="시계로 돌리기">${HALF_TURN_ICON.cw}</button>
|
||||
</div>`;
|
||||
|
||||
|
||||
@@ -123,14 +123,14 @@ export function buildStructuresForm(options: {
|
||||
|
||||
const primary = document.createElement("button");
|
||||
primary.type = "button";
|
||||
primary.className = "b05-route__irregular-btn is-primary";
|
||||
primary.className = "ui-btn ui-btn--filled b05-route__irregular-btn is-primary";
|
||||
const removeButton = document.createElement("button");
|
||||
removeButton.type = "button";
|
||||
removeButton.className = "b05-route__irregular-btn is-danger";
|
||||
removeButton.className = "ui-btn ui-btn--danger-ghost b05-route__irregular-btn is-danger";
|
||||
removeButton.textContent = "삭제";
|
||||
const resetButton = document.createElement("button");
|
||||
resetButton.type = "button";
|
||||
resetButton.className = "b05-route__irregular-btn";
|
||||
resetButton.className = "ui-btn ui-btn--ghost b05-route__irregular-btn";
|
||||
resetButton.textContent = "리셋";
|
||||
const actions = document.createElement("div");
|
||||
actions.className = "b05-route__irregular-actions";
|
||||
|
||||
@@ -249,7 +249,7 @@ export function renderStructureList(params: StructureListParams): void {
|
||||
clear.className = "b05-route__irregular-clear";
|
||||
const button = document.createElement("button");
|
||||
button.type = "button";
|
||||
button.className = "b05-route__irregular-btn is-danger";
|
||||
button.className = "ui-btn ui-btn--danger-ghost b05-route__irregular-btn is-danger";
|
||||
button.textContent = "구조물 전체 삭제";
|
||||
button.addEventListener("click", params.onClearAll);
|
||||
clear.append(button);
|
||||
|
||||
@@ -40,7 +40,7 @@ export function buildSummaryRow(): SummaryRow {
|
||||
name.dataset.b05Summary = "pick";
|
||||
const clear = document.createElement("button");
|
||||
clear.type = "button";
|
||||
clear.className = "b05-route__irregular-btn";
|
||||
clear.className = "ui-btn ui-btn--ghost b05-route__irregular-btn";
|
||||
clear.textContent = "해제";
|
||||
clear.dataset.b05Summary = "clear";
|
||||
const line = document.createElement("div");
|
||||
|
||||
@@ -69,7 +69,7 @@ export function createWideningBox(hooks: {
|
||||
const on = !isRunOff(run, off);
|
||||
const button = document.createElement("button");
|
||||
button.type = "button";
|
||||
button.className = `b05-route__irregular-btn${on ? " is-on" : ""}`;
|
||||
button.className = `ui-btn ui-btn--ghost b05-route__irregular-btn${on ? " is-on" : ""}`;
|
||||
button.setAttribute("aria-pressed", String(on));
|
||||
button.dataset.wideningRun = `${run.start_m}-${run.end_m}`;
|
||||
const from = stationLabel(run.start_m, step);
|
||||
|
||||
@@ -197,10 +197,10 @@ html.is-bm-route .b05-route__view-controls {
|
||||
}
|
||||
|
||||
/* 방위 나침반을 놓을 자리 — ISO 버튼 바로 아래(2026-09-03 사용자 지시).
|
||||
버튼 줄 높이 34px + 위 여백 16px 아래에 붙인다. 위젯 모양·색은 공용
|
||||
버튼 줄 높이 32px(단추 단 32) + 위 여백 16px 아래에 붙인다. 위젯 모양·색은 공용
|
||||
(`ui_template/ui_template_compass.css`)이고 여기서는 위치만 준다. */
|
||||
.b05-route__compass {
|
||||
top: calc(var(--spacing-16) + 34px + var(--spacing-8));
|
||||
top: calc(var(--spacing-16) + 32px + var(--spacing-8));
|
||||
left: var(--spacing-16);
|
||||
}
|
||||
|
||||
@@ -217,9 +217,9 @@ html.is-bm-route .b05-route__view-controls {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.b05-route__view-controls .ui-btn {
|
||||
height: 34px;
|
||||
padding: 0 var(--spacing-8);
|
||||
/* 보기 줄 단추 = 부품 단추 단 32(553-2) · 줄 폭이 지도 폭을 넘지 않게 안 여백은 8 그대로 */
|
||||
.b05-route__view-controls .ui-btn[data-size] {
|
||||
padding-inline: var(--spacing-8);
|
||||
}
|
||||
|
||||
.b05-route__view-separator {
|
||||
@@ -231,7 +231,7 @@ html.is-bm-route .b05-route__view-controls {
|
||||
/* [3D 업데이트] 대기 표시 — 계획선 편집이 3D에 아직 안 들어갔음을 점으로 알린다. */
|
||||
.b05-route__view-controls .ui-btn.is-pending {
|
||||
position: relative;
|
||||
border-color: var(--color-warning, #d98a00);
|
||||
border-color: var(--color-warning);
|
||||
}
|
||||
|
||||
.b05-route__view-controls .ui-btn.is-pending::after {
|
||||
@@ -242,7 +242,7 @@ html.is-bm-route .b05-route__view-controls {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: var(--color-warning, #d98a00);
|
||||
background: var(--color-warning);
|
||||
}
|
||||
|
||||
.b05-route__panel {
|
||||
@@ -356,30 +356,14 @@ html.is-bm-route .b05-route__view-controls {
|
||||
gap: var(--spacing-8);
|
||||
}
|
||||
|
||||
/* [추가] · [삭제] · [리셋] = 부품 「단추」(553-2 · 주 filled · 위험 고스트 · 보조 ghost) — 크기 = 좌측 패널 양식 */
|
||||
.b05-route__irregular-btn {
|
||||
flex: 1 1 0;
|
||||
padding: var(--spacing-8);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-inputs);
|
||||
background: var(--color-surface);
|
||||
color: var(--color-text-body);
|
||||
font-size: var(--text-caption);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.b05-route__irregular-btn.is-primary {
|
||||
border-color: color-mix(in srgb, var(--color-royal-amethyst, rgb(109 40 217)) 55%, transparent);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.b05-route__irregular-btn.is-danger {
|
||||
border-color: color-mix(in srgb, var(--color-danger) 50%, transparent);
|
||||
color: var(--color-danger);
|
||||
}
|
||||
|
||||
.b05-route__irregular-btn:disabled {
|
||||
opacity: 0.45;
|
||||
cursor: default;
|
||||
/* 안 여백 8 그대로 — 옆 칸 폭 보호(구조물 조합 [해제]) */
|
||||
.b05-route__irregular-btn.ui-btn {
|
||||
padding-inline: var(--spacing-8);
|
||||
}
|
||||
|
||||
.b05-route__irregular-list {
|
||||
@@ -590,27 +574,7 @@ html.is-bm-route .b05-route__view-controls {
|
||||
margin-right: var(--spacing-8);
|
||||
}
|
||||
|
||||
.b05-route-profile__tool {
|
||||
padding: var(--btn-bar-padding);
|
||||
border: 1px solid color-mix(in srgb, var(--color-border) 75%, transparent);
|
||||
border-radius: 3px;
|
||||
background: color-mix(in srgb, var(--color-surface-raised) 80%, transparent);
|
||||
color: var(--color-text);
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--btn-bar-font-size);
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.b05-route-profile__tool:disabled {
|
||||
opacity: 0.35;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.b05-route-profile__tool.is-active {
|
||||
border-color: var(--color-primary);
|
||||
background: color-mix(in srgb, var(--color-primary) 22%, transparent);
|
||||
}
|
||||
/* 종단 도구 단추 = 부품 「단추」 유리 · 단 18(553-2 · `_Profile_Tools.ts`) */
|
||||
|
||||
.b05-route-profile__tool-hint {
|
||||
color: var(--color-text-muted);
|
||||
|
||||
@@ -87,28 +87,9 @@
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* 표시 토글 버튼 — B04 지도 레이어 버튼(.b04-map__layer-button--gis)과 같은 양식을 쓴다.
|
||||
크기(패딩·글자)만 이 패널 기준을 유지한다(2026-08-01 사용자 지시). */
|
||||
/* 표시 토글 = 부품 「켜기」 칩 단 20(553-2 · 색 점 = 층 선 색) — 한 줄 유지 · 좁아져도 안 쭈그러듦. */
|
||||
.b05-drainage__layer-button {
|
||||
/* 한 줄 유지 — 좁아져도 글자가 접히거나 쭈그러들지 않게 크기를 고정한다. */
|
||||
flex: 0 0 auto;
|
||||
white-space: nowrap;
|
||||
padding: 2px var(--spacing-8);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-inputs);
|
||||
background: var(--color-surface);
|
||||
color: var(--color-text-secondary);
|
||||
font-size: var(--text-caption);
|
||||
opacity: 0.55;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* 켜진 레이어는 그 레이어의 선 색을 테두리·글자·안쪽 링에 그대로 쓴다(지도와 바로 대조). */
|
||||
.b05-drainage__layer-button.is-active {
|
||||
border-color: var(--b05-layer-color, var(--color-border));
|
||||
box-shadow: inset 0 0 0 1px var(--b05-layer-color, transparent);
|
||||
color: var(--b05-layer-color, var(--color-text-body));
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* 배관 우클릭 메뉴 — 뷰포트 기준 절대 위치(B04 지도와 같은 조작) · 모양은 공용 `.ui-ctx-menu`. */
|
||||
@@ -156,21 +137,9 @@
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* 머리 줄 단추 = 부품 「단추」 단 22(553-2) — 자리만 */
|
||||
.b05-drainage__analyze {
|
||||
margin-left: auto;
|
||||
padding: 2px var(--spacing-8);
|
||||
border: 1px solid
|
||||
color-mix(in srgb, var(--color-royal-amethyst, rgb(109 40 217)) 55%, transparent);
|
||||
border-radius: var(--radius-inputs);
|
||||
background: var(--color-surface);
|
||||
color: var(--color-text-body);
|
||||
font-size: var(--text-caption);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.b05-drainage__analyze:disabled {
|
||||
opacity: 0.45;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* 머리 줄 둘째 단추([자동 제안]) — [업데이트] 우측에 나란히(auto 마진 해제). */
|
||||
@@ -178,21 +147,11 @@
|
||||
margin-left: var(--spacing-4, 4px);
|
||||
}
|
||||
|
||||
/* 배관 편집 토글 활성 상태. */
|
||||
.b05-drainage__analyze.is-active {
|
||||
background: color-mix(
|
||||
in srgb,
|
||||
var(--color-royal-amethyst, rgb(109 40 217)) 18%,
|
||||
var(--color-surface)
|
||||
);
|
||||
border-color: var(--color-royal-amethyst, rgb(109 40 217));
|
||||
}
|
||||
|
||||
/* 유역 제원 목록 — 면적·유역표고·유하거리·관경(수식 확정 전까지 "미정"). */
|
||||
/* 유역 목록은 3행까지만 보이고 나머지는 스크롤한다(2026-08-01 사용자 지시).
|
||||
높이를 비율로 잡으면 유역 수와 무관하게 잘려 몇 개인지 가늠이 안 된다. */
|
||||
.b05-drainage__basins {
|
||||
--b05-basin-row: 34px;
|
||||
--b05-basin-row: 32px;
|
||||
|
||||
display: flex;
|
||||
max-height: calc(3 * var(--b05-basin-row) + 2 * 2px + 2 * var(--spacing-8));
|
||||
@@ -217,25 +176,11 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
.b05-drainage__basin {
|
||||
display: flex;
|
||||
min-height: var(--b05-basin-row);
|
||||
align-items: center;
|
||||
gap: var(--spacing-8);
|
||||
padding: var(--spacing-4) var(--spacing-8);
|
||||
border: 1px solid transparent;
|
||||
border-radius: var(--radius-inputs);
|
||||
background: none;
|
||||
color: var(--color-text-body);
|
||||
/* 유역 줄 = 부품 「목록 줄」 단 32(553-2) — 번호 원 · 제원 왼쪽 붙임 · 글 12(제원 한 줄) */
|
||||
.b05-drainage__basin.ui-list-row {
|
||||
flex: none;
|
||||
justify-content: flex-start;
|
||||
font-size: var(--text-caption);
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.b05-drainage__basin:hover,
|
||||
.b05-drainage__basin.is-selected {
|
||||
border-color: var(--color-border);
|
||||
background: var(--color-surface);
|
||||
}
|
||||
|
||||
/* 지도 위 서클 번호와 같은 파스텔 색을 써서 목록 항목과 유역을 눈으로 잇는다. */
|
||||
@@ -270,7 +215,7 @@
|
||||
/* 배수유역 낡음(326-6) — 옛 그림 그대로 · [업데이트] 단추에 점([3D 업데이트] 꼴) · 구석 「계산 중」. */
|
||||
.b05-drainage__update.is-pending {
|
||||
position: relative;
|
||||
border-color: var(--color-warning, #d98a00);
|
||||
border-color: var(--color-warning);
|
||||
}
|
||||
|
||||
.b05-drainage__update.is-pending::after {
|
||||
@@ -281,7 +226,7 @@
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: var(--color-warning, #d98a00);
|
||||
background: var(--color-warning);
|
||||
}
|
||||
|
||||
.b05-drainage__busy {
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
|
||||
/* 조작 설명 — 도구줄 아래 왼쪽 · 기본 접힘 · [?] 로 펼침(345-5 덧 3 · 352-1) · 펼치면 **2열**(사용자 지시 ⑩). */
|
||||
.b05-routeedit__hint {
|
||||
top: calc(var(--spacing-16) + 34px + var(--spacing-8));
|
||||
top: calc(var(--spacing-16) + 32px + var(--spacing-8));
|
||||
left: var(--spacing-16);
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
@@ -72,11 +72,10 @@
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.b05-routeedit__hint-toggle {
|
||||
.b05-routeedit__hint-toggle.ui-btn[data-size] {
|
||||
flex: none;
|
||||
padding: var(--spacing-4, 4px) var(--spacing-8);
|
||||
padding-inline: var(--spacing-8);
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
@@ -132,22 +131,12 @@
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* 접기 = 부품 「아이콘 단추」 단 18(553-2) */
|
||||
.b05-routeedit__info-toggle {
|
||||
grid-column: -2;
|
||||
padding: 0 2px;
|
||||
border: 0;
|
||||
background: none;
|
||||
color: inherit;
|
||||
font: inherit;
|
||||
line-height: inherit;
|
||||
cursor: pointer;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.b05-routeedit__info-toggle:hover {
|
||||
color: var(--color-text-body);
|
||||
}
|
||||
|
||||
/* 회전 단추 — 지도 오른쪽 위(사용자 지시 ⑯) · 횡단 판 왼쪽에 앉음(352-1). 여기만 클릭을 받는다. */
|
||||
.b05-routeedit__spin {
|
||||
position: absolute;
|
||||
@@ -158,12 +147,6 @@
|
||||
gap: var(--spacing-8);
|
||||
}
|
||||
|
||||
.b05-routeedit__spin .ui-btn {
|
||||
padding: var(--spacing-8) var(--spacing-12);
|
||||
font-size: var(--text-body);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.b05-routeedit__legend {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -192,7 +175,7 @@
|
||||
.b05-routeedit__side-wrap {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
top: calc(var(--spacing-16) + 34px + var(--spacing-8)); /* 도구줄 · 회전 단추 줄 아래 */
|
||||
top: calc(var(--spacing-16) + 32px + var(--spacing-8)); /* 도구줄(단 32) · 회전 단추 줄 아래 */
|
||||
right: var(--spacing-12);
|
||||
bottom: calc(var(--spacing-12) + var(--b05-profile-cover, 0px));
|
||||
display: flex;
|
||||
@@ -377,7 +360,7 @@
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-4, 4px);
|
||||
height: 34px;
|
||||
height: 32px;
|
||||
padding: 0 var(--spacing-8);
|
||||
border: 1px solid color-mix(in srgb, var(--color-border) 65%, transparent);
|
||||
border-radius: var(--radius-8, 6px);
|
||||
|
||||
@@ -284,15 +284,15 @@
|
||||
align-items: stretch;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 1px solid var(--color-border, #3a3f4a);
|
||||
border-radius: var(--radius-inputs, 4px);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-inputs);
|
||||
background: var(--color-surface);
|
||||
gap: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.b05-structure__stepper:focus-within {
|
||||
border-color: var(--color-royal-amethyst, rgb(109 40 217));
|
||||
border-color: var(--color-accent);
|
||||
}
|
||||
|
||||
/* 가운데 숫자칸은 자기 테두리·배경을 버리고 덩어리 안에 녹는다. */
|
||||
@@ -309,32 +309,22 @@
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* 좌우 끝 버튼 — 덩어리 안에서는 가르는 선 하나씩만 갖는다. */
|
||||
.b05-structure__step {
|
||||
flex: none;
|
||||
/* 좌우 끝 버튼 = 부품 「아이콘 단추」(553-2) — 덩어리 안에서는 가르는 선 하나씩만 갖는다. */
|
||||
.b05-structure__stepper > .b05-structure__step {
|
||||
/* 손가락·마우스로 집기 쉽게 넓힌다(2026-08-29 사용자 지시). 숫자칸이 남는 폭을
|
||||
차지하므로 이 값이 곧 버튼 폭이다. */
|
||||
width: 28px;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
color: var(--color-text-body);
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.b05-structure__step:first-child {
|
||||
border-right: 1px solid var(--color-border, #3a3f4a);
|
||||
.b05-structure__stepper > .b05-structure__step:first-child {
|
||||
border-right: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.b05-structure__step:last-child {
|
||||
border-left: 1px solid var(--color-border, #3a3f4a);
|
||||
}
|
||||
|
||||
.b05-structure__step:hover {
|
||||
background: color-mix(in srgb, var(--color-royal-amethyst, rgb(109 40 217)) 14%, transparent);
|
||||
.b05-structure__stepper > .b05-structure__step:last-child {
|
||||
border-left: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
/* 구조물 배치 폼의 숫자 칸 — 브라우저 기본 증감 화살표(스피너)를 없앤다
|
||||
@@ -389,10 +379,6 @@
|
||||
height: var(--b05-control-h);
|
||||
}
|
||||
|
||||
.b05-structure__step {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 조정창에서 옮겨 온 행(단 수·옵션) — 같은 변수로 맞춘다. */
|
||||
.b05-structure__adjust-slot .b06-structure-panel__controls {
|
||||
height: var(--b05-control-h);
|
||||
@@ -634,10 +620,10 @@
|
||||
font-size: var(--text-caption);
|
||||
}
|
||||
|
||||
/* 켬 = 확폭 포함 — 테두리색 + 표식(`.is-primary` 는 [추가] 단추 몫이라 안 씀) */
|
||||
.b05-structure__widening .b05-route__irregular-btn.is-on {
|
||||
border-color: color-mix(in srgb, var(--color-royal-amethyst, rgb(109 40 217)) 55%, transparent);
|
||||
color: var(--color-text);
|
||||
/* 켬 = 확폭 포함 — 부품 보조 단추 꼴 + 표식 · 끔 = 흐린 선 · 글(`.is-primary` 는 [추가] 단추 몫이라 안 씀) */
|
||||
.b05-structure__widening .b05-route__irregular-btn[aria-pressed="false"] {
|
||||
border-color: var(--color-border);
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.b05-structure__widening [data-widening-run][aria-pressed="true"]::before {
|
||||
|
||||
@@ -413,34 +413,15 @@
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* 상시 보이게 둔다(예전엔 패널 hover 시에만 노출). 크기는 ▲▼·↺·⬆⬇ 전부 21×17로
|
||||
키웠다(2026-08-04 사용자 지시 — 18×15는 누르기도 읽기도 작았다). */
|
||||
/* 상시 보이게 둔다(예전엔 패널 hover 시에만 노출). ▲▼·↺·⬆⬇ = 부품 「아이콘 단추」 선 꼴 단 18(553-2 · 18×18). */
|
||||
.b05-profile-edit__btn {
|
||||
position: absolute;
|
||||
width: 21px;
|
||||
height: 17px;
|
||||
padding: 0;
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
border: 1px solid color-mix(in srgb, var(--color-border) 75%, transparent);
|
||||
border-radius: 3px;
|
||||
background: color-mix(in srgb, var(--color-surface-raised) 80%, transparent);
|
||||
color: var(--color-text);
|
||||
font-size: 9px;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
opacity: 0.9;
|
||||
pointer-events: auto;
|
||||
transition:
|
||||
opacity var(--transition-fast),
|
||||
background var(--transition-fast);
|
||||
}
|
||||
|
||||
.b05-route-profile .b05-profile-edit__btn:hover,
|
||||
.b05-route-profile .b05-profile-edit__btn:focus-visible {
|
||||
border-color: var(--color-border);
|
||||
background: var(--color-surface-raised);
|
||||
color: var(--color-text);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@@ -470,8 +451,8 @@
|
||||
}
|
||||
|
||||
.b05-profile-edit__btn.is-down {
|
||||
border-color: color-mix(in srgb, var(--color-chart-0, #5b8def) 65%, transparent);
|
||||
color: var(--color-chart-0, #5b8def);
|
||||
border-color: color-mix(in srgb, var(--color-chart-0) 65%, transparent);
|
||||
color: var(--color-chart-0);
|
||||
}
|
||||
|
||||
.b05-route-profile .b05-profile-edit__btn.is-up:hover,
|
||||
@@ -483,16 +464,15 @@
|
||||
|
||||
.b05-route-profile .b05-profile-edit__btn.is-down:hover,
|
||||
.b05-route-profile .b05-profile-edit__btn.is-down:focus-visible {
|
||||
border-color: var(--color-chart-0, #5b8def);
|
||||
background: color-mix(in srgb, var(--color-chart-0, #5b8def) 14%, var(--color-surface-raised));
|
||||
color: var(--color-chart-0, #5b8def);
|
||||
border-color: var(--color-chart-0);
|
||||
background: color-mix(in srgb, var(--color-chart-0) 14%, var(--color-surface-raised));
|
||||
color: var(--color-chart-0);
|
||||
}
|
||||
|
||||
.b05-profile-edit__btn.is-reset {
|
||||
top: 22px;
|
||||
border-color: color-mix(in srgb, var(--color-royal-amethyst, rgb(109 40 217)) 55%, transparent);
|
||||
background: var(--color-surface-raised);
|
||||
color: color-mix(in srgb, var(--color-royal-amethyst, rgb(139 92 246)) 85%, var(--color-text));
|
||||
border-color: color-mix(in srgb, var(--color-accent) 55%, transparent);
|
||||
color: var(--color-accent);
|
||||
opacity: 0.95;
|
||||
}
|
||||
.b05-profile-table__segment.is-structure {
|
||||
@@ -528,30 +508,12 @@
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.b05-profile__zoom-btn {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-left: 1px solid var(--color-border);
|
||||
background: none;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 0.8rem;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
/* 묶음 안 단추 = 부품 「아이콘 단추」 단 22(553-2) — 붙은 묶음이라 둥글기 없이 가르는 선 하나씩 ·
|
||||
* 배율 한계(축소는 폭맞춤, 확대는 8배)에 닿은 단추는 부품 막힘 꼴(흐림). */
|
||||
.b05-profile__zoom > .b05-profile__zoom-btn {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.b05-profile__zoom-btn:first-child {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.b05-profile__zoom-btn:hover:not(:disabled) {
|
||||
color: var(--color-text);
|
||||
background: var(--color-surface);
|
||||
}
|
||||
|
||||
/* 배율 한계(축소는 폭맞춤, 확대는 8배)에 닿은 버튼 — 눌러도 변화가 없으니 흐리게 죽인다. */
|
||||
.b05-profile__zoom-btn:disabled {
|
||||
opacity: 0.35;
|
||||
cursor: default;
|
||||
.b05-profile__zoom-btn + .b05-profile__zoom-btn {
|
||||
border-left-color: var(--color-border);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,11 @@ function el(tag, className = "") {
|
||||
parent: null,
|
||||
listeners: {},
|
||||
style: { height: "", cssText: "" },
|
||||
attrs: {},
|
||||
setAttribute(k, v) {
|
||||
node.attrs[k] = String(v);
|
||||
},
|
||||
getAttribute: (k) => node.attrs[k] ?? null,
|
||||
};
|
||||
node.classList = {
|
||||
list: () => node.className.split(/\s+/).filter(Boolean),
|
||||
|
||||
@@ -151,7 +151,9 @@ def test_도구줄_직선화_오른쪽_자유지정():
|
||||
tools = _read("B05_Profile/B05_Profile_UI_Profile_Tools.ts")
|
||||
assert '"자유지정"' in tools
|
||||
assert "wrap.append(reset, undo, redo, straighten, free, shift, up, down)" in tools
|
||||
assert 'className = "b05-route-profile__tool"' in tools # 같은 단추 양식
|
||||
assert (
|
||||
'className = "ui-btn ui-btn--glass b05-route-profile__tool"' in tools
|
||||
) # 같은 단추 양식(부품 단추 · 553-2)
|
||||
|
||||
|
||||
def test_적용은_직선화와_같은_길_키_배선():
|
||||
|
||||
@@ -102,6 +102,9 @@ def test_배선과_양식():
|
||||
assert "attachSubPanelPopouts(profile);" in shared
|
||||
css = (ROOT / "A00_Common/design/design_page.css").read_text(encoding="utf-8")
|
||||
block = re.search(r"\n\.b05-subpanel__popout \{([^}]*)\}", css).group(1)
|
||||
assert "var(--btn-bar-padding)" in block and "var(--btn-bar-font-size)" in block
|
||||
# 크기 = 부품 단추 단 18(553-2) — 페이지 CSS 여백 덮어쓰기 없음
|
||||
assert "flex: none;" in block and "padding" not in block
|
||||
popout = (ROOT / "A00_Common/design/design_profile_popout.ts").read_text(encoding="utf-8")
|
||||
assert popout.count('button.setAttribute("data-size", "18")') == 2
|
||||
assert ".b05-profile__masshaul-overlay.is-popout," in css
|
||||
assert ".b05-drainage.is-popout {" in css
|
||||
|
||||
@@ -35,7 +35,7 @@ def test_도움말_기본_접힘_펼침_기억() -> None:
|
||||
# 접힘 = 몸통 없음 · 펼침 = 2열 · 단추만 클릭 받음
|
||||
assert "display: none;" in _rule(".b05-routeedit__hint-body")
|
||||
assert "display: grid;" in _rule(".b05-routeedit__hint.is-open > .b05-routeedit__hint-body")
|
||||
assert "pointer-events: auto;" in _rule(".b05-routeedit__hint-toggle")
|
||||
assert "pointer-events: auto;" in _rule(".b05-routeedit__hint-toggle.ui-btn[data-size]")
|
||||
assert "pointer-events: none;" in _rule(".b05-routeedit__hint")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user