mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-10 06:14:33 +00:00
feat(frontend): Phase 5a — theme system + Vite 8 + vue-i18n 11
Bumps Vite to 8.0.11 (npm install picked up 6.4.2 from the stale
lockfile; clean install resolves the new constraint). Bumps vue-i18n
to 11.1.4 since v10 was just EOL'd.
Migrates aThemeSwitch.html — the two-flavor theme picker + global
themeSwitcher object — into:
- composables/useTheme.js: single reactive `theme` state with
toggleTheme / toggleUltra. Boot side-effect applies the stored theme
to <body>/<html> before Vue renders; watchEffect persists changes
back to localStorage.
- components/ThemeSwitch.vue: full menu version for the main panel.
- components/ThemeSwitchLogin.vue: login-popover version.
AD-Vue 1 → 4 changes hit on this component:
- <a-icon type="bulb" :theme="filled|outlined"> dropped — replaced by
explicit BulbFilled / BulbOutlined imports from
@ant-design/icons-vue, swapped via <component :is="BulbIcon">
- Vue.component('a-theme-switch', { ... }) global registration → SFC
+ per-page import
- this.$message.config(...) (Vue 2 instance method) → message.config(...)
imported from ant-design-vue, called once in login.js at boot
Login page now surfaces a settings button → popover → theme picker.
Known gap: web/assets/css/custom.min.css isn't yet imported into the
new bundle, so toggling dark mode currently only re-themes AD-Vue's
own components, not the panel chrome. The body class is still toggled
so behavior is correct; visual fidelity returns when custom.css is
ported or directly imported.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
46
frontend/src/components/ThemeSwitch.vue
Normal file
46
frontend/src/components/ThemeSwitch.vue
Normal file
@@ -0,0 +1,46 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import { BulbFilled, BulbOutlined } from '@ant-design/icons-vue';
|
||||
import { theme, currentTheme, toggleTheme, toggleUltra, pauseAnimationsUntilLeave } from '@/composables/useTheme.js';
|
||||
|
||||
const BulbIcon = computed(() => (theme.isDark ? BulbFilled : BulbOutlined));
|
||||
|
||||
function onDarkChange() {
|
||||
pauseAnimationsUntilLeave('change-theme');
|
||||
toggleTheme();
|
||||
}
|
||||
|
||||
function onUltraClick() {
|
||||
pauseAnimationsUntilLeave('change-theme-ultra');
|
||||
toggleUltra();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-menu :theme="currentTheme" mode="inline" :selected-keys="[]">
|
||||
<a-sub-menu>
|
||||
<template #title>
|
||||
<span>
|
||||
<component :is="BulbIcon" />
|
||||
<span class="theme-label">Theme</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<a-menu-item id="change-theme" class="ant-menu-theme-switch">
|
||||
<span>Dark</span>
|
||||
<a-switch :style="{ marginLeft: '2px' }" size="small" :checked="theme.isDark" @change="onDarkChange" />
|
||||
</a-menu-item>
|
||||
|
||||
<a-menu-item v-if="theme.isDark" id="change-theme-ultra" class="ant-menu-theme-switch">
|
||||
<span>Ultra dark</span>
|
||||
<a-checkbox :style="{ marginLeft: '2px' }" :checked="theme.isUltra" @click="onUltraClick" />
|
||||
</a-menu-item>
|
||||
</a-sub-menu>
|
||||
</a-menu>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.theme-label {
|
||||
margin-left: 8px;
|
||||
}
|
||||
</style>
|
||||
25
frontend/src/components/ThemeSwitchLogin.vue
Normal file
25
frontend/src/components/ThemeSwitchLogin.vue
Normal file
@@ -0,0 +1,25 @@
|
||||
<script setup>
|
||||
import { theme, toggleTheme, toggleUltra, pauseAnimationsUntilLeave } from '@/composables/useTheme.js';
|
||||
|
||||
function onDarkChange() {
|
||||
pauseAnimationsUntilLeave('change-theme');
|
||||
toggleTheme();
|
||||
}
|
||||
|
||||
function onUltraClick() {
|
||||
toggleUltra();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-space id="change-theme" direction="vertical" :size="10" :style="{ width: '100%' }">
|
||||
<a-space direction="horizontal" size="small">
|
||||
<a-switch size="small" :checked="theme.isDark" @change="onDarkChange" />
|
||||
<span>Dark</span>
|
||||
</a-space>
|
||||
<a-space v-if="theme.isDark" direction="horizontal" size="small">
|
||||
<a-checkbox :checked="theme.isUltra" @click="onUltraClick" />
|
||||
<span>Ultra dark</span>
|
||||
</a-space>
|
||||
</a-space>
|
||||
</template>
|
||||
Reference in New Issue
Block a user