Files
invyone/frontend/components/v2/config-panels/InvLegacyTextConfigPanel.tsx
T
DDD1542 a8ded6455d refactor: ConfigPanel Inv 네이밍 통합 + legacy 패널 분리 + input cp 마이그
11 패널 일괄 Inv* prefix 통일:
- 통합 (lib/registry/components/X/): button / container / divider / search /
  stats / table / title / input → Inv*ConfigPanel
- frontend/components/v2/config-panels/V2FieldConfigPanel → InvFieldConfigPanel
- 옛 v2-* hidden 호환 → InvLegacy{Divider,Text,Button}ConfigPanel

input 통합 컴포넌트 cp 톤 신규 작성 (InvInputConfigPanel):
- 277줄 옛 디자인 → CPVisualGrid 10칸 type 카드 + 타입별 옵션 + FeatureChipGrid

getComponentConfigPanel.tsx 버그 수정 (Codex 검토):
- "stats" key 중복 제거 (옛 StatsCardConfigPanel 이 통합 stats 덮던 silent bug)
- ALIAS 에서 v2-button-primary/v2-divider-line/v2-text-display 제외
  (옵션 B 일관성 — 옛 hidden 컴포넌트는 InvLegacy 패널 사용)
- MAP 의 해당 키를 InvLegacy* 로 직접 매핑

호출처 일괄 갱신:
- 각 통합 컴포넌트의 index.ts 7개 (import / config_panel / re-export)
- v2-input/v2-select/v2-divider-line/v2-text-display/v2-button-primary
  의 index.ts (config_panel 매핑)
- V2PropertiesPanel.tsx 의 require pattern (v2-input/v2-select)

검증: tsc 우리 영역 0건 / V2FieldConfigPanel 잔재 0건 / 기존 path 잔재 0건

다음 세션: useDbTables hook 추출 + 잔여 V2* cp 마이그 + dead code 정리

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 17:57:57 +09:00

206 lines
6.9 KiB
TypeScript

"use client";
/**
* InvLegacyTextConfigPanel — 제목/텍스트 (v2-text-display) cp 톤 설정 패널
*
* 흐름:
* ① 표시 텍스트 — CPText
* ② 폰트 — 크기 (CPVisualGrid Aa preview) + 굵기 (CPVisualGrid 가나다 preview) + 직접 입력
* ③ 정렬 — CPVisualGrid (icon)
* ④ 색 — CPColor
* ▾ 고급 설정 — 배경색 / 패딩 / 모서리 / 테두리 + disabled (FeatureChipGrid)
*
* Reference: notes/gbpark/2026-04-28-cp-panel-standard.md
*/
import React from "react";
import { AlignLeft, AlignCenter, AlignRight } from "lucide-react";
import {
CPSection,
CPRow,
CPGroup,
CPText,
CPColor,
CPVisualGrid,
FeatureChipGrid,
} from "./_shared/cp";
import { TextDisplayConfig } from "@/lib/registry/components/v2-text-display/types";
interface InvLegacyTextConfigPanelProps {
config: TextDisplayConfig;
onChange: (config: Partial<TextDisplayConfig>) => void;
}
export const InvLegacyTextConfigPanel: React.FC<InvLegacyTextConfigPanelProps> = ({ config, onChange }) => {
const update = (field: keyof TextDisplayConfig, value: any) => {
const next = { ...config, [field]: value };
onChange({ [field]: value });
if (typeof window !== "undefined") {
window.dispatchEvent(
new CustomEvent("componentConfigChanged", { detail: { config: next } }),
);
}
};
const fontSize = config.fontSize || "14px";
const fontWeight = config.fontWeight || "normal";
const textAlign = config.textAlign || "left";
const color = config.color || "#212121";
return (
<div style={{ fontFamily: "var(--v5-font-sans)", color: "var(--cp-text)", padding: "0 12px" }}>
{/* ── ① 표시 텍스트 ─────────────────────────── */}
<CPSection title="① 표시 텍스트" desc="화면에 보일 텍스트">
<CPRow label="텍스트">
<CPText
value={config.text || ""}
onChange={(v) => update("text", v)}
placeholder="표시할 텍스트를 입력하세요"
/>
</CPRow>
</CPSection>
{/* ── ② 폰트 ─────────────────────────── */}
<CPSection title="② 폰트" desc="크기와 굵기 선택">
<CPRow label="크기" />
<CPVisualGrid
cols={4}
value={fontSize}
onChange={(v) => update("fontSize", v)}
cardHeight={60}
options={[
{
value: "12px",
label: "작게",
preview: <span style={{ fontSize: 12, fontWeight: 600 }}>Aa</span>,
},
{
value: "14px",
label: "보통",
preview: <span style={{ fontSize: 14, fontWeight: 600 }}>Aa</span>,
},
{
value: "18px",
label: "크게",
preview: <span style={{ fontSize: 18, fontWeight: 600 }}>Aa</span>,
},
{
value: "24px",
label: "제목",
preview: <span style={{ fontSize: 22, fontWeight: 700 }}>Aa</span>,
},
]}
/>
<div style={{ marginTop: 8 }}>
<CPRow label="직접 입력">
<CPText
value={fontSize}
onChange={(v) => update("fontSize", v)}
placeholder="14px"
/>
</CPRow>
</div>
<div style={{ marginTop: 10 }}>
<CPRow label="굵기" />
<CPVisualGrid
cols={3}
value={fontWeight}
onChange={(v) => update("fontWeight", v)}
cardHeight={50}
options={[
{
value: "lighter",
label: "얇게",
preview: <span style={{ fontSize: 13, fontWeight: 300 }}></span>,
},
{
value: "normal",
label: "보통",
preview: <span style={{ fontSize: 13, fontWeight: 400 }}></span>,
},
{
value: "bold",
label: "굵게",
preview: <span style={{ fontSize: 13, fontWeight: 700 }}></span>,
},
]}
/>
</div>
</CPSection>
{/* ── ③ 정렬 ─────────────────────────── */}
<CPSection title="③ 정렬">
<CPVisualGrid
cols={3}
value={textAlign}
onChange={(v) => update("textAlign", v)}
cardHeight={48}
options={[
{ value: "left", label: "왼쪽", preview: <AlignLeft size={16} /> },
{ value: "center", label: "가운데", preview: <AlignCenter size={16} /> },
{ value: "right", label: "오른쪽", preview: <AlignRight size={16} /> },
]}
/>
</CPSection>
{/* ── ④ 색상 ─────────────────────────── */}
<CPSection title="④ 색상">
<CPRow label="텍스트 색">
<CPColor value={color} onChange={(v) => update("color", v)} />
</CPRow>
</CPSection>
{/* ── ▾ 고급 설정 ─────────────────────────── */}
<CPGroup title="고급 설정" defaultOpen={false}>
<CPRow label="배경색">
<CPColor
value={config.backgroundColor || "#ffffff"}
onChange={(v) => update("backgroundColor", v)}
/>
</CPRow>
<CPRow label="패딩" help="예: 8px / 4px 8px">
<CPText
value={config.padding || ""}
onChange={(v) => update("padding", v)}
placeholder="8px"
/>
</CPRow>
<CPRow label="모서리 둥글기" help="예: 4px / 8px">
<CPText
value={config.borderRadius || ""}
onChange={(v) => update("borderRadius", v)}
placeholder="4px"
/>
</CPRow>
<CPRow label="테두리" help="예: 1px solid #d1d5db">
<CPText
value={config.border || ""}
onChange={(v) => update("border", v)}
placeholder="1px solid #d1d5db"
/>
</CPRow>
<div style={{ marginTop: 8 }}>
<FeatureChipGrid
items={[
{
key: "disabled",
label: "비활성화",
desc: "텍스트를 회색으로 흐리게 표시하고 클릭/이벤트를 차단합니다.\n조건부 표시와 함께 자주 쓰여요.",
},
]}
source={config as any}
onToggle={(k, v) => update(k as keyof TextDisplayConfig, v)}
/>
</div>
</CPGroup>
</div>
);
};
InvLegacyTextConfigPanel.displayName = "InvLegacyTextConfigPanel";
export default InvLegacyTextConfigPanel;