From 70f7341e643421a615adcc4376de5df730282778 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A0=EB=B3=91=EC=B2=A0?= Date: Thu, 19 Mar 2026 17:49:02 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20[rules]=20=EA=B3=B5=ED=86=B5=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=9A=B0=EC=84=A0=20?= =?UTF-8?q?=EC=A0=91=EA=B7=BC=20=EA=B7=9C=EC=B9=99=20+=20CurrencyInput=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=20=EA=B7=9C=EC=B9=99=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CLAUDE.md | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 785d508b..e128b1fe 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -542,6 +542,55 @@ url: `${API_URL}/api/v1/items?${params.toString()}` - **IntegratedListTemplateV2 사용 시 → 컬럼 설정(`useColumnSettings` + `ColumnSettingsPopover`), 모바일 카드(`renderMobileCard`), 체크박스(`Set`), 테이블 내 필터(`tableHeaderActions`) 필수 적용** - 상세/폼 → Card + 기존 패턴 따르기 +### 🔴 리스트 페이지 공통 기능은 공통 컴포넌트에서 해결 +리스트 페이지 전체에 적용해야 하는 기능은 **개별 페이지 수정 금지**. 반드시 공통 레이어에서 처리. + +| 기능 | 수정 위치 | 개별 페이지 수정 | +|------|----------|----------------| +| 검색 상태 보존 | `UniversalListPage` (내장 `useListSearchState`) | ❌ 금지 | +| 검색 X(클리어) 버튼 | `SearchFilter` + `IntegratedListTemplateV2` | ❌ 금지 | +| 검색 디바운스 | `UniversalListPage` 내부 300ms debounce | ❌ 금지 | +| 체크박스 선택 | `IntegratedListTemplateV2` | ❌ 금지 | +| 페이지네이션 | `IntegratedListTemplateV2` | ❌ 금지 | +| 모바일 카드/인피니티 | `IntegratedListTemplateV2` | ❌ 금지 | +| 컬럼 설정 | `useColumnSettings` + `ColumnSettingsPopover` | ❌ 금지 | + +**원칙: "26개 페이지에 하나씩 적용" → 잘못된 접근. "공통 1곳 수정 → 전체 자동 적용" → 올바른 접근.** + +### 🔴 목록 페이지 검색 — UniversalListPage + clientSideFiltering 필수 +목록 페이지의 검색은 **반드시 `UniversalListPage` + `clientSideFiltering: true` + `searchFilter`** 패턴을 사용한다. +`IntegratedListTemplateV2`에 직접 `onSearchChange`를 연결하면 키입력마다 화면이 깜빡이며 한글 조합이 불가능해진다. + +```typescript +// ✅ 올바른 패턴 — UniversalListPage + clientSideFiltering (품목관리, 수주관리와 동일) +const config: UniversalListConfig = { + clientSideFiltering: true, + searchFilter: (item, searchValue) => { + const q = searchValue.toLowerCase(); + return item.name.toLowerCase().includes(q) || item.code.toLowerCase().includes(q); + }, + searchPlaceholder: '이름, 코드 검색...', +}; +// 데이터를 한 번 API로 로드 → 검색은 메모리에서 즉시 필터링 → 깜빡임 없음 +``` + +```typescript +// ❌ 금지 패턴 — IntegratedListTemplateV2에 onSearchChange 직접 연결 + { setSearchTerm(q); }} // 키입력마다 state 변경 → re-render → 화면 깜빡임 +/> +``` + +### 🔴 금액 입력 컴포넌트 선택 규칙 +| 용도 | 컴포넌트 | 특징 | +|------|---------|------| +| **금액 입력** (경조사비, 비용 등) | `CurrencyInput` | 입력 중 실시간 천단위 콤마, ₩ 표시 | +| **수량 입력** (재고, BOM 등) | `NumberInput` | 소수점 허용, 포커스 해제 시 콤마(`useComma`) | +| **테이블 내 금액** (단가 등) | `NumberInput useComma` | 간결한 인라인용 | + +`NumberInput useComma`는 포커스 해제 시에만 콤마 표시. 금액 전용 입력에는 반드시 `CurrencyInput` 사용. + --- ## FormField 사용 규칙 (신규 폼 필수)