a0345b384d
- 调整文本预览区域高度,单行显示截断文本 - 缩小二维码图片尺寸(56x56 -> 48x48) - 减少内边距和间距,更紧凑的布局 - 确保完整显示在popup窗口中无需滚动
115 lines
3.9 KiB
TypeScript
115 lines
3.9 KiB
TypeScript
import { Loader2, Pencil, QrCode } from 'lucide-react';
|
|
import TextInputArea from '@/components/TextInputArea';
|
|
import QrCodePreview from '@/components/QrCodePreview';
|
|
import { useI18n } from '@/utils/chromeI18n';
|
|
import { useQrCodeContext } from '../contexts/QrCodeContext';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Label } from '@/components/ui/label';
|
|
import { cn } from '@/lib/utils';
|
|
|
|
/** 文本预览的最大显示字符数 */
|
|
const TEXT_PREVIEW_MAX_LENGTH = 80;
|
|
|
|
export default function GeneratePanel() {
|
|
const { t } = useI18n('qrCode');
|
|
const {
|
|
generatorState,
|
|
setTextToEncode,
|
|
confirmGenerate,
|
|
backToEdit,
|
|
downloadQrCode,
|
|
copyQrCode,
|
|
} = useQrCodeContext();
|
|
|
|
const isInputStep = generatorState.step === 'input';
|
|
const hasText = generatorState.textToEncode.trim().length > 0;
|
|
|
|
/** 截断文本用于预览显示 */
|
|
const getTruncatedText = (text: string) => {
|
|
if (text.length <= TEXT_PREVIEW_MAX_LENGTH) return text;
|
|
return text.slice(0, TEXT_PREVIEW_MAX_LENGTH) + '...';
|
|
};
|
|
|
|
// 输入态:只显示输入框和生成按钮
|
|
if (isInputStep) {
|
|
return (
|
|
<div className="w-full select-none p-0.5">
|
|
<div
|
|
className={cn(
|
|
'border border-border rounded-xl bg-card text-card-foreground shadow-sm flex flex-col p-4',
|
|
'focus-within:ring-1 focus-within:ring-ring focus-within:border-ring',
|
|
)}
|
|
>
|
|
<div className="flex flex-col space-y-2.5">
|
|
<Label className="text-[10px] font-bold text-muted-foreground/90 uppercase tracking-wider select-none pl-0.5">
|
|
{t('qrCode:urlInputLabel')}
|
|
</Label>
|
|
|
|
<TextInputArea
|
|
value={generatorState.textToEncode}
|
|
onChange={setTextToEncode}
|
|
placeholder={t('qrCode:urlInputPlaceholder')}
|
|
showCount={true}
|
|
showClear={true}
|
|
allowCopy={false}
|
|
minRows={6}
|
|
maxRows={12}
|
|
externalError={generatorState.inputError || undefined}
|
|
onClear={() => setTextToEncode('')}
|
|
/>
|
|
|
|
<Button
|
|
onClick={confirmGenerate}
|
|
disabled={!hasText || generatorState.generating}
|
|
className="w-full"
|
|
>
|
|
{generatorState.generating ? (
|
|
<>
|
|
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
|
|
{t('qrCode:generating')}
|
|
</>
|
|
) : (
|
|
<>
|
|
<QrCode className="w-4 h-4 mr-2" />
|
|
{t('qrCode:generateButton')}
|
|
</>
|
|
)}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// 预览态:显示文本预览 + 二维码(紧凑布局,适配popup窗口)
|
|
return (
|
|
<div className="w-full select-none p-0.5 flex flex-col">
|
|
{/* 文本预览区域(固定高度,单行显示) */}
|
|
<div className="border border-border rounded-xl bg-card text-card-foreground shadow-sm p-3 mb-3">
|
|
<div className="flex items-center justify-between mb-1.5">
|
|
<Label className="text-[10px] font-bold text-muted-foreground/90 uppercase tracking-wider select-none pl-0.5">
|
|
{t('qrCode:textPreviewLabel')}
|
|
</Label>
|
|
<Button variant="ghost" size="sm" onClick={backToEdit} className="h-6 px-2 text-xs">
|
|
<Pencil className="w-3 h-3 mr-1" />
|
|
{t('qrCode:editButton')}
|
|
</Button>
|
|
</div>
|
|
<div
|
|
className="text-sm text-foreground bg-muted/50 rounded-md px-3 py-2 cursor-default line-clamp-1"
|
|
title={generatorState.savedText}
|
|
>
|
|
{getTruncatedText(generatorState.savedText)}
|
|
</div>
|
|
</div>
|
|
|
|
{/* 二维码预览区域(自适应剩余空间) */}
|
|
<QrCodePreview
|
|
qrCodeDataUrl={generatorState.qrCodeDataUrl}
|
|
onDownload={downloadQrCode}
|
|
onCopy={copyQrCode}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|