디자인 수정
Build & Deploy to K8s / build-and-deploy (push) Successful in 3m59s

This commit is contained in:
2026-04-21 22:59:51 +09:00
parent bc66d8c549
commit 5153386fce
24 changed files with 2992 additions and 887 deletions
+4 -34
View File
@@ -19,7 +19,6 @@ import type {
ResponsivePolicy,
TemplateViewsV2,
ViewV2,
BlockRole,
} from '@/types/invyone-component';
// ─────────────────────────────────────────────────────────────────────────────
@@ -342,27 +341,18 @@ export function isV2Views(views: unknown): views is TemplateViewsV2 {
/**
* 런타임 정규화.
* 이미 v2 포맷으로 저장된 stale 데이터가 최신 규칙을 반영하지 못해 화면이
* 틀어지는 문제 방지. 단계로 동작:
* 틀어지는 문제 방지. 현재는 한 단계로 동작:
*
* [Stage 1] componentId / responsivePolicy 보정
* - LEGACY_TO_UNIFIED 로 componentId 를 통합 ID 로 교체
* - unified ID 기준으로 inferPolicy 재적용
*
* [Stage 2] button/input role 좌표 기반 재분류 (view 단위)
* - main 블록의 yPct 범위를 모은 뒤
* - button/input 의 centerY 가 어떤 main 범위 안이면 companion
* (= 같은 가로 라인에 배치), 밖이면 action (= 별도 액션 라인)
* - 디자이너가 명시 main/overlay 로 둔 경우는 그대로 보존
*
* 분류가 바뀌면 bandId 는 리셋 → 런타임 buildBands fallback 에 위임.
* - role / bandId 는 사용자가 저장한 값을 그대로 보존
*/
const COORD_DEPENDENT_ROLES = new Set(['button', 'input']);
function normalizeRoles(v: TemplateViewsV2): TemplateViewsV2 {
const patchView = (view: ViewV2 | undefined): ViewV2 | undefined => {
if (!view) return view;
// Stage 1: componentId / policy 보정. role 은 일단 보존.
// Stage 1: componentId / policy 보정. role / bandId 는 그대로 보존.
const stage1: BlockV2[] = view.blocks.map((b) => {
const unified = LEGACY_TO_UNIFIED[b.componentId] ?? b.componentId;
const idChanged = unified !== b.componentId;
@@ -378,27 +368,7 @@ function normalizeRoles(v: TemplateViewsV2): TemplateViewsV2 {
responsivePolicy: nextPolicy,
};
});
// Stage 2: 좌표 기반 role 재분류 (button/input 만).
// main 블록 y 범위 수집 — 디자이너가 명시한 role='main' 을 신뢰.
const mainRanges = stage1
.filter((b) => b.role === 'main')
.map((b) => ({ top: b.yPct, bottom: b.yPct + b.hPct }));
const stage2: BlockV2[] = stage1.map((b) => {
if (!COORD_DEPENDENT_ROLES.has(b.componentId)) return b;
if (b.role === 'main' || b.role === 'overlay') return b;
const centerY = b.yPct + b.hPct / 2;
const inMain = mainRanges.some(
(r) => centerY >= r.top && centerY <= r.bottom,
);
const nextRole: BlockRole = inMain ? 'companion' : 'action';
if (b.role === nextRole) return b;
const { bandId: _drop, ...rest } = b;
return { ...rest, role: nextRole };
});
return { ...view, blocks: stage2 };
return { ...view, blocks: stage1 };
};
return {
...v,