mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-28 05:39:34 +08:00
feat: dark mode
This commit is contained in:
@@ -2,6 +2,7 @@ import AppLogo from './src/AppLogo.vue';
|
||||
import AppProvider from './src/AppProvider.vue';
|
||||
import AppSearch from './src/search/AppSearch.vue';
|
||||
import AppLocalePicker from './src/AppLocalePicker.vue';
|
||||
import AppDarkModeToggle from './src/AppDarkModeToggle.vue';
|
||||
|
||||
export { useAppProviderContext } from './src/useAppContext';
|
||||
export { AppLogo, AppProvider, AppSearch, AppLocalePicker };
|
||||
export { AppLogo, AppProvider, AppSearch, AppLocalePicker, AppDarkModeToggle };
|
||||
|
111
src/components/Application/src/AppDarkModeToggle.vue
Normal file
111
src/components/Application/src/AppDarkModeToggle.vue
Normal file
@@ -0,0 +1,111 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="getShowDarkModeToggle"
|
||||
:class="[
|
||||
prefixCls,
|
||||
`${prefixCls}--${size}`,
|
||||
{
|
||||
[`${prefixCls}--dark`]: isDark,
|
||||
},
|
||||
]"
|
||||
@click="toggleDarkMode"
|
||||
>
|
||||
<div :class="`${prefixCls}-inner`"> </div>
|
||||
<SvgIcon size="14" name="sun" />
|
||||
<SvgIcon size="14" name="moon" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed } from 'vue';
|
||||
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
|
||||
import { SvgIcon } from '/@/components/Icon';
|
||||
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
||||
import { updateHeaderBgColor, updateSidebarBgColor } from '/@/logics/theme/updateBackground';
|
||||
import { updateDarkTheme } from '/@/logics/theme/dark';
|
||||
|
||||
import { ThemeEnum } from '/@/enums/appEnum';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'DarkModeToggle',
|
||||
components: { SvgIcon },
|
||||
props: {
|
||||
size: {
|
||||
type: String,
|
||||
default: 'default',
|
||||
validate: (val) => ['default', 'large'].includes(val),
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const { prefixCls } = useDesign('dark-mode-toggle');
|
||||
const { getDarkMode, setDarkMode, getShowDarkModeToggle } = useRootSetting();
|
||||
const isDark = computed(() => getDarkMode.value === ThemeEnum.DARK);
|
||||
function toggleDarkMode() {
|
||||
const darkMode = getDarkMode.value === ThemeEnum.DARK ? ThemeEnum.LIGHT : ThemeEnum.DARK;
|
||||
setDarkMode(darkMode);
|
||||
updateDarkTheme(darkMode);
|
||||
updateHeaderBgColor();
|
||||
updateSidebarBgColor();
|
||||
}
|
||||
|
||||
return {
|
||||
isDark,
|
||||
prefixCls,
|
||||
toggleDarkMode,
|
||||
getShowDarkModeToggle,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@prefix-cls: ~'@{namespace}-dark-mode-toggle';
|
||||
|
||||
html[data-theme='dark'] {
|
||||
.@{prefix-cls} {
|
||||
border: 1px solid rgb(196, 188, 188);
|
||||
}
|
||||
}
|
||||
|
||||
.@{prefix-cls} {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 50px;
|
||||
height: 26px;
|
||||
padding: 0 6px;
|
||||
margin-left: auto;
|
||||
cursor: pointer;
|
||||
background-color: #151515;
|
||||
border-radius: 30px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
&-inner {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
background-color: #fff;
|
||||
border-radius: 50%;
|
||||
transition: transform 0.5s, background-color 0.5s;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
&--dark {
|
||||
.@{prefix-cls}-inner {
|
||||
transform: translateX(calc(100% + 2px));
|
||||
}
|
||||
}
|
||||
|
||||
&--large {
|
||||
width: 72px;
|
||||
height: 34px;
|
||||
padding: 0 10px;
|
||||
|
||||
.@{prefix-cls}-inner {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -42,9 +42,9 @@
|
||||
padding: 0 16px;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
background: rgb(255 255 255);
|
||||
background: @component-background;
|
||||
border-top: 1px solid @border-color-base;
|
||||
border-radius: 0 0 16px 16px;
|
||||
box-shadow: 0 -1px 0 0 #e0e3e8, 0 -3px 6px 0 rgba(69, 98, 155, 0.12);
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
|
||||
|
@@ -190,12 +190,10 @@
|
||||
&-content {
|
||||
position: relative;
|
||||
width: 632px;
|
||||
// padding: 14px;
|
||||
margin: 0 auto auto auto;
|
||||
background: #f5f6f7;
|
||||
background: @component-background;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
||||
// box-shadow: inset 1px 1px 0 0 hsla(0, 0%, 100%, 0.5), 0 3px 8px 0 #555a64;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
@@ -253,8 +251,7 @@
|
||||
font-size: 14px;
|
||||
color: @text-color-base;
|
||||
cursor: pointer;
|
||||
// background: @primary-color;
|
||||
background: #fff;
|
||||
background: @component-background;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 3px 0 #d4d9e1;
|
||||
align-items: center;
|
||||
|
Reference in New Issue
Block a user