10 KiB
10 KiB
[체크리스트] 버튼 아이콘화 - 화면 디자이너 버튼 표시 모드 확장
공정 상태
- 전체 진행률: 100% (전 단계 구현 및 검증 완료)
- 현재 단계: 완료
구현 체크리스트
1단계: 아이콘 매핑 파일 생성
frontend/lib/button-icon-map.tsx생성- 버튼 액션별 추천 아이콘 매핑 (
actionIconMap) 정의 (14개 액션 x 6개 아이콘) - 아이콘 크기 비율 매핑 (
iconSizePresets) 정의 (작게/보통/크게/매우 크게, 버튼 높이 대비 %) +getIconSizeStyle()유틸 - lucide 아이콘 동적 렌더링 포함
getButtonDisplayContent()구현 - SVG 아이콘 렌더링 (DOMPurify 정화 via
isomorphic-dompurify) - 아이콘 이름 → 컴포넌트 매핑 객체 (
iconMap) +addToIconMap()동적 추가 - deprecated 액션용 안내 문구 상수 (
NO_ICON_MESSAGE) 정의 isomorphic-dompurify기존 설치 확인 (추가 설치 불필요)ButtonIconRenderer공용 컴포넌트 추가 (모든 렌더러에서 재사용)getDefaultIconForAction()디폴트 아이콘 유틸 함수 추가 (액션별 첫 번째 추천 / 범용 폴백)FALLBACK_ICON_NAME상수 +SquareMousePointerimport/매핑 추가
2단계: ButtonConfigPanel 수정
- 표시 모드 버튼 그룹 UI 추가 (텍스트 / 아이콘 / 아이콘+텍스트)
displayMode상태 관리 및onUpdateProperty연동- 아이콘 모드 선택 시 조건부 UI 분기 (텍스트 입력 숨김 → 아이콘 선택 표시)
- 아이콘+텍스트 모드 선택 시 아이콘 선택 + 텍스트 입력 동시 표시
- 버튼 액션별 추천 아이콘 그리드 렌더링 (4열 그리드)
- 선택된 아이콘 하이라이트 (
ring-2 ring-primary/30 border-primary) - 아이콘 크기 비율 프리셋 버튼 그룹 (작게/보통/크게/매우 크게, 한글 라벨)
- px 직접 입력 필드 제거 (비율 프리셋만 제공)
icon.name,icon.size를onUpdateProperty로 저장- 아이콘 색상 컬러 피커 구현 (
ColorPickerWithTransparent재사용) - "텍스트 색상과 동일" 초기화 버튼 구현
- 텍스트 위치 4방향 설정 추가 (
iconTextPosition, 왼쪽/오른쪽/위쪽/아래쪽) - 아이콘-텍스트 간격 설정 추가 (
iconGap, 슬라이더 + 직접 입력, 아이콘+텍스트 모드 전용) - 아이콘 모드 레이아웃 안내 문구 표시 (Info 아이콘 + bg-blue-50 박스)
- 액션 변경 시 선택 아이콘 자동 초기화 로직 (추천 목록에 없으면 해제)
- deprecated 액션에서 안내 문구 + 커스텀 아이콘 추가 버튼 표시
- 아이콘/아이콘+텍스트 모드 전환 시 아이콘 미선택이면 디폴트 아이콘 자동 부여
- 커스텀 아이콘 삭제 시 디폴트 아이콘으로 자동 복귀 (텍스트 모드 전환 방지)
3단계: 커스텀 아이콘 추가/삭제 (lucide 검색)
- "lucide 검색" 버튼 UI
- lucide 아이콘 검색 팝오버 (Popover + Command + CommandInput)
import { icons } from "lucide-react"기반 전체 아이콘 검색/필터링- 선택 시
componentConfig.customIcons배열 추가 +addToIconMap동적 등록 - lucide 커스텀 아이콘 그리드 렌더링 (추천 아이콘 아래, 구분선 포함)
- lucide 커스텀 아이콘 X 버튼으로 개별 삭제
3-1단계: 커스텀 아이콘 추가/삭제 (SVG 붙여넣기)
- "SVG 붙여넣기" 버튼 UI (Popover)
- SVG 입력 textarea + DOMPurify 실시간 미리보기
- SVG 유효성 검사 (
<svg태그 포함 여부) - 아이콘 이름 입력 필드 (관리자가 구분용 이름 지정)
- DOMPurify로 SVG 정화(sanitize) 후 저장
componentConfig.customSvgIcons배열에{ name, svg }추가- SVG 커스텀 아이콘 그리드 렌더링 (lucide 커스텀 아이콘과 함께 표시)
- SVG 커스텀 아이콘 X 버튼으로 개별 삭제
- 커스텀 아이콘(lucide + SVG 모두)이 모든 버튼 액션에서 공통 노출
4단계: 버튼 렌더링 수정 (뷰어/위젯)
InteractiveScreenViewerDynamic.tsx-ButtonIconRenderer적용InteractiveScreenViewer.tsx-ButtonIconRenderer적용ButtonWidget.tsx-ButtonIconRenderer적용 (디자인/실행 모드 모두)OptimizedButtonComponent.tsx-ButtonIconRenderer적용 (실행 중 "처리 중..." 유지)ButtonPrimaryComponent.tsx-ButtonIconRenderer적용 (v2-button-primary 캔버스 렌더링)- lucide 아이콘 렌더링 (
icon.type === "lucide",getLucideIcon조회) - SVG 아이콘 렌더링 (
icon.type === "svg", DOMPurify 정화 후 innerHTML) - 아이콘+텍스트 모드:
inline-flex items-center+ 동적gap(iconGap px) icon.color설정 시 아이콘만 별도 색상 적용 (inline style)icon.color미설정 시 textColor 상속 (currentColor 기본)- 아이콘 크기 비율 프리셋
getIconSizeStyle()처리 (버튼 높이 대비 %) - 텍스트 위치 4방향 렌더링 (
flexDirection+ 요소 순서 조합)
4-2단계: 버튼 테두리 이중 적용 수정
RealtimePreviewDynamic.tsx— position wrapper에서 버튼 컴포넌트 border strip 추가ButtonPrimaryComponent.tsx— 외부 wrapper에서 border 속성 destructure 제거ButtonPrimaryComponent.tsx—border: "none"shorthand 제거, 개별 longhand 속성으로 변경isButtonComponent조건에"v2-button-primary"추가
4-1단계: 키보드 단축키 충돌 수정
ScreenDesigner.tsx글로벌 keydown 핸들러에 입력 필드 감지 가드 추가browserShortcuts배열에서Ctrl+V제거- 입력 필드(input/textarea/select/contentEditable) 포커스 시 Ctrl+A/C/V/Z 기본 동작 허용
- SVG 붙여넣기 textarea에
onPaste/onKeyDownstopPropagation 핸들러 추가
5단계: 검증
- 텍스트 모드: 기존 동작 변화 없음 확인 (하위 호환성)
displayMode없는 기존 버튼: 텍스트 모드로 정상 동작- 아이콘 모드 선택 → 추천 아이콘 6개 그리드 표시
- 아이콘 선택 → 캔버스(오른쪽 프리뷰) 및 실제 화면에서 아이콘 렌더링 확인
- 아이콘 크기 비율 프리셋 변경 → 버튼 높이 대비 비율 반영 확인
- 텍스트 위치 4방향(왼/오른/위/아래) 변경 → 레이아웃 방향 반영 확인
- 버튼 테두리 설정 → 내부 버튼에만 적용, 외부 wrapper에 이중 적용 없음 확인
- 버튼 액션 변경 → 추천 아이콘 목록 갱신 확인
- lucide 커스텀 아이콘 추가 → 모든 액션에서 노출 확인
- SVG 커스텀 아이콘 붙여넣기 → 미리보기 → 추가 → 모든 액션에서 노출 확인
- SVG에 악성 코드 삽입 시도 → DOMPurify 정화 후 안전 렌더링 확인
- 커스텀 아이콘 삭제 → 목록에서 제거 확인
- deprecated 액션에서 안내 문구 + 커스텀 아이콘 추가 가능 확인
- 아이콘+텍스트 모드: 아이콘 + 텍스트 나란히 렌더링 확인
- 아이콘+텍스트 간격 조절: 슬라이더/직접 입력으로 간격 변경 → 실시간 반영 확인
- 아이콘 색상 미설정 → textColor와 동일한 색상 확인
- 아이콘 색상 설정 → 아이콘만 해당 색상, 텍스트는 textColor 유지 확인
- 외부 SVG (고유 색상) → icon.color 설정해도 SVG 원본 색상 유지 확인
- "텍스트 색상과 동일" 버튼 → icon.color 해제되고 textColor 상속 복원 확인
- 레이아웃 안내 문구: 아이콘 모드에서만 표시, 다른 모드에서 숨김 확인
- 입력 필드에서 Ctrl+A/C/V/Z 단축키 정상 동작 확인
- 아이콘 모드 전환 시 디폴트 아이콘 자동 선택 → 캔버스에 즉시 반영 확인
- 커스텀 아이콘 삭제 시 디폴트 아이콘으로 복귀 → 아이콘 모드 유지 확인
- deprecated 액션에서 디폴트 폴백 아이콘(SquareMousePointer) 표시 확인
6단계: 정리
- TypeScript 컴파일 에러 없음 확인 (우리 파일 6개 모두 0 에러)
- 불필요한 import 없음 확인
- 이 체크리스트 완료 표시 업데이트
변경 이력
| 날짜 | 내용 |
|---|---|
| 2026-03-04 | 계획서, 맥락노트, 체크리스트 작성 완료 |
| 2026-03-04 | 외부 SVG 붙여넣기 기능 추가 (3개 문서 모두 반영) |
| 2026-03-04 | 아이콘+텍스트 모드, 레이아웃 안내 추가 |
| 2026-03-04 | 설정 패널 내 미리보기 제거 (오른쪽 캔버스 프리뷰로 대체) |
| 2026-03-04 | 아이콘 색상 설정 추가 (icon.color, 기본값 textColor 상속) |
| 2026-03-04 | 3개 문서 교차 검토 — 개요 누락 보완, 시각 예시 문구 통일, 렌더 함수 px 대응, 용어 명확화 |
| 2026-03-04 | 구현 완료 — 1~4단계 코드 작성, 6단계 린트/타입 검증 통과 |
| 2026-03-04 | 아이콘-텍스트 간격 설정 추가 (iconGap, 슬라이더+직접 입력) |
| 2026-03-04 | noIconAction에서 커스텀 아이콘 추가 허용 + 안내 문구 변경 |
| 2026-03-04 | ScreenDesigner 키보드 단축키 수정 — 입력 필드에서 텍스트 편집 단축키 허용 |
| 2026-03-04 | SVG 붙여넣기 textarea에 onPaste/onKeyDown 핸들러 추가 |
| 2026-03-04 | SVG 커스텀 아이콘 이름 중복 방지 (자동 넘버링) |
| 2026-03-04 | 디폴트 아이콘 자동 부여 — 모드 전환 시 자동 선택, 커스텀 삭제 시 디폴트 복귀 |
| 2026-03-04 | getDefaultIconForAction() 유틸 + SquareMousePointer 폴백 아이콘 추가 |
| 2026-03-04 | 3개 문서 변경사항 동기화 및 코드 정리 |
| 2026-03-04 | 아이콘 크기: 절대 px → 버튼 높이 대비 비율(%) 4단계 프리셋으로 변경, px 직접 입력 제거 |
| 2026-03-04 | 텍스트 위치 4방향 설정 추가 (왼쪽/오른쪽/위쪽/아래쪽) |
| 2026-03-04 | 버튼 테두리 이중 적용 수정 — position wrapper에서 border strip, border shorthand 제거 |
| 2026-03-04 | 프리셋 라벨 한글화 (작게/보통/크게/매우 크게), 라벨 "아이콘 크기 비율"로 변경 |