Skip to content

Commit 4187fac

Browse files
committed
feat: add dark mode support
1 parent 5d8e806 commit 4187fac

6 files changed

Lines changed: 55 additions & 9 deletions

File tree

src/App.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import ChartContainer from './components/ChartContainer';
66
import { ComparisonControls } from './components/ComparisonControls';
77
import { Header } from './components/Header';
88
import { FileConfigModal } from './components/FileConfigModal';
9+
import { ThemeToggle } from './components/ThemeToggle';
910
import { PanelLeftClose, PanelLeftOpen } from 'lucide-react';
1011
import { mergeFilesWithReplacement } from './utils/mergeFiles.js';
1112

@@ -273,9 +274,10 @@ function App() {
273274
<h1 className="text-lg font-extrabold text-transparent bg-clip-text bg-gradient-to-r from-blue-600 via-purple-500 to-indigo-600 animate-gradient-slow">
274275
Log Analyzer
275276
</h1>
277+
<ThemeToggle className="ml-auto" />
276278
<button
277279
onClick={() => setSidebarVisible(false)}
278-
className="ml-auto p-1 text-gray-400 hover:text-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 rounded"
280+
className="p-1 text-gray-400 hover:text-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 rounded"
279281
aria-label="隐藏工具栏"
280282
>
281283
<PanelLeftClose size={16} aria-hidden="true" />

src/components/FileUpload.jsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,18 @@ export function FileUpload({ onFilesUploaded }) {
6363
}, [processFiles]);
6464

6565
return (
66-
<div className="bg-white rounded-lg shadow-md p-3">
66+
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-md p-3">
6767
<h3
6868
id="file-upload-heading"
69-
className="text-base font-semibold text-gray-800 mb-2"
69+
className="text-base font-semibold text-gray-800 dark:text-gray-100 mb-2"
7070
>
7171
📁 文件上传
7272
</h3>
7373
<div
7474
className={`drag-area border-2 border-dashed rounded-lg p-4 text-center cursor-pointer ${
75-
isDragOver ? 'border-blue-500 bg-blue-50' : 'border-gray-300 hover:border-gray-400'
75+
isDragOver
76+
? 'border-blue-500 bg-blue-50 dark:bg-blue-900'
77+
: 'border-gray-300 hover:border-gray-400 dark:border-gray-600 dark:hover:border-gray-500 dark:bg-gray-700'
7678
}`}
7779
onDragEnter={handleDragEnter}
7880
onDragOver={handleDragOver}
@@ -90,17 +92,17 @@ export function FileUpload({ onFilesUploaded }) {
9092
}
9193
}}
9294
>
93-
<Upload
94-
className="mx-auto mb-2 text-gray-400"
95-
size={32}
95+
<Upload
96+
className="mx-auto mb-2 text-gray-400 dark:text-gray-200"
97+
size={32}
9698
aria-hidden="true"
9799
/>
98-
<p className="text-sm text-gray-600 mb-1">
100+
<p className="text-sm text-gray-600 dark:text-gray-300 mb-1">
99101
🎯 拖拽文件到此处或点击选择文件
100102
</p>
101103
<p
102104
id="file-upload-description"
103-
className="text-xs text-gray-500"
105+
className="text-xs text-gray-500 dark:text-gray-400"
104106
>
105107
📄 支持所有文本格式文件
106108
</p>

src/components/ThemeToggle.jsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React, { useState } from 'react';
2+
import { Moon, Sun } from 'lucide-react';
3+
4+
export function ThemeToggle({ className = '' }) {
5+
const [isDark, setIsDark] = useState(() =>
6+
document.documentElement.classList.contains('dark')
7+
);
8+
9+
const toggleTheme = () => {
10+
document.documentElement.classList.toggle('dark');
11+
setIsDark(document.documentElement.classList.contains('dark'));
12+
};
13+
14+
return (
15+
<button
16+
onClick={toggleTheme}
17+
aria-label="切换主题"
18+
className={`p-1 text-gray-400 hover:text-gray-600 dark:text-gray-300 dark:hover:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 rounded ${className}`}
19+
>
20+
{isDark ? <Sun size={16} aria-hidden="true" /> : <Moon size={16} aria-hidden="true" />}
21+
</button>
22+
);
23+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { render, screen, fireEvent } from '@testing-library/react';
2+
import { describe, it, expect } from 'vitest';
3+
import { ThemeToggle } from '../ThemeToggle';
4+
5+
describe('ThemeToggle', () => {
6+
it('toggles dark class on document element', () => {
7+
document.documentElement.classList.remove('dark');
8+
render(<ThemeToggle />);
9+
const button = screen.getByRole('button', { name: '切换主题' });
10+
fireEvent.click(button);
11+
expect(document.documentElement.classList.contains('dark')).toBe(true);
12+
fireEvent.click(button);
13+
expect(document.documentElement.classList.contains('dark')).toBe(false);
14+
});
15+
});

src/index.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
/* Accessibility improvements */
66
@layer base {
7+
body {
8+
@apply bg-gray-50 text-gray-900 dark:bg-gray-900 dark:text-gray-100;
9+
}
710
/* Screen reader only content */
811
.sr-only {
912
position: absolute;

tailwind.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/** @type {import('tailwindcss').Config} */
22
export default {
3+
darkMode: 'class',
34
content: [
45
"./index.html",
56
"./src/**/*.{js,ts,jsx,tsx}",

0 commit comments

Comments
 (0)