feat: 新增侧边栏颜色切换 (#681)

* fix: 修复Header元素偏移的问题

* fix: 修复i18n未引用的问题

* feat: 新增侧边栏颜色模式

* chore: 移除侧边栏模式跟随系统

* feat: 换种展示方式
This commit is contained in:
悠静萝莉 2024-02-14 22:51:15 +08:00 committed by GitHub
parent b9095ce939
commit ce97b04d79
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 67 additions and 16 deletions

View File

@ -5,6 +5,7 @@ export default {
mode: 'light',
layout: 'side',
splitMenu: false,
sideMode: 'light',
isFooterAside: false,
isSidebarFixed: true,
isHeaderFixed: true,

View File

@ -238,7 +238,6 @@ const navToHelper = () => {
display: flex;
align-items: normal;
line-height: 0;
padding-left: var(--td-comp-margin-xl);
}
.header-logo-container {

View File

@ -5,7 +5,7 @@
:layout="settingStore.layout"
:is-fixed="settingStore.isSidebarFixed"
:menu="sideMenu"
:theme="settingStore.displayMode"
:theme="settingStore.displaySideMode"
:is-compact="settingStore.isSidebarCompact"
/>
</template>

View File

@ -3,12 +3,12 @@
<t-menu :class="menuCls" :theme="theme" :value="active" :collapsed="collapsed" :default-expanded="defaultExpanded">
<template #logo>
<span v-if="showLogo" :class="`${prefix}-side-nav-logo-wrapper`" @click="goHome">
<component :is="getLogo()" :class="`${prefix}-side-nav-logo-${collapsed ? 't' : 'tdesign'}-logo`" />
<component :is="getLogo()" :class="logoCls" />
</span>
</template>
<menu-content :nav-data="menu" />
<template #operations>
<span class="version-container"> {{ !collapsed ? 'TDesign Starter' : '' }} {{ pgk.version }} </span>
<span :class="versionCls"> {{ !collapsed ? 'TDesign Starter' : '' }} {{ pgk.version }} </span>
</template>
</t-menu>
<div :class="`${prefix}-side-nav-placeholder${collapsed ? '-hidden' : ''}`"></div>
@ -75,6 +75,10 @@ const defaultExpanded = computed(() => {
return union(expanded, parentPath === '' ? [] : [parentPath]);
});
const sideMode = computed(() => {
const { theme } = props;
return theme === 'dark';
});
const sideNavCls = computed(() => {
const { isCompact } = props;
return [
@ -84,7 +88,22 @@ const sideNavCls = computed(() => {
},
];
});
const logoCls = computed(() => {
return [
`${prefix}-side-nav-logo-${collapsed.value ? 't' : 'tdesign'}-logo`,
{
[`${prefix}-side-nav-dark`]: sideMode.value,
},
];
});
const versionCls = computed(() => {
return [
`version-container`,
{
[`${prefix}-side-nav-dark`]: sideMode.value,
},
];
});
const menuCls = computed(() => {
const { showLogo, isFixed, layout } = props;
return [

View File

@ -52,7 +52,6 @@
</t-popup>
</div>
</t-radio-group>
<div class="setting-group-title">{{ $t('layout.setting.navigationLayout') }}</div>
<t-radio-group v-model="formData.layout">
<div v-for="(item, index) in LAYOUT_OPTION" :key="index" class="setting-layout-drawer">
@ -62,15 +61,24 @@
</div>
</t-radio-group>
<t-form-item v-show="formData.layout === 'mix'" label="分割菜单(混合模式下有效)" name="splitMenu">
<t-form-item v-show="formData.layout === 'mix'" :label="$t('layout.setting.splitMenu')" name="splitMenu">
<t-switch v-model="formData.splitMenu" />
</t-form-item>
<t-form-item v-show="formData.layout === 'mix'" label="固定 Sidebar" name="isSidebarFixed">
<t-form-item
v-show="formData.layout === 'mix'"
:label="$t('layout.setting.fixedSidebar')"
name="isSidebarFixed"
>
<t-switch v-model="formData.isSidebarFixed" />
</t-form-item>
<div class="setting-group-title">{{ $t('layout.setting.element.title') }}</div>
<t-form-item :label="$t('layout.setting.sideMode')" name="sideMode">
<t-radio-group v-model="formData.sideMode" class="side-mode-radio">
<t-radio-button key="light" value="light" :label="$t('layout.setting.theme.options.light')" />
<t-radio-button key="dark" value="dark" :label="$t('layout.setting.theme.options.dark')" />
</t-radio-group>
</t-form-item>
<t-form-item
v-show="formData.layout === 'side'"
:label="$t('layout.setting.element.showHeader')"
@ -295,6 +303,10 @@ watchEffect(() => {
width: 100%;
justify-content: space-between;
align-items: center;
&.side-mode-radio {
justify-content: end;
}
}
.t-radio-group.t-size-m .t-radio-button {

View File

@ -33,6 +33,7 @@ export default {
},
},
navigationLayout: 'Navigation Layout',
sideMode: 'Side Menu Mode',
splitMenu: 'Split MenuOnly Mix mode',
fixedSidebar: 'Fixed Sidebar',
element: {

View File

@ -33,6 +33,7 @@ export default {
},
},
navigationLayout: '导航布局',
sideMode: '侧边栏模式',
splitMenu: '分割菜单(混合模式下有效)',
fixedSidebar: '固定侧边栏',
element: {

View File

@ -33,18 +33,16 @@ export const useSettingStore = defineStore('setting', {
}
return state.mode as 'dark' | 'light';
},
displaySideMode: (state): 'dark' | 'light' => {
return state.sideMode as 'dark' | 'light';
},
},
actions: {
async changeMode(mode: 'dark' | 'light' | 'auto') {
let theme = mode;
if (mode === 'auto') {
const media = window.matchMedia('(prefers-color-scheme:dark)');
if (media.matches) {
theme = 'dark';
} else {
theme = 'light';
}
theme = this.getMediaColor();
}
const isDarkMode = theme === 'dark';
@ -52,6 +50,19 @@ export const useSettingStore = defineStore('setting', {
this.chartColors = isDarkMode ? DARK_CHART_COLORS : LIGHT_CHART_COLORS;
},
async changeSideMode(mode: 'dark' | 'light') {
const isDarkMode = mode === 'dark';
document.documentElement.setAttribute('side-mode', isDarkMode ? 'dark' : '');
},
getMediaColor() {
const media = window.matchMedia('(prefers-color-scheme:dark)');
if (media.matches) {
return 'dark';
}
return 'light';
},
changeBrandTheme(brandTheme: string) {
const mode = this.displayMode;
// 以主题色加显示模式作为键
@ -79,6 +90,9 @@ export const useSettingStore = defineStore('setting', {
if (key === 'mode') {
this.changeMode(payload[key]);
}
if (key === 'sideMode') {
this.changeSideMode(payload[key]);
}
if (key === 'brandTheme') {
this.changeBrandTheme(payload[key]);
}

View File

@ -163,7 +163,7 @@
}
&-logo-tdesign-logo {
padding: 0 var(--td-comp-paddingLR-xl);
margin-right: var(--td-comp-margin-xxxl);
height: var(--td-comp-size-s);
width: 100%;
color: var(--td-text-color-primary);
@ -176,6 +176,10 @@
}
}
&-side-nav-dark {
color: var(--td-font-white-1) !important;
}
&-side-nav-placeholder {
flex: 1 1 232px;
min-width: 232px;