From 707f17ac842b360eab4fd4abe900ec471c951a1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=A8=E9=9C=96=E9=93=83?= Date: Sat, 6 Jun 2026 10:09:48 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AD=97=E6=AE=B5=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E4=BC=98=E5=8C=96=20-=20=E8=BE=93=E5=85=A5=E9=99=90=E5=88=B6?= =?UTF-8?q?=E3=80=81=E9=80=89=E4=B8=AD=E6=A0=B7=E5=BC=8F=E3=80=81=E5=8F=96?= =?UTF-8?q?=E6=B6=88=E9=80=89=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - FieldEditor: 字段名称maxLength=20,描述maxLength=50 - FieldItem: 统一有无描述时的垂直居中布局,选中左侧竖线+背景高亮 - FieldList: 点击已选中字段可取消选中,选中态加shadow和ring效果 - index: 支持selectedIndex=-1取消选中 --- .../components/FieldEditor.tsx | 2 + .../components/FieldItem.tsx | 53 ++++++++++++------- .../components/FieldList.tsx | 18 +++++-- src/pages/TestDataGenerator/index.tsx | 4 +- 4 files changed, 51 insertions(+), 26 deletions(-) diff --git a/src/pages/TestDataGenerator/components/FieldEditor.tsx b/src/pages/TestDataGenerator/components/FieldEditor.tsx index 0935f3d..76f2baa 100644 --- a/src/pages/TestDataGenerator/components/FieldEditor.tsx +++ b/src/pages/TestDataGenerator/components/FieldEditor.tsx @@ -80,6 +80,7 @@ export default function FieldEditor({ field, onChange }: FieldEditorProps) { value={field.name} onChange={(e) => handleNameChange(e.target.value)} placeholder={t('testDataGenerator_fieldNamePlaceholder')} + maxLength={20} className="h-9" /> @@ -92,6 +93,7 @@ export default function FieldEditor({ field, onChange }: FieldEditorProps) { value={field.description || ''} onChange={(e) => handleDescriptionChange(e.target.value)} placeholder={t('testDataGenerator_fieldDescriptionPlaceholder')} + maxLength={50} className="h-9" /> diff --git a/src/pages/TestDataGenerator/components/FieldItem.tsx b/src/pages/TestDataGenerator/components/FieldItem.tsx index d39f5c3..dc6d5ef 100644 --- a/src/pages/TestDataGenerator/components/FieldItem.tsx +++ b/src/pages/TestDataGenerator/components/FieldItem.tsx @@ -1,6 +1,6 @@ /** * 字段项组件 - * 展示单个字段的基本信息 + * 展示单个字段的基本信息,适配固定高度卡片 */ import { useI18n } from '@/utils/chromeI18n'; @@ -20,30 +20,45 @@ export default function FieldItem({ field, onClick, isSelected }: FieldItemProps return (
-
- {field.name} - - {generator?.name || field.generatorId} - - {!field.required && ( - - {field.nullRate}% - - )} - {field.unique && ( - - {t('testDataGenerator_unique')} +
+ {/* 第一行:字段名 + 标签 */} +
+ + {field.name} + + + {generator?.name || field.generatorId} + {!field.required && ( + + {field.nullRate}% + + )} + {field.unique && ( + + {t('testDataGenerator_unique')} + + )} +
+ {/* 第二行:描述 */} + {field.description && ( +

+ {field.description} +

)}
- {field.description && ( -

{field.description}

- )}
); } diff --git a/src/pages/TestDataGenerator/components/FieldList.tsx b/src/pages/TestDataGenerator/components/FieldList.tsx index a64a9c3..c6ee4a2 100644 --- a/src/pages/TestDataGenerator/components/FieldList.tsx +++ b/src/pages/TestDataGenerator/components/FieldList.tsx @@ -74,12 +74,12 @@ function SortableFieldItem({
@@ -131,6 +131,14 @@ export default function FieldList({ }), ); + // 点击已选中的字段时取消选中 + const handleToggleSelect = useCallback( + (index: number) => { + onSelect(selectedIndex === index ? -1 : index); + }, + [selectedIndex, onSelect], + ); + const handleDragEnd = (event: DragEndEvent) => { const { active, over } = event; if (!over || active.id === over.id) return; @@ -232,7 +240,7 @@ export default function FieldList({ onSelect(realIndex)} + onSelect={() => handleToggleSelect(realIndex)} onRemove={() => onRemove(realIndex)} />
@@ -248,7 +256,7 @@ export default function FieldList({ key={field.id} field={field} isSelected={selectedIndex === index} - onSelect={() => onSelect(index)} + onSelect={() => handleToggleSelect(index)} onRemove={() => onRemove(index)} /> ))} diff --git a/src/pages/TestDataGenerator/index.tsx b/src/pages/TestDataGenerator/index.tsx index fc641f2..834267d 100644 --- a/src/pages/TestDataGenerator/index.tsx +++ b/src/pages/TestDataGenerator/index.tsx @@ -173,8 +173,8 @@ export default function TestDataGeneratorPage() { generate(fields, count, format === 'csv'); }, [fields, count, format, generate]); - // 获取选中的字段 - const selectedField = selectedIndex !== null ? fields[selectedIndex] : null; + // 获取选中的字段(-1 或 null 表示未选中) + const selectedField = selectedIndex !== null && selectedIndex >= 0 ? fields[selectedIndex] : null; return (