refactor: 使用 Label 组件替换原生 label 元素,并在 DecodeResultPaper 中引入 Input 组件

This commit is contained in:
雨霖铃
2026-06-10 08:15:09 +08:00
parent 355a94d116
commit 1f9288f780
5 changed files with 32 additions and 29 deletions
+2 -6
View File
@@ -9,6 +9,7 @@
*/
import { Download } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { formatBytes } from '@/utils/format';
import { useI18n } from '@/utils/chromeI18n';
@@ -63,12 +64,7 @@ export default function DecodeResultPaper({
<label className="block text-xs font-medium text-muted-foreground mb-1">
{t('decodedFileName')}
</label>
<input
type="text"
value={fileName}
onChange={(e) => onFileNameChange(e.target.value)}
className="w-full px-3 py-2 text-sm border border-border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"
/>
<Input value={fileName} onChange={(e) => onFileNameChange(e.target.value)} />
</div>
{/* 下载按钮 */}
+9 -5
View File
@@ -1,6 +1,8 @@
import { useCallback, useEffect, useRef } from 'react';
import { Image, X } from 'lucide-react';
import { toast } from 'sonner';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
import { useI18n } from '@/utils/chromeI18n';
interface ImageUploaderProps {
@@ -125,7 +127,7 @@ const ImageUploader = ({
className="hidden"
id="qr-code-upload"
/>
<label htmlFor="qr-code-upload" className="cursor-pointer text-center w-full">
<Label htmlFor="qr-code-upload" className="cursor-pointer text-center w-full">
{selectedFile ? (
<div className="text-center w-full relative">
<div className="relative inline-block">
@@ -134,17 +136,19 @@ const ImageUploader = ({
alt="QR Code Preview"
className="max-w-full max-h-40 rounded-lg object-contain"
/>
<button
<Button
type="button"
variant="destructive"
size="icon"
data-testid="ClearIcon"
onClick={(e) => {
e.stopPropagation();
handleClearFile();
}}
className="absolute -top-2 -right-2 w-6 h-6 bg-red-500 text-white rounded-full flex items-center justify-center hover:bg-red-600 transition-colors"
className="absolute -top-2 -right-2 h-6 w-6 rounded-full"
>
<X className="w-3 h-3" />
</button>
</Button>
</div>
<span className="block text-sm text-muted-foreground mt-2">{selectedFile.name}</span>
<span className="block text-xs text-muted-foreground">{t('qrCode:clickToChange')}</span>
@@ -163,7 +167,7 @@ const ImageUploader = ({
</span>
</>
)}
</label>
</Label>
</div>
);
};
@@ -6,6 +6,7 @@
import { useState, useCallback } from 'react';
import { useI18n } from '@/utils/chromeI18n';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Switch } from '@/components/ui/switch';
import { Badge } from '@/components/ui/badge';
import { getGeneratorById } from '@/lib/generators';
@@ -110,9 +111,9 @@ export default function FieldEditor({ field, onChange, allFieldNames = [] }: Fie
<div className="space-y-4">
<div className="space-y-2">
<div className="flex items-center justify-between">
<label className="text-sm font-medium text-foreground">
<Label className="text-sm font-medium text-foreground">
{t('testDataGenerator_fieldName')}
</label>
</Label>
<span className="text-xs text-muted-foreground">{field.name.length}/20</span>
</div>
<Input
@@ -127,9 +128,9 @@ export default function FieldEditor({ field, onChange, allFieldNames = [] }: Fie
<div className="space-y-2">
<div className="flex items-center justify-between">
<label className="text-sm font-medium text-foreground">
<Label className="text-sm font-medium text-foreground">
{t('testDataGenerator_fieldDescription')}
</label>
</Label>
<span className="text-xs text-muted-foreground">
{(field.description || '').length}/50
</span>
@@ -147,9 +148,9 @@ export default function FieldEditor({ field, onChange, allFieldNames = [] }: Fie
{/* 必填/选填配置 */}
<div className="space-y-3">
<div className="flex items-center justify-between">
<label className="text-sm font-medium text-foreground">
<Label className="text-sm font-medium text-foreground">
{t('testDataGenerator_required')}
</label>
</Label>
<Switch checked={field.required} onCheckedChange={handleRequiredChange} />
</div>
@@ -198,26 +199,26 @@ export default function FieldEditor({ field, onChange, allFieldNames = [] }: Fie
{/* 唯一性约束 */}
<div className="flex items-center justify-between">
<label className="text-sm font-medium text-foreground">
<Label className="text-sm font-medium text-foreground">
{t('testDataGenerator_uniqueConstraint')}
</label>
</Label>
<Switch checked={field.unique} onCheckedChange={handleUniqueChange} />
</div>
{/* 生成器选择 */}
<div className="space-y-2">
<label className="text-sm font-medium text-foreground">
<Label className="text-sm font-medium text-foreground">
{t('testDataGenerator_generator')}
</label>
</Label>
<GeneratorSelector selectedId={field.generatorId} onChange={handleGeneratorChange} />
</div>
{/* 生成器参数配置 */}
{generator && (
<div className="space-y-2">
<label className="text-sm font-medium text-foreground">
<Label className="text-sm font-medium text-foreground">
{t('testDataGenerator_generatorParams')}
</label>
</Label>
<GeneratorConfig
generator={generator}
params={field.params}
@@ -5,6 +5,7 @@
import { useI18n } from '@/utils/chromeI18n';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
interface GenerateOptionsProps {
count: number;
@@ -32,9 +33,9 @@ export default function GenerateOptions({
<div className="space-y-4">
{/* 生成数量 */}
<div className="space-y-2">
<label className="text-sm font-medium text-foreground">
<Label className="text-sm font-medium text-foreground">
{t('testDataGenerator_count')}
</label>
</Label>
<div className="flex flex-wrap gap-2">
{COUNT_PRESETS.map((preset) => (
<button
@@ -67,9 +68,9 @@ export default function GenerateOptions({
{/* 数据格式 */}
<div className="space-y-2">
<label className="text-sm font-medium text-foreground">
<Label className="text-sm font-medium text-foreground">
{t('testDataGenerator_format')}
</label>
</Label>
<div className="flex gap-2">
{FORMAT_OPTIONS.map((option) => (
<button
@@ -4,6 +4,7 @@
*/
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Switch } from '@/components/ui/switch';
import {
Select,
@@ -39,10 +40,10 @@ export default function GeneratorConfig({ generator, params, onChange }: Generat
<div className="space-y-4 p-3 rounded-lg bg-muted/30">
{generator.params.map((param) => (
<div key={param.key} className="space-y-2">
<label className="text-sm font-medium text-foreground">
<Label className="text-sm font-medium text-foreground">
{param.label}
{param.required && <span className="text-destructive ml-1">*</span>}
</label>
</Label>
{param.description && (
<p className="text-xs text-muted-foreground">{param.description}</p>
)}