refactor: 统一中文文案并简化组件结构,提升代码可读性

移除 chrome.i18n 后,将各功能页面、布局与工具模块的 UI 文案改为内联中文;
删除冗余注释与过度抽象(如 ToolCard、StatCard),精简 props 与状态管理;
同步优化 JsonTools、StorageCleaner、Timestamp、TestDataGenerator、Dashboard、
Base64Converter、RightClickRestorer、TextStatistics、TopBar、RouterProvider、
ThemeModeProvider 及生成器库与 utils 工具文件。
This commit is contained in:
雨霖铃
2026-06-27 10:49:36 +08:00
parent f3a9838017
commit d38bafe237
85 changed files with 324 additions and 864 deletions
@@ -5,7 +5,6 @@ import Index from '../index';
describe('Timestamp 页面', () => {
it('应该渲染模式切换按钮', () => {
render(<Index />);
// 基本渲染测试:页面含多个模式切换按钮,应至少渲染一个
expect(screen.getAllByRole('button').length).toBeGreaterThan(0);
});
});
@@ -8,9 +8,15 @@ import {
SelectValue,
} from '@/components/ui/select';
import { cn } from '@/lib/utils';
import { MODE_OPTIONS, UNIT_OPTIONS, ZONES, type ZoneType } from '../constants';
import {
CARD_CLASS,
INPUT_PLACEHOLDERS,
MODE_OPTIONS,
UNIT_OPTIONS,
ZONES,
type ZoneType,
} from '../constants';
import type { UseTimestampConverterReturn } from '../useTimestampConverter';
import ToolCard from './ToolCard';
type ConverterFormProps = Omit<UseTimestampConverterReturn, 'result' | 'handleUseNow'>;
@@ -20,20 +26,19 @@ export default function ConverterForm({
unit,
zone,
error,
inputPlaceholder,
setMode,
setInput,
setUnit,
setZone,
}: ConverterFormProps) {
return (
<ToolCard className="gap-4">
<div className={cn(CARD_CLASS, 'gap-4')}>
<SwitchButtonGroup value={mode} options={MODE_OPTIONS} onChange={setMode} size="small" />
<div className="flex flex-col gap-1.5">
<Input
type="text"
placeholder={inputPlaceholder}
placeholder={INPUT_PLACEHOLDERS[mode]}
value={input}
onChange={(e) => setInput(e.target.value)}
className={cn(
@@ -71,6 +76,6 @@ export default function ConverterForm({
</SelectContent>
</Select>
</div>
</ToolCard>
</div>
);
}
+3 -3
View File
@@ -34,7 +34,7 @@ export default function LiveClock({ unit, onUseNow, className, ...props }: LiveC
{...props}
>
<span className="text-muted-foreground font-bold text-[10px] uppercase tracking-wider whitespace-nowrap shrink-0 selection:bg-transparent select-none">
{'当前时间戳'}
</span>
<span className="flex-1 font-mono font-bold text-foreground text-sm tracking-tight leading-none truncate tabular-nums">
@@ -47,7 +47,7 @@ export default function LiveClock({ unit, onUseNow, className, ...props }: LiveC
onUseNow(rawTime);
toast.success('已使用当前时间戳');
}}
title={'填充到下方'}
title="填充到下方"
variant="ghost"
size="icon"
className="h-7 w-7 text-muted-foreground hover:text-foreground"
@@ -55,7 +55,7 @@ export default function LiveClock({ unit, onUseNow, className, ...props }: LiveC
<Clock className="w-3.5 h-3.5" />
</Button>
<CopyButton text={text} tooltip={'复制时间戳'} className="h-7 w-7 rounded-md border" />
<CopyButton text={text} tooltip="复制时间戳" className="h-7 w-7 rounded-md border" />
</div>
);
}
@@ -14,15 +14,16 @@ export default function ResultView({
className,
...props
}: ResultViewProps) {
if (!result && !showEmptyPlaceholder) return null;
if (!result) {
if (!showEmptyPlaceholder) return null;
return (
<EmptyPlaceholder
className={cn('flex-1 min-h-[320px]', className)}
messageClassName="text-sm font-medium text-muted-foreground max-w-none"
{...props}
>
{'请输入并点击转换'}
</EmptyPlaceholder>
);
}
@@ -30,7 +31,7 @@ export default function ResultView({
return (
<div className={cn('flex flex-col w-full', className)} {...props}>
<span className="block text-muted-foreground/90 mb-2.5 text-xs font-semibold tracking-wider uppercase">
{'转换结果'}
</span>
<div className="bg-card text-card-foreground border border-border p-4 sm:p-5 rounded-xl relative shadow-sm flex justify-between items-center gap-4 focus-within:ring-1 focus-within:ring-ring">
@@ -39,7 +40,7 @@ export default function ResultView({
</span>
<CopyButton
text={result}
tooltip={'复制结果'}
tooltip="复制结果"
variant="ghost"
size="icon"
className="h-7 w-7 text-muted-foreground hover:text-foreground"
@@ -1,15 +0,0 @@
import React from 'react';
import { cn } from '@/lib/utils';
import { CARD_CLASS } from '../constants';
interface ToolCardProps extends React.HTMLAttributes<HTMLDivElement> {
children: React.ReactNode;
}
export default function ToolCard({ children, className, ...props }: ToolCardProps) {
return (
<div className={cn(CARD_CLASS, className)} {...props}>
{children}
</div>
);
}
+4 -3
View File
@@ -1,7 +1,8 @@
import { cn } from '@/lib/utils';
import LiveClock from './components/LiveClock';
import ConverterForm from './components/ConverterForm';
import ResultView from './components/ResultView';
import ToolCard from './components/ToolCard';
import { CARD_CLASS } from './constants';
import { useTimestampConverter } from './useTimestampConverter';
export default function Index() {
@@ -14,9 +15,9 @@ export default function Index() {
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 items-stretch">
<ConverterForm {...formProps} />
<ToolCard className="h-full">
<div className={cn(CARD_CLASS, 'h-full')}>
<ResultView result={result} showEmptyPlaceholder />
</ToolCard>
</div>
</div>
</div>
);
+1 -3
View File
@@ -1,7 +1,7 @@
import { useMemo, useState } from 'react';
import dayjs from '@/utils/dayjs';
import type { UnitType, ZoneType, ModeType } from './constants';
import { DATE_FORMAT, INPUT_PLACEHOLDERS, msToUnit, dayjsFromTimestamp } from './constants';
import { DATE_FORMAT, msToUnit, dayjsFromTimestamp } from './constants';
import { useContextMenuData } from '@/utils/useContextMenuData';
export interface UseTimestampConverterReturn {
@@ -11,7 +11,6 @@ export interface UseTimestampConverterReturn {
zone: ZoneType;
result: string;
error: string;
inputPlaceholder: string;
setMode: (mode: ModeType) => void;
setInput: (value: string) => void;
@@ -101,7 +100,6 @@ export function useTimestampConverter(): UseTimestampConverterReturn {
zone,
result,
error,
inputPlaceholder: INPUT_PLACEHOLDERS[mode],
setMode: handleSetMode,
setInput,
setUnit,