feat(ui): 添加明暗主题切换支持

- 创建 ThemeProvider 管理主题状态
- 配置浅色和深色主题(Vercel/Linear 风格)
- 集成 Google Fonts(Inter + JetBrains Mono)
- 在我的页面添加主题切换开关
- 更新颜色系统符合 modernization-v2.md 规范
- 优化间距和圆角系统

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-23 14:12:00 +08:00
parent 6ccb29556e
commit c4cf23a4a1
11 changed files with 1052 additions and 208 deletions

View File

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:shadcn_ui/shadcn_ui.dart';
import 'package:provider/provider.dart';
import '../../../providers/auth_provider.dart';
import '../../../providers/theme_provider.dart';
import '../auth/login_page.dart';
/// 菜单项数据模型
@@ -241,15 +242,19 @@ class _MenuList extends StatelessWidget {
@override
Widget build(BuildContext context) {
final theme = ShadTheme.of(context);
final items = _buildMenuItems();
final themeProvider = context.watch<ThemeProvider>();
return ShadCard(
padding: EdgeInsets.zero,
child: Column(
children: [
for (var i = 0; i < items.length; i++) ...[
_MenuItemTile(item: items[i]),
if (i < items.length - 1)
// 主题切换开关(特殊处理)
_ThemeToggleTile(isDarkMode: themeProvider.isDarkMode),
Divider(color: theme.colorScheme.border, height: 1, indent: 56),
// 普通菜单项
for (var i = 0; i < _buildMenuItems().length; i++) ...[
_MenuItemTile(item: _buildMenuItems()[i]),
if (i < _buildMenuItems().length - 1)
Divider(color: theme.colorScheme.border, height: 1, indent: 56),
],
],
@@ -268,6 +273,51 @@ class _MenuList extends StatelessWidget {
}
}
/// 主题切换组件
class _ThemeToggleTile extends StatelessWidget {
final bool isDarkMode;
const _ThemeToggleTile({required this.isDarkMode});
@override
Widget build(BuildContext context) {
final theme = ShadTheme.of(context);
final themeProvider = context.read<ThemeProvider>();
return InkWell(
onTap: () => themeProvider.toggleTheme(),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
child: Row(
children: [
_MenuIcon(icon: isDarkMode ? LucideIcons.moon : LucideIcons.sun),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('深色模式', style: theme.textTheme.small.copyWith(fontWeight: FontWeight.w500)),
const SizedBox(height: 2),
Text(
isDarkMode ? '当前:深色主题' : '当前:浅色主题',
style: theme.textTheme.muted.copyWith(fontSize: 11),
),
],
),
),
Switch(
value: isDarkMode,
onChanged: (_) => themeProvider.toggleTheme(),
activeTrackColor: theme.colorScheme.primary.withValues(alpha: 0.5),
activeColor: theme.colorScheme.primary,
),
],
),
),
);
}
}
/// 菜单项组件
class _MenuItemTile extends StatelessWidget {
final _MenuItem item;