<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>
|