mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-05-13 09:36:05 +00:00
fix(theme): default to dark, polish theme cycle visibility and hover
New installs land on plain dark instead of ultra-dark. The cycle button icon now has an explicit colour so it stays visible inside the mobile drawer (the previous color:inherit didn't cascade through the teleported node), and hover/focus matches the menu's blue across sidebar, login, and sub pages.
This commit is contained in:
parent
b5479f3f30
commit
88061bac10
4 changed files with 69 additions and 20 deletions
|
|
@ -128,7 +128,8 @@ function cycleTheme() {
|
||||||
<svg v-if="!theme.isDark" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
<svg v-if="!theme.isDark" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||||
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||||
<circle cx="12" cy="12" r="4" />
|
<circle cx="12" cy="12" r="4" />
|
||||||
<path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" />
|
<path
|
||||||
|
d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" />
|
||||||
</svg>
|
</svg>
|
||||||
<svg v-else-if="!theme.isUltra" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
<svg v-else-if="!theme.isUltra" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||||
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||||
|
|
@ -169,7 +170,8 @@ function cycleTheme() {
|
||||||
<svg v-if="!theme.isDark" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
<svg v-if="!theme.isDark" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||||
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||||
<circle cx="12" cy="12" r="4" />
|
<circle cx="12" cy="12" r="4" />
|
||||||
<path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" />
|
<path
|
||||||
|
d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" />
|
||||||
</svg>
|
</svg>
|
||||||
<svg v-else-if="!theme.isUltra" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
<svg v-else-if="!theme.isUltra" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||||
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||||
|
|
@ -275,16 +277,18 @@ function cycleTheme() {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: inherit;
|
color: rgba(0, 0, 0, 0.75);
|
||||||
padding: 0;
|
padding: 0;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
transition: background-color 0.2s, transform 0.15s;
|
transition: background-color 0.2s, transform 0.15s, color 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-cycle:hover,
|
.theme-cycle:hover,
|
||||||
.theme-cycle:focus-visible {
|
.theme-cycle:focus-visible {
|
||||||
background: rgba(128, 128, 128, 0.18);
|
background-color: rgba(64, 150, 255, 0.1);
|
||||||
|
color: #4096ff;
|
||||||
transform: scale(1.08);
|
transform: scale(1.08);
|
||||||
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-cycle svg {
|
.theme-cycle svg {
|
||||||
|
|
@ -446,6 +450,19 @@ html[data-theme='ultra-dark'] .drawer-close {
|
||||||
color: rgba(255, 255, 255, 0.85);
|
color: rgba(255, 255, 255, 0.85);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Force a visible icon colour on the theme cycle button across themes.
|
||||||
|
* The scoped `color: inherit` previously relied on parent chain to
|
||||||
|
* cascade — fine on the desktop sider where `.sider-brand` is themed,
|
||||||
|
* but inside the teleported drawer body the cascade didn't reach and
|
||||||
|
* the icon merged into the dark background on mobile. */
|
||||||
|
body.dark .theme-cycle {
|
||||||
|
color: rgba(255, 255, 255, 0.85);
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-theme='ultra-dark'] .theme-cycle {
|
||||||
|
color: rgba(255, 255, 255, 0.92);
|
||||||
|
}
|
||||||
|
|
||||||
/* Pin the drawer surface to the same colour the desktop sider uses
|
/* Pin the drawer surface to the same colour the desktop sider uses
|
||||||
* (Layout.colorBgHeader / Menu.colorItemBg from useTheme.js) so the
|
* (Layout.colorBgHeader / Menu.colorItemBg from useTheme.js) so the
|
||||||
* header, empty body region, and menu items read as one continuous
|
* header, empty body region, and menu items read as one continuous
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ function readBool(key, fallback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const isDark = readBool(STORAGE_DARK, true);
|
const isDark = readBool(STORAGE_DARK, true);
|
||||||
const isUltra = readBool(STORAGE_ULTRA, true);
|
const isUltra = readBool(STORAGE_ULTRA, false);
|
||||||
|
|
||||||
export const theme = reactive({
|
export const theme = reactive({
|
||||||
isDark,
|
isDark,
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,8 @@ function cycleTheme() {
|
||||||
<svg v-if="!themeState.isDark" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
<svg v-if="!themeState.isDark" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||||
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||||
<circle cx="12" cy="12" r="4" />
|
<circle cx="12" cy="12" r="4" />
|
||||||
<path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" />
|
<path
|
||||||
|
d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" />
|
||||||
</svg>
|
</svg>
|
||||||
<svg v-else-if="!themeState.isUltra" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
<svg v-else-if="!themeState.isUltra" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||||
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||||
|
|
@ -277,24 +278,49 @@ function cycleTheme() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes blob-drift-a {
|
@keyframes blob-drift-a {
|
||||||
0% { transform: translate(0, 0) scale(1); }
|
0% {
|
||||||
50% { transform: translate(18vw, 10vh) scale(1.15); }
|
transform: translate(0, 0) scale(1);
|
||||||
100% { transform: translate(34vw, 22vh) scale(1.25); }
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: translate(18vw, 10vh) scale(1.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translate(34vw, 22vh) scale(1.25);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes blob-drift-b {
|
@keyframes blob-drift-b {
|
||||||
0% { transform: translate(0, 0) scale(1); }
|
0% {
|
||||||
50% { transform: translate(-16vw, -10vh) scale(1.12); }
|
transform: translate(0, 0) scale(1);
|
||||||
100% { transform: translate(-30vw, -22vh) scale(1.2); }
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: translate(-16vw, -10vh) scale(1.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translate(-30vw, -22vh) scale(1.2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes blob-drift-c {
|
@keyframes blob-drift-c {
|
||||||
0% { transform: translate(-50%, -50%) scale(1); }
|
0% {
|
||||||
50% { transform: translate(-20%, -20%) scale(1.1); }
|
transform: translate(-50%, -50%) scale(1);
|
||||||
100% { transform: translate(-80%, -10%) scale(1.05); }
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: translate(-20%, -20%) scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translate(-80%, -10%) scale(1.05);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-reduced-motion: reduce) {
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
|
||||||
.login-app::before,
|
.login-app::before,
|
||||||
.login-app::after,
|
.login-app::after,
|
||||||
.login-content::before {
|
.login-content::before {
|
||||||
|
|
@ -310,7 +336,7 @@ function cycleTheme() {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-content > * {
|
.login-content>* {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
@ -347,7 +373,8 @@ function cycleTheme() {
|
||||||
|
|
||||||
.theme-cycle:hover,
|
.theme-cycle:hover,
|
||||||
.theme-cycle:focus-visible {
|
.theme-cycle:focus-visible {
|
||||||
color: var(--color-accent);
|
background-color: rgba(64, 150, 255, 0.1);
|
||||||
|
color: #4096ff;
|
||||||
transform: scale(1.05);
|
transform: scale(1.05);
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
@ -428,10 +455,12 @@ function cycleTheme() {
|
||||||
.headline-leave-active {
|
.headline-leave-active {
|
||||||
transition: opacity 280ms ease, transform 280ms ease;
|
transition: opacity 280ms ease, transform 280ms ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.headline-enter-from {
|
.headline-enter-from {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(6px);
|
transform: translateY(6px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.headline-leave-to {
|
.headline-leave-to {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(-6px);
|
transform: translateY(-6px);
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,8 @@ const themeClass = computed(() => ({
|
||||||
<svg v-if="!themeState.isDark" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
<svg v-if="!themeState.isDark" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||||
<circle cx="12" cy="12" r="4" />
|
<circle cx="12" cy="12" r="4" />
|
||||||
<path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" />
|
<path
|
||||||
|
d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" />
|
||||||
</svg>
|
</svg>
|
||||||
<svg v-else-if="!themeState.isUltra" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
<svg v-else-if="!themeState.isUltra" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||||
|
|
@ -503,7 +504,8 @@ const themeClass = computed(() => ({
|
||||||
|
|
||||||
.theme-cycle:hover,
|
.theme-cycle:hover,
|
||||||
.theme-cycle:focus-visible {
|
.theme-cycle:focus-visible {
|
||||||
color: #1677ff;
|
background-color: rgba(64, 150, 255, 0.1);
|
||||||
|
color: #4096ff;
|
||||||
transform: scale(1.05);
|
transform: scale(1.05);
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
@ -520,6 +522,7 @@ const themeClass = computed(() => ({
|
||||||
|
|
||||||
.is-dark .theme-cycle:hover,
|
.is-dark .theme-cycle:hover,
|
||||||
.is-dark .theme-cycle:focus-visible {
|
.is-dark .theme-cycle:focus-visible {
|
||||||
|
background-color: rgba(64, 150, 255, 0.1);
|
||||||
color: #4096ff;
|
color: #4096ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue