From 6516a14832ac8be0ce5232efa292ecff7524e9ab Mon Sep 17 00:00:00 2001 From: hyejj19 Date: Tue, 24 Feb 2026 10:26:09 +0900 Subject: [PATCH 1/7] =?UTF-8?q?fix:=20=ED=85=8C=EC=9D=B4=EC=8A=A4=ED=8C=85?= =?UTF-8?q?=20=ED=83=9C=EA=B7=B8=20=EB=AA=A9=EB=A1=9D=20=EC=A0=84=EC=B2=B4?= =?UTF-8?q?=20=EB=85=B8=EC=B6=9C=20=EB=B0=8F=20=EC=84=A0=ED=83=9D=20?= =?UTF-8?q?=EC=98=81=EC=97=AD=20=ED=99=95=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 위스키 등록/수정, 태그 관리 페이지의 태그 조회 size를 100에서 500으로 증가 - TagSelector의 기존 태그 노출 영역을 max-h-32에서 max-h-60으로 확장 Closes bottle-note/workspace#181 Co-Authored-By: Claude Opus 4.6 --- src/components/common/TagSelector.tsx | 2 +- src/pages/tasting-tags/TastingTagList.tsx | 2 +- src/pages/whisky/WhiskyDetail.tsx | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/common/TagSelector.tsx b/src/components/common/TagSelector.tsx index 1ea1a1d..07e4cfe 100644 --- a/src/components/common/TagSelector.tsx +++ b/src/components/common/TagSelector.tsx @@ -125,7 +125,7 @@ export function TagSelector({ selectedTags, availableTags, onTagsChange }: TagSe /> {filteredUnselectedTags.length > 0 ? ( -
+
{filteredUnselectedTags.map((tag) => ( t.korName) ?? []; // 로컬 상태 From 29342c5a18e5622a604f9ef2128f095ab817c9ef Mon Sep 17 00:00:00 2001 From: hyejj19 Date: Tue, 24 Feb 2026 14:31:06 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20=EB=B0=B0=EB=84=88=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=ED=85=8D=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=9C=84=EA=B3=84=20=EA=B0=9C=ED=8E=B8=20=EB=B0=8F?= =?UTF-8?q?=20UX=20=EA=B0=9C=EC=84=A0=20(#179)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 카드 재편: name(설명) 필드를 기본정보에서 텍스트 카드로 이동 - 라벨 변경: 설명A/B → 제목 첫번째줄/두번째줄, 색상 라벨 스왑 - 프리뷰: 폰트 크기 스왑 (제목 크게, 설명 작게) - 프리뷰: 실제 프론트엔드 배너 크기 기반 반응형 프리셋 (SE/표준/Max/전체) - 컬러 피커: 프리셋 칩 + native color picker + HEX 입력 컴포넌트 추가 Co-Authored-By: Claude Opus 4.6 --- e2e/pages/banner-detail.page.ts | 6 +- src/components/common/ColorPickerInput.tsx | 97 +++++++++++++++ .../components/BannerBasicInfoCard.tsx | 9 -- .../banners/components/BannerPreviewCard.tsx | 116 +++++++++++------- .../components/BannerTextSettingsCard.tsx | 59 +++++---- 5 files changed, 203 insertions(+), 84 deletions(-) create mode 100644 src/components/common/ColorPickerInput.tsx diff --git a/e2e/pages/banner-detail.page.ts b/e2e/pages/banner-detail.page.ts index db07585..41c1a58 100644 --- a/e2e/pages/banner-detail.page.ts +++ b/e2e/pages/banner-detail.page.ts @@ -24,16 +24,16 @@ export class BannerDetailPage extends BasePage { readonly loadingState = () => this.page.getByText('로딩 중...'); - readonly nameInput = () => this.page.getByPlaceholder('배너명을 입력하세요'); + readonly nameInput = () => this.page.getByPlaceholder('설명을 입력하세요'); readonly bannerTypeSelect = () => this.page.locator('button[role="combobox"]').filter({ hasText: /^\s*(설문조사|큐레이션|광고|제휴|기타|배너 타입 선택)\s*$/ }); readonly isActiveSwitch = () => this.page.locator('button#isActive'); - readonly descriptionAInput = () => this.page.getByPlaceholder('첫 번째 줄 설명'); + readonly descriptionAInput = () => this.page.getByPlaceholder('제목 첫번째줄을 입력하세요'); - readonly descriptionBInput = () => this.page.getByPlaceholder('두 번째 줄 설명'); + readonly descriptionBInput = () => this.page.getByPlaceholder('제목 두번째줄을 입력하세요'); readonly textPositionSelect = () => this.page.locator('button[role="combobox"]').filter({ hasText: /좌측 상단|좌측 하단|우측 상단|우측 하단|중앙|텍스트 위치 선택/ }); diff --git a/src/components/common/ColorPickerInput.tsx b/src/components/common/ColorPickerInput.tsx new file mode 100644 index 0000000..15e4a34 --- /dev/null +++ b/src/components/common/ColorPickerInput.tsx @@ -0,0 +1,97 @@ +import { useRef } from 'react'; +import { Pipette } from 'lucide-react'; + +import { cn } from '@/lib/utils'; +import { Input } from '@/components/ui/input'; +import { Button } from '@/components/ui/button'; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from '@/components/ui/popover'; + +const PRESET_COLORS = [ + 'ffffff', '000000', 'f5f5f5', '333333', 'a3a3a3', '737373', + 'ef4444', 'f97316', 'eab308', '22c55e', '3b82f6', '8b5cf6', + 'ec4899', '78716c', '0ea5e9', '14b8a6', 'f43f5e', 'd97706', +] as const; + +interface ColorPickerInputProps { + value: string; + onChange: (hex: string) => void; + error?: string; + id?: string; +} + +export function ColorPickerInput({ value, onChange, error, id }: ColorPickerInputProps) { + const nativeInputRef = useRef(null); + + const handleNativeChange = (e: React.ChangeEvent) => { + onChange(e.target.value.replace('#', '')); + }; + + const handleTextChange = (e: React.ChangeEvent) => { + const raw = e.target.value.replace(/[^0-9a-fA-F]/g, '').slice(0, 6); + onChange(raw); + }; + + return ( +
+
+ + + + + + +
+ {PRESET_COLORS.map((color) => ( +
+
+ + +
+
+
+
+ ); +} diff --git a/src/pages/banners/components/BannerBasicInfoCard.tsx b/src/pages/banners/components/BannerBasicInfoCard.tsx index c9b5965..0f3072b 100644 --- a/src/pages/banners/components/BannerBasicInfoCard.tsx +++ b/src/pages/banners/components/BannerBasicInfoCard.tsx @@ -1,6 +1,5 @@ import type { UseFormReturn } from 'react-hook-form'; -import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Switch } from '@/components/ui/switch'; import { @@ -29,14 +28,6 @@ export function BannerBasicInfoCard({ form }: BannerBasicInfoCardProps) { 기본 정보 - - - - - + + + + + @@ -60,34 +69,22 @@ export function BannerTextSettingsCard({ form }: BannerTextSettingsCardProps) {
- -
-
- -
+ + form.setValue('descriptionFontColor', hex, { shouldValidate: true })} + error={form.formState.errors.descriptionFontColor?.message} + /> - -
-
- -
+ + form.setValue('nameFontColor', hex, { shouldValidate: true })} + error={form.formState.errors.nameFontColor?.message} + />
From 79870280c1899e72804475019d9a9fe458a76745 Mon Sep 17 00:00:00 2001 From: hyejj19 Date: Tue, 24 Feb 2026 14:40:40 +0900 Subject: [PATCH 3/7] =?UTF-8?q?fix:=20=EC=9C=84=EC=8A=A4=ED=82=A4=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D/=EC=88=98=EC=A0=95=20=EC=8B=9C=20=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4=ED=8C=85=20=ED=83=9C=EA=B7=B8=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=B2=84?= =?UTF-8?q?=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AlcoholCreateRequest/UpdateRequest 타입에 tastingTagIds 필드 추가 - useWhiskyDetailForm에서 태그 ID 배열을 API 요청에 포함 - WhiskyTastingTagCard에서 전체 태그 목록 기반 ID 매핑으로 변경 (기존: 선택 목록에서만 조회하여 새 태그 ID가 0으로 전송됨) - WhiskyDetail에서 tagListItems prop 전달 Closes #182 Co-Authored-By: Claude Opus 4.6 --- src/pages/whisky/WhiskyDetail.tsx | 1 + .../components/WhiskyTastingTagCard.tsx | 27 ++++++++++++++----- src/pages/whisky/useWhiskyDetailForm.ts | 7 ++++- src/types/api/alcohol.api.ts | 4 +++ 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/pages/whisky/WhiskyDetail.tsx b/src/pages/whisky/WhiskyDetail.tsx index c02c392..ee4414d 100644 --- a/src/pages/whisky/WhiskyDetail.tsx +++ b/src/pages/whisky/WhiskyDetail.tsx @@ -171,6 +171,7 @@ export function WhiskyDetailPage() { diff --git a/src/pages/whisky/components/WhiskyTastingTagCard.tsx b/src/pages/whisky/components/WhiskyTastingTagCard.tsx index 4f7e9ec..b30b6c3 100644 --- a/src/pages/whisky/components/WhiskyTastingTagCard.tsx +++ b/src/pages/whisky/components/WhiskyTastingTagCard.tsx @@ -8,31 +8,46 @@ import { TagSelector } from '@/components/common/TagSelector'; import type { AlcoholTastingTag } from '@/types/api'; +/** 태그 목록 아이템 (ID 매핑용) */ +interface TagListItem { + id: number; + korName: string; + engName: string; +} + /** * WhiskyTastingTagCard 컴포넌트의 props * @param tastingTags - 현재 선택된 테이스팅 태그 목록 - * @param availableTags - 선택 가능한 태그 목록 + * @param availableTags - 선택 가능한 태그 이름 목록 + * @param tagListItems - 전체 태그 목록 (ID 매핑용) * @param onTagsChange - 태그 변경 콜백 */ export interface WhiskyTastingTagCardProps { tastingTags: AlcoholTastingTag[]; availableTags?: string[]; + tagListItems?: TagListItem[]; onTagsChange: (tags: AlcoholTastingTag[]) => void; disabled?: boolean; } +/** 이름으로 태그 객체를 찾아 반환. 선택 목록 → 전체 목록 → 폴백 순서 */ +function resolveTag(name: string, selected: AlcoholTastingTag[], all: TagListItem[]): AlcoholTastingTag { + const fromSelected = selected.find((t) => t.korName === name); + if (fromSelected) return fromSelected; + const fromAll = all.find((t) => t.korName === name); + if (fromAll) return { id: fromAll.id, korName: fromAll.korName, engName: fromAll.engName }; + return { id: 0, korName: name, engName: name }; +} + export function WhiskyTastingTagCard({ tastingTags, availableTags = [], + tagListItems = [], onTagsChange, disabled = false, }: WhiskyTastingTagCardProps) { const handleTagsChange = (tags: string[]) => { - const newTags = tags.map((name) => { - const existing = tastingTags.find((t) => t.korName === name); - return existing ?? { id: 0, korName: name, engName: name }; - }); - onTagsChange(newTags); + onTagsChange(tags.map((name) => resolveTag(name, tastingTags, tagListItems))); }; return ( diff --git a/src/pages/whisky/useWhiskyDetailForm.ts b/src/pages/whisky/useWhiskyDetailForm.ts index bf0bac6..2ab7ad0 100644 --- a/src/pages/whisky/useWhiskyDetailForm.ts +++ b/src/pages/whisky/useWhiskyDetailForm.ts @@ -132,7 +132,7 @@ export function useWhiskyDetailForm(id: string | undefined): UseWhiskyDetailForm const onSubmit = ( data: WhiskyFormValues, - { relatedKeywords }: { tastingTags: AlcoholTastingTag[]; relatedKeywords: string[]; imagePreviewUrl: string | null } + { tastingTags, relatedKeywords }: { tastingTags: AlcoholTastingTag[]; relatedKeywords: string[]; imagePreviewUrl: string | null } ) => { // TODO: API에 relatedKeywords 필드 추가 시 요청 데이터에 포함 console.log('Related Keywords:', relatedKeywords); @@ -145,6 +145,9 @@ export function useWhiskyDetailForm(id: string | undefined): UseWhiskyDetailForm // 증류소 미선택(0) 시 '-' 항목의 ID로 대체 const distilleryId = data.distilleryId || (distilleryData?.items.find((d) => d.korName === '-')?.id ?? data.distilleryId); + // 테이스팅 태그 ID 목록 추출 + const tastingTagIds = tastingTags.map((tag) => tag.id); + if (isNewMode) { const createData: AlcoholCreateRequest = { korName: data.korName, @@ -161,6 +164,7 @@ export function useWhiskyDetailForm(id: string | undefined): UseWhiskyDetailForm imageUrl: data.imageUrl, description, volume: data.volume, + tastingTagIds, }; createMutation.mutate(createData); } else if (alcoholId) { @@ -179,6 +183,7 @@ export function useWhiskyDetailForm(id: string | undefined): UseWhiskyDetailForm imageUrl: data.imageUrl, description, volume: data.volume, + tastingTagIds, }; updateMutation.mutate({ alcoholId, data: updateData }); } diff --git a/src/types/api/alcohol.api.ts b/src/types/api/alcohol.api.ts index 488cedb..693404a 100644 --- a/src/types/api/alcohol.api.ts +++ b/src/types/api/alcohol.api.ts @@ -235,6 +235,8 @@ export interface AlcoholApiTypes { description: string; /** 용량 (예: "700ml") */ volume: string; + /** 연결할 테이스팅 태그 ID 목록 */ + tastingTagIds: number[]; }; /** 응답 데이터 */ response: { @@ -294,6 +296,8 @@ export interface AlcoholApiTypes { description: string; /** 용량 (예: "700ml") */ volume: string; + /** 연결할 테이스팅 태그 ID 목록 */ + tastingTagIds: number[]; }; /** 응답 데이터 */ response: { From e5f41528f807982c7345f6728d5e3cdce3d6dfe9 Mon Sep 17 00:00:00 2001 From: hyejj19 Date: Tue, 24 Feb 2026 14:40:45 +0900 Subject: [PATCH 4/7] =?UTF-8?q?docs:=20CLAUDE.md=EC=97=90=20Memoization=20?= =?UTF-8?q?=EA=B0=80=EC=9D=B4=EB=93=9C=EB=9D=BC=EC=9D=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit React 공식 문서, Kent C. Dodds, Josh Comeau의 근거를 기반으로 useMemo/useCallback 사용 DO/DON'T 가이드라인 추가. Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 6e4c1ba..e93e851 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -95,6 +95,30 @@ export interface ComponentProps { ... } export function Component({ ... }: ComponentProps) { ... } ``` +### Memoization (useMemo / useCallback) +**원칙: 측정 먼저, 최적화 나중.** 추측으로 추가하지 않는다. + +**사용하는 경우:** +- 계산 비용 ≥1ms (`console.time()`으로 측정 확인) +- `memo()`로 감싼 자식에 객체/함수를 props로 전달할 때 (세트로 사용) +- 다른 Hook의 deps 배열에 객체/배열/함수가 들어갈 때 (참조 안정화) +- 커스텀 훅에서 함수를 반환할 때 (소비자 최적화 여지 보장) +- Context Provider의 value prop + +**사용하지 않는 경우:** +- `memo()` 없는 자식에게 전달되는 props (효과 없음) +- 단순 계산 (`.map()`, `.filter()`, 문자열 접합, 날짜 포맷 등) +- "혹시 모르니까" 예방적 추가 (코드 복잡성 + 메모리 비용만 증가) +- deps가 매 렌더마다 바뀌는 경우 (캐시 히트 0%) +- useEffect deps 문제를 우회하기 위해 (근본 원인을 수정할 것) + +> React Compiler 1.0 (2025.10 stable)이 수동 메모이제이션을 자동화한다. +> 지금 최소화하면 향후 마이그레이션에도 유리. +> +> 근거: [React 공식 useMemo](https://react.dev/reference/react/useMemo) | +> [Kent C. Dodds](https://kentcdodds.com/blog/usememo-and-usecallback) | +> [Josh Comeau](https://www.joshwcomeau.com/react/usememo-and-usecallback/) + ## 구현 워크플로우 (IMPORTANT) ### 자동 TDD 적용 From 21debf7dd25e7d5f0a272252b63ca66e6d164c7f Mon Sep 17 00:00:00 2001 From: hyejj19 Date: Tue, 24 Feb 2026 14:41:33 +0900 Subject: [PATCH 5/7] =?UTF-8?q?fix:=20=EB=B0=B0=EB=84=88=20=ED=94=84?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20border-radius=20=EC=A0=9C=EA=B1=B0,=20shad?= =?UTF-8?q?ow=20=EC=A0=9C=EA=B1=B0,=20gap/=EA=B6=8C=EC=9E=A5=EC=82=AC?= =?UTF-8?q?=EC=9D=B4=EC=A6=88=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 프리뷰 컨테이너 rounded-lg 제거 (프론트엔드 원본과 동일) - 텍스트 drop-shadow 제거 (프론트엔드 원본에 없음) - 제목/설명 사이 flex gap-2 적용 (프론트엔드 mt-2와 동일) - 권장 이미지 사이즈 1920x600 → 936x454px (실제 배너 비율 2x 레티나 기준) Co-Authored-By: Claude Opus 4.6 --- src/pages/banners/components/BannerImageCard.tsx | 2 +- src/pages/banners/components/BannerPreviewCard.tsx | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/pages/banners/components/BannerImageCard.tsx b/src/pages/banners/components/BannerImageCard.tsx index 81b8448..1f4eabc 100644 --- a/src/pages/banners/components/BannerImageCard.tsx +++ b/src/pages/banners/components/BannerImageCard.tsx @@ -21,7 +21,7 @@ export function BannerImageCard({ imagePreviewUrl, onImageChange, isUploading, e minHeight={200} />

- 권장 사이즈: 1920x600px + 권장 사이즈: 936x454px (2x 기준, 비율 약 2:1)

{error && (

{error}

diff --git a/src/pages/banners/components/BannerPreviewCard.tsx b/src/pages/banners/components/BannerPreviewCard.tsx index dbe56dd..802a997 100644 --- a/src/pages/banners/components/BannerPreviewCard.tsx +++ b/src/pages/banners/components/BannerPreviewCard.tsx @@ -51,7 +51,7 @@ export function BannerPreviewCard({ form, imagePreviewUrl }: BannerPreviewCardPr
- {descriptionA &&

{descriptionA}

} - {descriptionB &&

{descriptionB}

} +
+ {descriptionA &&

{descriptionA}

} + {descriptionB &&

{descriptionB}

}
) : null; const descBlock = name ? (

{name} @@ -130,7 +130,7 @@ function BannerTextOverlay({ return (

{isBottom ? ( <> From 899c57c5cfdd76df6f2769e796a0687dcbedb87f Mon Sep 17 00:00:00 2001 From: hyejj19 Date: Tue, 24 Feb 2026 14:54:57 +0900 Subject: [PATCH 6/7] =?UTF-8?q?fix:=20PR=20=EB=A6=AC=EB=B7=B0=20=EB=B0=98?= =?UTF-8?q?=EC=98=81=20=E2=80=94=20=EC=A0=91=EA=B7=BC=EC=84=B1,=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20UX,=20=ED=94=84=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=EA=B8=B0=EB=B3=B8=EA=B0=92=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ColorPickerInput: 색상 칩에 aria-label, 피커 버튼에 aria-label 추가 - banner.schema: 에러 메시지 "배너명은 필수입니다" → "설명은 필수입니다" - BannerTextSettingsCard: 색상 onChange에서 shouldValidate 제거 (타이핑 중 에러 방지) - BannerPreviewCard: 기본 너비 468 → 375 (표준, 좁은 뷰포트 대응) - BannerImageCard: 권장 사이즈 프론트엔드 실제 비율에 맞춤 Co-Authored-By: Claude Opus 4.6 --- src/components/common/ColorPickerInput.tsx | 3 ++- src/pages/banners/banner.schema.ts | 2 +- src/pages/banners/components/BannerPreviewCard.tsx | 2 +- src/pages/banners/components/BannerTextSettingsCard.tsx | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/components/common/ColorPickerInput.tsx b/src/components/common/ColorPickerInput.tsx index 15e4a34..b7d75c7 100644 --- a/src/components/common/ColorPickerInput.tsx +++ b/src/components/common/ColorPickerInput.tsx @@ -51,7 +51,7 @@ export function ColorPickerInput({ value, onChange, error, id }: ColorPickerInpu /> - @@ -67,6 +67,7 @@ export function ColorPickerInput({ value, onChange, error, id }: ColorPickerInpu )} style={{ backgroundColor: `#${color}` }} onClick={() => onChange(color)} + aria-label={`색상 #${color}`} title={`#${color}`} /> ))} diff --git a/src/pages/banners/banner.schema.ts b/src/pages/banners/banner.schema.ts index 9ba917f..96f98b6 100644 --- a/src/pages/banners/banner.schema.ts +++ b/src/pages/banners/banner.schema.ts @@ -42,7 +42,7 @@ function formatDateTime(date: Date, startOfDay: boolean): string { /** 배너 폼 Zod 스키마 */ export const bannerFormSchema = z.object({ - name: z.string().min(1, '배너명은 필수입니다'), + name: z.string().min(1, '설명은 필수입니다'), bannerType: z.enum(['SURVEY', 'CURATION', 'AD', 'PARTNERSHIP', 'ETC'], { message: '배너 타입을 선택해주세요', }), diff --git a/src/pages/banners/components/BannerPreviewCard.tsx b/src/pages/banners/components/BannerPreviewCard.tsx index 802a997..7beae0b 100644 --- a/src/pages/banners/components/BannerPreviewCard.tsx +++ b/src/pages/banners/components/BannerPreviewCard.tsx @@ -22,7 +22,7 @@ interface BannerPreviewCardProps { } export function BannerPreviewCard({ form, imagePreviewUrl }: BannerPreviewCardProps) { - const [selectedWidth, setSelectedWidth] = useState(468); + const [selectedWidth, setSelectedWidth] = useState(PREVIEW_WIDTHS[1].width); if (!imagePreviewUrl) return null; diff --git a/src/pages/banners/components/BannerTextSettingsCard.tsx b/src/pages/banners/components/BannerTextSettingsCard.tsx index 1aa2331..2c40d9a 100644 --- a/src/pages/banners/components/BannerTextSettingsCard.tsx +++ b/src/pages/banners/components/BannerTextSettingsCard.tsx @@ -73,7 +73,7 @@ export function BannerTextSettingsCard({ form }: BannerTextSettingsCardProps) { form.setValue('descriptionFontColor', hex, { shouldValidate: true })} + onChange={(hex) => form.setValue('descriptionFontColor', hex)} error={form.formState.errors.descriptionFontColor?.message} /> @@ -82,7 +82,7 @@ export function BannerTextSettingsCard({ form }: BannerTextSettingsCardProps) { form.setValue('nameFontColor', hex, { shouldValidate: true })} + onChange={(hex) => form.setValue('nameFontColor', hex)} error={form.formState.errors.nameFontColor?.message} /> From aace917be858ceaae20b741eb456d0d371df0cda Mon Sep 17 00:00:00 2001 From: hyejj19 Date: Tue, 24 Feb 2026 14:59:08 +0900 Subject: [PATCH 7/7] =?UTF-8?q?chore:=20=EB=B2=84=EC=A0=84=201.1.4?= =?UTF-8?q?=EB=A1=9C=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 781dcb0..65087b4 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.3 +1.1.4