fix: 修复暗黑模式样式兼容性
- 在 tailwind.config.js 中启用 darkMode: 'class' 并扩展语义化颜色变量 - 将全项目硬编码颜色(bg-white、text-gray-*、border-gray-* 等)替换为语义化类名 - 修复 popup/index.html 硬编码浅色背景色 - 同步更新相关单元测试中的类名断言
This commit is contained in:
@@ -8,8 +8,8 @@ interface AutoRefreshToggleProps {
|
||||
export default function AutoRefreshToggle({ autoRefresh, onChange }: AutoRefreshToggleProps) {
|
||||
const { t } = useLazyTranslation('storageCleaner');
|
||||
return (
|
||||
<div className="mb-3 p-4 rounded-lg bg-white border border-gray-200 flex justify-between items-center shadow-sm transition-all hover:shadow-md">
|
||||
<span className="text-sm font-bold text-gray-700 px-3">
|
||||
<div className="mb-3 p-4 rounded-lg bg-background border border-border flex justify-between items-center shadow-sm transition-all hover:shadow-md">
|
||||
<span className="text-sm font-bold text-foreground px-3">
|
||||
{t('storageCleaner:autoRefresh')}
|
||||
</span>
|
||||
<label className="relative inline-flex items-center cursor-pointer">
|
||||
@@ -19,7 +19,7 @@ export default function AutoRefreshToggle({ autoRefresh, onChange }: AutoRefresh
|
||||
onChange={(e) => onChange(e.target.checked)}
|
||||
className="sr-only peer"
|
||||
/>
|
||||
<div className="w-9 h-5 bg-gray-200 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-amber-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all peer-checked:bg-amber-500" />
|
||||
<div className="w-9 h-5 bg-gray-200 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-amber-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-background after:border-input after:border after:rounded-full after:h-4 after:w-4 after:transition-all peer-checked:bg-amber-500" />
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -27,7 +27,7 @@ export default function CleaningResult({ result }: CleaningResultProps) {
|
||||
)}
|
||||
<span
|
||||
className={`text-sm font-semibold leading-relaxed ${
|
||||
isSuccess ? 'text-green-700' : 'text-red-700'
|
||||
isSuccess ? 'text-green-600' : 'text-red-700'
|
||||
}`}
|
||||
>
|
||||
{isSuccess
|
||||
|
||||
@@ -13,7 +13,7 @@ export default function ErrorDisplay({ error }: ErrorDisplayProps) {
|
||||
<div className="flex flex-col items-center justify-center rounded-lg p-6 shadow-lg border border-red-200 bg-red-50">
|
||||
<AlertCircle className="h-9 w-9 text-red-500 mb-3" />
|
||||
<p className="text-sm font-bold leading-relaxed mb-4 text-red-600">{error}</p>
|
||||
<p className="text-xs font-medium leading-relaxed text-gray-500">
|
||||
<p className="text-xs font-medium leading-relaxed text-muted-foreground">
|
||||
{t('storageCleaner:errorStandardOnly')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -22,23 +22,23 @@ export default function OptionItem({
|
||||
className={`flex justify-between items-center py-2 px-3 rounded-lg transition-all duration-200 ${
|
||||
checked
|
||||
? 'bg-amber-50 border border-amber-200'
|
||||
: 'bg-transparent border border-transparent hover:bg-gray-50 hover:shadow-sm'
|
||||
: 'bg-transparent border border-transparent hover:bg-muted hover:shadow-sm'
|
||||
}`}
|
||||
>
|
||||
<div className="flex-1 min-w-0 mr-3">
|
||||
<span
|
||||
className={`block text-xs leading-tight truncate transition-colors ${
|
||||
checked ? 'text-amber-700 font-bold' : 'text-gray-900 font-bold'
|
||||
checked ? 'text-amber-700 font-bold' : 'text-foreground font-bold'
|
||||
}`}
|
||||
>
|
||||
{t(labelKey)}
|
||||
</span>
|
||||
{size !== undefined && size > 0 ? (
|
||||
<span className="block text-[10px] font-semibold text-gray-500 mt-0.5 opacity-80">
|
||||
<span className="block text-[10px] font-semibold text-muted-foreground mt-0.5 opacity-80">
|
||||
{isCount ? `${size} ${t('storageCleaner:countUnit')}` : formatSize(size)}
|
||||
</span>
|
||||
) : (
|
||||
<span className="block text-[10px] font-medium text-gray-400 mt-0.5 italic">
|
||||
<span className="block text-[10px] font-medium text-muted-foreground mt-0.5 italic">
|
||||
{t('storageCleaner:noData')}
|
||||
</span>
|
||||
)}
|
||||
@@ -47,7 +47,7 @@ export default function OptionItem({
|
||||
type="checkbox"
|
||||
checked={checked}
|
||||
onChange={onChange}
|
||||
className="h-4 w-4 rounded border-gray-300 text-amber-500 focus:ring-amber-500"
|
||||
className="h-4 w-4 rounded border-input text-amber-500 focus:ring-amber-500"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -31,7 +31,7 @@ export default function StorageOptionsGrid({
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="mb-3 border rounded-lg bg-white shadow-sm overflow-hidden transition-all hover:shadow-md">
|
||||
<div className="mb-3 border rounded-lg bg-background shadow-sm overflow-hidden transition-all hover:shadow-md">
|
||||
<div className="p-3">
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
{optionKeys.map(({ key, isCount }) => (
|
||||
@@ -48,13 +48,15 @@ export default function StorageOptionsGrid({
|
||||
</div>
|
||||
</div>
|
||||
<div className="border-t" />
|
||||
<div className="flex justify-between items-center px-5 py-2 transition-colors hover:bg-gray-50 rounded-b-lg">
|
||||
<span className="text-xs font-bold text-gray-500">{t('storageCleaner:selectAll')}</span>
|
||||
<div className="flex justify-between items-center px-5 py-2 transition-colors hover:bg-muted rounded-b-lg">
|
||||
<span className="text-xs font-bold text-muted-foreground">
|
||||
{t('storageCleaner:selectAll')}
|
||||
</span>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={allSelected}
|
||||
onChange={(e) => onSelectAll(e.target.checked)}
|
||||
className="h-4 w-4 rounded border-gray-300 text-amber-500 focus:ring-amber-500"
|
||||
className="h-4 w-4 rounded border-input text-amber-500 focus:ring-amber-500"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user