Skip to content

Commit 72679cc

Browse files
EstrellaXDclaude
andcommitted
feat(webui): complete UI redesign with design system, dark mode, and accessibility
Implement a comprehensive UI overhaul using CSS custom properties for theming, scoped SCSS for all components and pages, dark/light mode toggle with flash prevention, page transitions, ARIA accessibility attributes, and responsive layout fixes. Fix VueUse auto-import configuration and dev proxy target. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 7913061 commit 72679cc

37 files changed

Lines changed: 2358 additions & 954 deletions

webui/index.html

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,24 @@
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<meta name="robots" content="noindex, nofollow" />
7-
<meta name="theme-color" content="#ffffff" />
7+
<meta name="theme-color" content="#FAFAFA" />
88
<link rel="icon" href="/images/logo.svg" />
99
<link rel="apple-touch-icon" href="/images/apple-touch-icon.png" />
1010
<meta name="description" content="Automated Bangumi Download Tool" />
11+
<link rel="preconnect" href="https://fonts.googleapis.com" />
12+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
13+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" />
1114
<title>AutoBangumi</title>
15+
<script>
16+
// Apply dark mode before render to prevent flash
17+
(function() {
18+
const saved = localStorage.getItem('theme');
19+
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
20+
if (saved === 'dark' || (!saved && prefersDark)) {
21+
document.documentElement.classList.add('dark');
22+
}
23+
})();
24+
</script>
1225
</head>
1326
<body>
1427
<div id="app"></div>

webui/src/App.vue

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,88 @@
11
<script setup lang="ts">
2-
import { type GlobalThemeOverrides, NConfigProvider } from 'naive-ui';
2+
import { computed } from 'vue';
3+
import { type GlobalThemeOverrides, NConfigProvider, darkTheme } from 'naive-ui';
34
4-
const theme: GlobalThemeOverrides = {
5+
const { isDark } = useDarkMode();
6+
const { refresh, isLoggedIn } = useAuth();
7+
8+
if (isLoggedIn.value) {
9+
refresh();
10+
}
11+
12+
const lightOverrides: GlobalThemeOverrides = {
13+
common: {
14+
primaryColor: '#6C4AB6',
15+
primaryColorHover: '#563A92',
16+
primaryColorPressed: '#4A3291',
17+
bodyColor: '#FAFAFA',
18+
cardColor: '#FFFFFF',
19+
borderColor: '#E2E8F0',
20+
textColorBase: '#1E293B',
21+
textColor1: '#1E293B',
22+
textColor2: '#64748B',
23+
textColor3: '#94A3B8',
24+
},
525
Spin: {
6-
color: '#fff',
26+
color: '#6C4AB6',
727
},
828
DataTable: {
9-
thColor: 'rgba(255, 255, 255, 0)',
10-
thColorHover: 'rgba(255, 255, 255, 0)',
11-
tdColorHover: 'rgba(255, 255, 255, 0)',
29+
thColor: 'transparent',
30+
thColorHover: 'transparent',
31+
tdColorHover: 'var(--color-surface-hover)',
32+
borderColor: 'var(--color-border)',
1233
},
1334
Checkbox: {
14-
colorChecked: '#4e3c94',
15-
borderFocus: '#4e3c94',
16-
boxShadowFocus: '0 0 0 2px rgba(78, 60, 148, 0.2)',
17-
borderChecked: '1px solid #4e3c94',
35+
colorChecked: '#6C4AB6',
36+
borderFocus: '#6C4AB6',
37+
boxShadowFocus: '0 0 0 2px rgba(108, 74, 182, 0.2)',
38+
borderChecked: '1px solid #6C4AB6',
1839
},
1940
};
2041
21-
const { refresh, isLoggedIn } = useAuth();
42+
const darkOverrides: GlobalThemeOverrides = {
43+
common: {
44+
primaryColor: '#8B6CC7',
45+
primaryColorHover: '#A78BDB',
46+
primaryColorPressed: '#7B5CB7',
47+
bodyColor: '#0F172A',
48+
cardColor: '#1E293B',
49+
borderColor: '#334155',
50+
textColorBase: '#F1F5F9',
51+
textColor1: '#F1F5F9',
52+
textColor2: '#94A3B8',
53+
textColor3: '#64748B',
54+
},
55+
Spin: {
56+
color: '#8B6CC7',
57+
},
58+
DataTable: {
59+
thColor: 'transparent',
60+
thColorHover: 'transparent',
61+
tdColorHover: 'var(--color-surface-hover)',
62+
borderColor: 'var(--color-border)',
63+
},
64+
Checkbox: {
65+
colorChecked: '#8B6CC7',
66+
borderFocus: '#8B6CC7',
67+
boxShadowFocus: '0 0 0 2px rgba(139, 108, 199, 0.2)',
68+
borderChecked: '1px solid #8B6CC7',
69+
},
70+
};
2271
23-
if (isLoggedIn.value) {
24-
refresh();
25-
}
72+
const themeOverrides = computed(() => isDark.value ? darkOverrides : lightOverrides);
73+
const naiveTheme = computed(() => isDark.value ? darkTheme : null);
2674
</script>
2775

2876
<template>
2977
<Suspense>
30-
<NConfigProvider :theme-overrides="theme">
78+
<NConfigProvider :theme="naiveTheme" :theme-overrides="themeOverrides">
3179
<RouterView></RouterView>
3280
</NConfigProvider>
3381
</Suspense>
3482
</template>
3583

3684
<style lang="scss">
37-
@import './style/transition';
3885
@import './style/var';
86+
@import './style/transition';
3987
@import './style/global';
4088
</style>

0 commit comments

Comments
 (0)