added dark mode 2

This commit is contained in:
2026-06-14 21:42:58 +03:30
parent c0633e5d5a
commit 31d7ade00f
+110 -39
View File
@@ -1,27 +1,42 @@
<template> <template>
<AMenuItemGroup title="پوسته"> <AMenuItem key="theme" class="theme-menu-entry" @click.stop>
<AMenuItem <APopover
v-for="opt in themeOptions" v-model:open="open"
:key="opt.value" trigger="click"
@click="darkmode.setSchema(opt.value)" placement="leftTop"
overlay-class-name="theme-menu-popover"
> >
<div class="theme-menu-item" :class="{ 'theme-menu-item--active': colorSchema === opt.value }"> <template #content>
<div class="theme-menu-item__main"> <div class="theme-menu-panel">
<Icon :icon="opt.icon" size="18" /> <button
<span>{{ opt.label }}</span> v-for="opt in themeOptions"
:key="opt.value"
type="button"
class="theme-menu-panel__option"
:class="{ 'theme-menu-panel__option--active': colorSchema === opt.value }"
@click="selectSchema(opt.value)"
>
<Icon :icon="opt.icon" size="18" />
<span>{{ opt.label }}</span>
<Icon
v-if="colorSchema === opt.value"
icon="vuesax-linear:tick-circle"
size="16"
class="theme-menu-panel__check"
/>
</button>
<div v-if="colorSchema === 'auto'" class="theme-menu-panel__hint">
وضعیت فعلی: {{ isDark ? 'تاریک' : 'روشن' }}
</div>
</div> </div>
<Icon </template>
v-if="colorSchema === opt.value" <div class="theme-menu-entry__trigger">
icon="vuesax-linear:tick-circle" <Icon :icon="triggerIcon" size="18" />
size="16" <span>پوسته</span>
class="theme-menu-item__check" <Icon icon="vuesax-linear:arrow-left" size="14" class="theme-menu-entry__arrow" />
/>
</div> </div>
</AMenuItem> </APopover>
<AMenuItem v-if="colorSchema === 'auto'" disabled class="theme-menu-hint-item"> </AMenuItem>
<span class="theme-menu-hint">وضعیت فعلی: {{ isDark ? 'تاریک' : 'روشن' }}</span>
</AMenuItem>
</AMenuItemGroup>
<AMenuDivider /> <AMenuDivider />
</template> </template>
@@ -29,8 +44,10 @@
import Icon from '@core/components/BaseIcon/src/Icon.vue' import Icon from '@core/components/BaseIcon/src/Icon.vue'
import { useAdminTheme } from '@core/composable/useAdminTheme' import { useAdminTheme } from '@core/composable/useAdminTheme'
import type { DarkModeSchema } from '@core/stores/darkmode' import type { DarkModeSchema } from '@core/stores/darkmode'
import { computed, ref } from 'vue'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
const open = ref(false)
const { isDark, darkmode } = useAdminTheme() const { isDark, darkmode } = useAdminTheme()
const { colorSchema } = storeToRefs(darkmode) const { colorSchema } = storeToRefs(darkmode)
@@ -39,45 +56,99 @@ const themeOptions: Array<{ value: DarkModeSchema; label: string; icon: string }
{ value: 'dark', label: 'تاریک', icon: 'vuesax-linear:moon' }, { value: 'dark', label: 'تاریک', icon: 'vuesax-linear:moon' },
{ value: 'auto', label: 'سیستم', icon: 'vuesax-linear:monitor' } { value: 'auto', label: 'سیستم', icon: 'vuesax-linear:monitor' }
] ]
const triggerIcon = computed(() => {
if (colorSchema.value === 'dark') return 'vuesax-linear:moon'
if (colorSchema.value === 'light') return 'vuesax-linear:sun-1'
return 'vuesax-linear:monitor'
})
function selectSchema(schema: DarkModeSchema) {
darkmode.setSchema(schema)
open.value = false
}
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.theme-menu-item { .theme-menu-entry {
padding: 0 !important;
}
.theme-menu-entry__trigger {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between;
gap: 8px; gap: 8px;
width: 100%; width: 100%;
min-width: 10rem; min-width: 10rem;
padding: 5px 12px;
cursor: pointer;
} }
.theme-menu-item__main { .theme-menu-entry__arrow {
margin-right: auto;
opacity: 0.45;
}
.theme-menu-panel {
display: flex;
flex-direction: column;
gap: 4px;
min-width: 9rem;
}
.theme-menu-panel__option {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8px; gap: 8px;
width: 100%;
padding: 8px 10px;
border: none;
border-radius: 6px;
background: transparent;
color: var(--admin-text);
font-size: 13px;
cursor: pointer;
text-align: right;
&:hover {
background: var(--admin-bg-hover);
color: var(--admin-gold-light);
}
&--active {
background: var(--admin-menu-selected);
color: var(--admin-menu-selected-text);
font-weight: 600;
}
} }
.theme-menu-item--active { .theme-menu-panel__check {
font-weight: 600; margin-right: auto;
}
.theme-menu-item__check {
color: var(--admin-gold-light, #d4af37); color: var(--admin-gold-light, #d4af37);
} }
.theme-menu-hint-item { .theme-menu-panel__hint {
height: auto !important; margin-top: 4px;
line-height: 1.3 !important; padding-top: 8px;
cursor: default !important; border-top: 1px solid var(--admin-border);
opacity: 1 !important;
}
.theme-menu-hint {
font-size: 11px; font-size: 11px;
color: rgba(0, 0, 0, 0.45); color: var(--admin-text-secondary);
} }
</style>
html.is-dark .theme-menu-hint { <style lang="less">
color: rgba(255, 255, 255, 0.45); .theme-menu-popover {
.ant-popover-inner {
background: var(--admin-bg-elevated);
border: 1px solid var(--admin-border-strong);
}
.ant-popover-inner-content {
padding: 8px;
}
.ant-popover-arrow-content::before {
background: var(--admin-bg-elevated);
}
} }
</style> </style>