mirror of
https://github.com/soybeanjs/soybean-admin.git
synced 2025-09-21 02:56:38 +08:00
feat(projects)!: optimize layout mode, split horizontal mix component into two layouts, and rename the component.
This commit is contained in:
parent
d37ce04606
commit
b6ac3106ce
@ -127,7 +127,6 @@ function handleClickMask() {
|
|||||||
:class="[
|
:class="[
|
||||||
style['layout-header'],
|
style['layout-header'],
|
||||||
commonClass,
|
commonClass,
|
||||||
headerClass,
|
|
||||||
headerLeftGapClass,
|
headerLeftGapClass,
|
||||||
{ 'absolute top-0 left-0 w-full': fixedHeaderAndTab }
|
{ 'absolute top-0 left-0 w-full': fixedHeaderAndTab }
|
||||||
]"
|
]"
|
||||||
|
@ -6,12 +6,6 @@ interface AdminLayoutHeaderConfig {
|
|||||||
* @default true
|
* @default true
|
||||||
*/
|
*/
|
||||||
headerVisible?: boolean;
|
headerVisible?: boolean;
|
||||||
/**
|
|
||||||
* Header class
|
|
||||||
*
|
|
||||||
* @default ''
|
|
||||||
*/
|
|
||||||
headerClass?: string;
|
|
||||||
/**
|
/**
|
||||||
* Header height
|
* Header height
|
||||||
*
|
*
|
||||||
|
@ -24,7 +24,8 @@ export const themeLayoutModeRecord: Record<UnionKey.ThemeLayoutMode, App.I18n.I1
|
|||||||
vertical: 'theme.layout.layoutMode.vertical',
|
vertical: 'theme.layout.layoutMode.vertical',
|
||||||
'vertical-mix': 'theme.layout.layoutMode.vertical-mix',
|
'vertical-mix': 'theme.layout.layoutMode.vertical-mix',
|
||||||
horizontal: 'theme.layout.layoutMode.horizontal',
|
horizontal: 'theme.layout.layoutMode.horizontal',
|
||||||
'horizontal-mix': 'theme.layout.layoutMode.horizontal-mix'
|
'top-hybrid-sidebar-first': 'theme.layout.layoutMode.top-hybrid-sidebar-first',
|
||||||
|
'top-hybrid-header-first': 'theme.layout.layoutMode.top-hybrid-header-first'
|
||||||
};
|
};
|
||||||
|
|
||||||
export const themeLayoutModeOptions = transformRecordToOption(themeLayoutModeRecord);
|
export const themeLayoutModeOptions = transformRecordToOption(themeLayoutModeRecord);
|
||||||
|
@ -29,7 +29,7 @@ const layoutMode = computed(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const headerProps = computed(() => {
|
const headerProps = computed(() => {
|
||||||
const { mode, reverseHorizontalMix } = themeStore.layout;
|
const { mode } = themeStore.layout;
|
||||||
|
|
||||||
const headerPropsConfig: Record<UnionKey.ThemeLayoutMode, App.Global.HeaderProps> = {
|
const headerPropsConfig: Record<UnionKey.ThemeLayoutMode, App.Global.HeaderProps> = {
|
||||||
vertical: {
|
vertical: {
|
||||||
@ -47,10 +47,15 @@ const headerProps = computed(() => {
|
|||||||
showMenu: true,
|
showMenu: true,
|
||||||
showMenuToggler: false
|
showMenuToggler: false
|
||||||
},
|
},
|
||||||
'horizontal-mix': {
|
'top-hybrid-sidebar-first': {
|
||||||
showLogo: true,
|
showLogo: true,
|
||||||
showMenu: true,
|
showMenu: true,
|
||||||
showMenuToggler: reverseHorizontalMix && isActiveFirstLevelMenuHasChildren.value
|
showMenuToggler: false
|
||||||
|
},
|
||||||
|
'top-hybrid-header-first': {
|
||||||
|
showLogo: true,
|
||||||
|
showMenu: true,
|
||||||
|
showMenuToggler: isActiveFirstLevelMenuHasChildren.value
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -61,21 +66,22 @@ const siderVisible = computed(() => themeStore.layout.mode !== 'horizontal');
|
|||||||
|
|
||||||
const isVerticalMix = computed(() => themeStore.layout.mode === 'vertical-mix');
|
const isVerticalMix = computed(() => themeStore.layout.mode === 'vertical-mix');
|
||||||
|
|
||||||
const isHorizontalMix = computed(() => themeStore.layout.mode === 'horizontal-mix');
|
const isTopHybridSidebarFirst = computed(() => themeStore.layout.mode === 'top-hybrid-sidebar-first');
|
||||||
|
|
||||||
|
const isTopHybridHeaderFirst = computed(() => themeStore.layout.mode === 'top-hybrid-header-first');
|
||||||
|
|
||||||
const siderWidth = computed(() => getSiderWidth());
|
const siderWidth = computed(() => getSiderWidth());
|
||||||
|
|
||||||
const siderCollapsedWidth = computed(() => getSiderCollapsedWidth());
|
const siderCollapsedWidth = computed(() => getSiderCollapsedWidth());
|
||||||
|
|
||||||
function getSiderWidth() {
|
function getSiderWidth() {
|
||||||
const { reverseHorizontalMix } = themeStore.layout;
|
|
||||||
const { width, mixWidth, mixChildMenuWidth } = themeStore.sider;
|
const { width, mixWidth, mixChildMenuWidth } = themeStore.sider;
|
||||||
|
|
||||||
if (isHorizontalMix.value && reverseHorizontalMix) {
|
if (isTopHybridHeaderFirst.value) {
|
||||||
return isActiveFirstLevelMenuHasChildren.value ? width : 0;
|
return isActiveFirstLevelMenuHasChildren.value ? width : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let w = isVerticalMix.value || isHorizontalMix.value ? mixWidth : width;
|
let w = isVerticalMix.value || isTopHybridSidebarFirst.value ? mixWidth : width;
|
||||||
|
|
||||||
if (isVerticalMix.value && appStore.mixSiderFixed && childLevelMenus.value.length) {
|
if (isVerticalMix.value && appStore.mixSiderFixed && childLevelMenus.value.length) {
|
||||||
w += mixChildMenuWidth;
|
w += mixChildMenuWidth;
|
||||||
@ -85,14 +91,13 @@ function getSiderWidth() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getSiderCollapsedWidth() {
|
function getSiderCollapsedWidth() {
|
||||||
const { reverseHorizontalMix } = themeStore.layout;
|
|
||||||
const { collapsedWidth, mixCollapsedWidth, mixChildMenuWidth } = themeStore.sider;
|
const { collapsedWidth, mixCollapsedWidth, mixChildMenuWidth } = themeStore.sider;
|
||||||
|
|
||||||
if (isHorizontalMix.value && reverseHorizontalMix) {
|
if (isTopHybridHeaderFirst.value) {
|
||||||
return isActiveFirstLevelMenuHasChildren.value ? collapsedWidth : 0;
|
return isActiveFirstLevelMenuHasChildren.value ? collapsedWidth : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let w = isVerticalMix.value || isHorizontalMix.value ? mixCollapsedWidth : collapsedWidth;
|
let w = isVerticalMix.value || isTopHybridSidebarFirst.value ? mixCollapsedWidth : collapsedWidth;
|
||||||
|
|
||||||
if (isVerticalMix.value && appStore.mixSiderFixed && childLevelMenus.value.length) {
|
if (isVerticalMix.value && appStore.mixSiderFixed && childLevelMenus.value.length) {
|
||||||
w += mixChildMenuWidth;
|
w += mixChildMenuWidth;
|
||||||
|
@ -6,8 +6,8 @@ import { useThemeStore } from '@/store/modules/theme';
|
|||||||
import VerticalMenu from './modules/vertical-menu.vue';
|
import VerticalMenu from './modules/vertical-menu.vue';
|
||||||
import VerticalMixMenu from './modules/vertical-mix-menu.vue';
|
import VerticalMixMenu from './modules/vertical-mix-menu.vue';
|
||||||
import HorizontalMenu from './modules/horizontal-menu.vue';
|
import HorizontalMenu from './modules/horizontal-menu.vue';
|
||||||
import HorizontalMixMenu from './modules/horizontal-mix-menu.vue';
|
import TopHybridSidebarFirst from './modules/top-hybrid-sidebar-first.vue';
|
||||||
import ReversedHorizontalMixMenu from './modules/reversed-horizontal-mix-menu.vue';
|
import TopHybridHeaderFirst from './modules/top-hybrid-header-first.vue';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'GlobalMenu'
|
name: 'GlobalMenu'
|
||||||
@ -21,7 +21,8 @@ const activeMenu = computed(() => {
|
|||||||
vertical: VerticalMenu,
|
vertical: VerticalMenu,
|
||||||
'vertical-mix': VerticalMixMenu,
|
'vertical-mix': VerticalMixMenu,
|
||||||
horizontal: HorizontalMenu,
|
horizontal: HorizontalMenu,
|
||||||
'horizontal-mix': themeStore.layout.reverseHorizontalMix ? ReversedHorizontalMixMenu : HorizontalMixMenu
|
'top-hybrid-sidebar-first': TopHybridSidebarFirst,
|
||||||
|
'top-hybrid-header-first': TopHybridHeaderFirst
|
||||||
};
|
};
|
||||||
|
|
||||||
return menuMap[themeStore.layout.mode];
|
return menuMap[themeStore.layout.mode];
|
||||||
|
@ -13,9 +13,15 @@ const appStore = useAppStore();
|
|||||||
const themeStore = useThemeStore();
|
const themeStore = useThemeStore();
|
||||||
|
|
||||||
const isVerticalMix = computed(() => themeStore.layout.mode === 'vertical-mix');
|
const isVerticalMix = computed(() => themeStore.layout.mode === 'vertical-mix');
|
||||||
const isHorizontalMix = computed(() => themeStore.layout.mode === 'horizontal-mix');
|
const isTopHybridSidebarFirst = computed(() => themeStore.layout.mode === 'top-hybrid-sidebar-first');
|
||||||
const darkMenu = computed(() => !themeStore.darkMode && !isHorizontalMix.value && themeStore.sider.inverted);
|
const isTopHybridHeaderFirst = computed(() => themeStore.layout.mode === 'top-hybrid-header-first');
|
||||||
const showLogo = computed(() => !isVerticalMix.value && !isHorizontalMix.value);
|
const darkMenu = computed(
|
||||||
|
() =>
|
||||||
|
!themeStore.darkMode && !isTopHybridSidebarFirst.value && !isTopHybridHeaderFirst.value && themeStore.sider.inverted
|
||||||
|
);
|
||||||
|
const showLogo = computed(
|
||||||
|
() => !isVerticalMix.value && !isTopHybridSidebarFirst.value && !isTopHybridHeaderFirst.value
|
||||||
|
);
|
||||||
const menuWrapperClass = computed(() => (showLogo.value ? 'flex-1-hidden' : 'h-full'));
|
const menuWrapperClass = computed(() => (showLogo.value ? 'flex-1-hidden' : 'h-full'));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@ type LayoutConfig = Record<
|
|||||||
UnionKey.ThemeLayoutMode,
|
UnionKey.ThemeLayoutMode,
|
||||||
{
|
{
|
||||||
placement: PopoverPlacement;
|
placement: PopoverPlacement;
|
||||||
headerClass: string;
|
|
||||||
menuClass: string;
|
menuClass: string;
|
||||||
mainClass: string;
|
mainClass: string;
|
||||||
}
|
}
|
||||||
@ -36,25 +35,26 @@ type LayoutConfig = Record<
|
|||||||
const layoutConfig: LayoutConfig = {
|
const layoutConfig: LayoutConfig = {
|
||||||
vertical: {
|
vertical: {
|
||||||
placement: 'bottom',
|
placement: 'bottom',
|
||||||
headerClass: '',
|
|
||||||
menuClass: 'w-1/3 h-full',
|
menuClass: 'w-1/3 h-full',
|
||||||
mainClass: 'w-2/3 h-3/4'
|
mainClass: 'w-2/3 h-3/4'
|
||||||
},
|
},
|
||||||
'vertical-mix': {
|
'vertical-mix': {
|
||||||
placement: 'bottom',
|
placement: 'bottom',
|
||||||
headerClass: '',
|
|
||||||
menuClass: 'w-1/4 h-full',
|
menuClass: 'w-1/4 h-full',
|
||||||
mainClass: 'w-2/3 h-3/4'
|
mainClass: 'w-2/3 h-3/4'
|
||||||
},
|
},
|
||||||
horizontal: {
|
horizontal: {
|
||||||
placement: 'bottom',
|
placement: 'bottom',
|
||||||
headerClass: '',
|
|
||||||
menuClass: 'w-full h-1/4',
|
menuClass: 'w-full h-1/4',
|
||||||
mainClass: 'w-full h-3/4'
|
mainClass: 'w-full h-3/4'
|
||||||
},
|
},
|
||||||
'horizontal-mix': {
|
'top-hybrid-sidebar-first': {
|
||||||
|
placement: 'bottom',
|
||||||
|
menuClass: 'w-full h-1/4',
|
||||||
|
mainClass: 'w-2/3 h-3/4'
|
||||||
|
},
|
||||||
|
'top-hybrid-header-first': {
|
||||||
placement: 'bottom',
|
placement: 'bottom',
|
||||||
headerClass: '',
|
|
||||||
menuClass: 'w-full h-1/4',
|
menuClass: 'w-full h-1/4',
|
||||||
mainClass: 'w-2/3 h-3/4'
|
mainClass: 'w-2/3 h-3/4'
|
||||||
}
|
}
|
||||||
@ -68,25 +68,27 @@ function handleChangeMode(mode: UnionKey.ThemeLayoutMode) {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="grid grid-cols-3 gap-x-32px gap-y-16px">
|
<div class="grid grid-cols-2 gap-x-16px gap-y-12px md:grid-cols-3">
|
||||||
<div
|
<div
|
||||||
v-for="(item, key) in layoutConfig"
|
v-for="(item, key) in layoutConfig"
|
||||||
:key="key"
|
:key="key"
|
||||||
class="flex-center cursor-pointer border-2px rounded-6px hover:border-primary"
|
class="flex-col-center cursor-pointer"
|
||||||
:class="[mode === key ? 'border-primary' : 'border-transparent']"
|
|
||||||
@click="handleChangeMode(key)"
|
@click="handleChangeMode(key)"
|
||||||
>
|
>
|
||||||
<NTooltip :placement="item.placement">
|
<NTooltip :placement="item.placement">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<div
|
<div
|
||||||
class="h-64px w-96px gap-6px rd-4px p-6px shadow dark:shadow-coolGray-5"
|
class="h-64px w-96px gap-6px rd-4px p-6px shadow ring-2 ring-transparent transition-all hover:ring-primary"
|
||||||
:class="[key.includes('vertical') ? 'flex' : 'flex-col']"
|
:class="{ '!ring-primary': mode === key }"
|
||||||
>
|
>
|
||||||
<slot :name="key"></slot>
|
<div class="h-full w-full gap-1" :class="[key.includes('vertical') ? 'flex' : 'flex-col']">
|
||||||
|
<slot :name="key"></slot>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
{{ $t(themeLayoutModeRecord[key]) }}
|
{{ $t(`theme.layout.layoutMode.${key}_detail`) }}
|
||||||
</NTooltip>
|
</NTooltip>
|
||||||
|
<p class="mt-8px text-12px">{{ $t(themeLayoutModeRecord[key]) }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { useThemeStore } from '@/store/modules/theme';
|
||||||
import LayoutMode from './modules/layout-mode.vue';
|
import LayoutMode from './modules/layout-mode.vue';
|
||||||
import TabSettings from './modules/tab-settings.vue';
|
import TabSettings from './modules/tab-settings.vue';
|
||||||
import HeaderSettings from './modules/header-settings.vue';
|
import HeaderSettings from './modules/header-settings.vue';
|
||||||
@ -9,6 +10,8 @@ import ContentSettings from './modules/content-settings.vue';
|
|||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'LayoutSettings'
|
name: 'LayoutSettings'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const themeStore = useThemeStore();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -16,7 +19,8 @@ defineOptions({
|
|||||||
<LayoutMode />
|
<LayoutMode />
|
||||||
<TabSettings />
|
<TabSettings />
|
||||||
<HeaderSettings />
|
<HeaderSettings />
|
||||||
<SiderSettings />
|
<!-- The top menu mode does not have a sidebar -->
|
||||||
|
<SiderSettings v-if="themeStore.layout.mode !== 'horizontal'" />
|
||||||
<FooterSettings />
|
<FooterSettings />
|
||||||
<ContentSettings />
|
<ContentSettings />
|
||||||
</div>
|
</div>
|
||||||
|
@ -12,6 +12,9 @@ const themeStore = useThemeStore();
|
|||||||
|
|
||||||
const layoutMode = computed(() => themeStore.layout.mode);
|
const layoutMode = computed(() => themeStore.layout.mode);
|
||||||
const isWrapperScrollMode = computed(() => themeStore.layout.scrollMode === 'wrapper');
|
const isWrapperScrollMode = computed(() => themeStore.layout.scrollMode === 'wrapper');
|
||||||
|
const isMixHorizontalMode = computed(() =>
|
||||||
|
['top-hybrid-sidebar-first', 'top-hybrid-header-first'].includes(layoutMode.value)
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -31,7 +34,7 @@ const isWrapperScrollMode = computed(() => themeStore.layout.scrollMode === 'wra
|
|||||||
<NInputNumber v-model:value="themeStore.footer.height" size="small" :step="1" class="w-120px" />
|
<NInputNumber v-model:value="themeStore.footer.height" size="small" :step="1" class="w-120px" />
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
<SettingItem
|
<SettingItem
|
||||||
v-if="themeStore.footer.visible && layoutMode === 'horizontal-mix'"
|
v-if="themeStore.footer.visible && isMixHorizontalMode"
|
||||||
key="4"
|
key="4"
|
||||||
:label="$t('theme.layout.footer.right')"
|
:label="$t('theme.layout.footer.right')"
|
||||||
>
|
>
|
||||||
|
@ -3,7 +3,6 @@ import { useAppStore } from '@/store/modules/app';
|
|||||||
import { useThemeStore } from '@/store/modules/theme';
|
import { useThemeStore } from '@/store/modules/theme';
|
||||||
import { $t } from '@/locales';
|
import { $t } from '@/locales';
|
||||||
import LayoutModeCard from '../../../components/layout-mode-card.vue';
|
import LayoutModeCard from '../../../components/layout-mode-card.vue';
|
||||||
import SettingItem from '../../../components/setting-item.vue';
|
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'LayoutMode'
|
name: 'LayoutMode'
|
||||||
@ -11,56 +10,52 @@ defineOptions({
|
|||||||
|
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
const themeStore = useThemeStore();
|
const themeStore = useThemeStore();
|
||||||
|
|
||||||
function handleReverseHorizontalMixChange(value: boolean) {
|
|
||||||
themeStore.setLayoutReverseHorizontalMix(value);
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<NDivider>{{ $t('theme.layout.layoutMode.title') }}</NDivider>
|
<NDivider>{{ $t('theme.layout.layoutMode.title') }}</NDivider>
|
||||||
<LayoutModeCard v-model:mode="themeStore.layout.mode" :disabled="appStore.isMobile">
|
<LayoutModeCard v-model:mode="themeStore.layout.mode" :disabled="appStore.isMobile">
|
||||||
<template #vertical>
|
<template #vertical>
|
||||||
<div class="layout-sider h-full w-18px"></div>
|
<div class="layout-sider h-full w-18px !bg-primary"></div>
|
||||||
<div class="vertical-wrapper">
|
<div class="vertical-wrapper">
|
||||||
<div class="layout-header"></div>
|
<div class="layout-header bg-primary-200"></div>
|
||||||
<div class="layout-main"></div>
|
<div class="layout-main"></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #vertical-mix>
|
<template #vertical-mix>
|
||||||
<div class="layout-sider h-full w-8px"></div>
|
<div class="layout-sider h-full w-8px !bg-primary"></div>
|
||||||
<div class="layout-sider h-full w-16px"></div>
|
<div class="layout-sider h-full w-16px !bg-primary-300"></div>
|
||||||
<div class="vertical-wrapper">
|
<div class="vertical-wrapper">
|
||||||
<div class="layout-header"></div>
|
<div class="layout-header bg-primary-200"></div>
|
||||||
<div class="layout-main"></div>
|
<div class="layout-main"></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #horizontal>
|
<template #horizontal>
|
||||||
<div class="layout-header"></div>
|
<div class="layout-header !bg-primary"></div>
|
||||||
<div class="horizontal-wrapper">
|
<div class="horizontal-wrapper">
|
||||||
<div class="layout-main"></div>
|
<div class="layout-main"></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #horizontal-mix>
|
<template #top-hybrid-sidebar-first>
|
||||||
<div class="layout-header"></div>
|
<div class="layout-header !bg-primary-300"></div>
|
||||||
|
<div class="horizontal-wrapper">
|
||||||
|
<div class="layout-sider w-18px !bg-primary"></div>
|
||||||
|
<div class="layout-main"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #top-hybrid-header-first>
|
||||||
|
<div class="layout-header bg-primary"></div>
|
||||||
<div class="horizontal-wrapper">
|
<div class="horizontal-wrapper">
|
||||||
<div class="layout-sider w-18px"></div>
|
<div class="layout-sider w-18px"></div>
|
||||||
<div class="layout-main"></div>
|
<div class="layout-main"></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</LayoutModeCard>
|
</LayoutModeCard>
|
||||||
<SettingItem
|
|
||||||
v-if="themeStore.layout.mode === 'horizontal-mix'"
|
|
||||||
:label="$t('theme.layout.layoutMode.reverseHorizontalMix')"
|
|
||||||
class="mt-16px"
|
|
||||||
>
|
|
||||||
<NSwitch :value="themeStore.layout.reverseHorizontalMix" @update:value="handleReverseHorizontalMixChange" />
|
|
||||||
</SettingItem>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.layout-header {
|
.layout-header {
|
||||||
--uno: h-16px bg-primary rd-4px;
|
--uno: h-16px rd-4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-sider {
|
.layout-sider {
|
||||||
|
@ -11,7 +11,7 @@ defineOptions({
|
|||||||
const themeStore = useThemeStore();
|
const themeStore = useThemeStore();
|
||||||
|
|
||||||
const layoutMode = computed(() => themeStore.layout.mode);
|
const layoutMode = computed(() => themeStore.layout.mode);
|
||||||
const isMixLayoutMode = computed(() => layoutMode.value.includes('mix'));
|
const isMixLayoutMode = computed(() => layoutMode.value.includes('mix') || layoutMode.value.includes('hybrid'));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -88,11 +88,19 @@ const local: App.I18n.Schema = {
|
|||||||
layout: {
|
layout: {
|
||||||
layoutMode: {
|
layoutMode: {
|
||||||
title: 'Layout Mode',
|
title: 'Layout Mode',
|
||||||
vertical: 'Vertical Menu Mode',
|
vertical: 'Vertical Mode',
|
||||||
horizontal: 'Horizontal Menu Mode',
|
horizontal: 'Horizontal Mode',
|
||||||
'vertical-mix': 'Vertical Mix Menu Mode',
|
'vertical-mix': 'Vertical Mix Mode',
|
||||||
'horizontal-mix': 'Horizontal Mix menu Mode',
|
'top-hybrid-sidebar-first': 'Top-Hybrid Sidebar-First',
|
||||||
reverseHorizontalMix: 'Reverse first level menus and child level menus position'
|
'top-hybrid-header-first': 'Top-Hybrid Header-First',
|
||||||
|
vertical_detail: 'Vertical menu layout, with the menu on the left and content on the right.',
|
||||||
|
'vertical-mix_detail':
|
||||||
|
'Vertical mix-menu layout, with the primary menu on the dark left side and the secondary menu on the lighter right side.',
|
||||||
|
horizontal_detail: 'Horizontal menu layout, with the menu at the top and content below.',
|
||||||
|
'top-hybrid-sidebar-first_detail':
|
||||||
|
'Top hybrid layout, with the primary menu on the left and the secondary menu at the top.',
|
||||||
|
'top-hybrid-header-first_detail':
|
||||||
|
'Top hybrid layout, with the primary menu at the top and the secondary menu on the left.'
|
||||||
},
|
},
|
||||||
tab: {
|
tab: {
|
||||||
title: 'Tab Settings',
|
title: 'Tab Settings',
|
||||||
|
@ -91,8 +91,13 @@ const local: App.I18n.Schema = {
|
|||||||
vertical: '左侧菜单模式',
|
vertical: '左侧菜单模式',
|
||||||
'vertical-mix': '左侧菜单混合模式',
|
'vertical-mix': '左侧菜单混合模式',
|
||||||
horizontal: '顶部菜单模式',
|
horizontal: '顶部菜单模式',
|
||||||
'horizontal-mix': '顶部菜单混合模式',
|
'top-hybrid-sidebar-first': '顶部混合-侧边优先',
|
||||||
reverseHorizontalMix: '一级菜单与子级菜单位置反转'
|
'top-hybrid-header-first': '顶部混合-顶部优先',
|
||||||
|
vertical_detail: '左侧菜单布局,菜单在左,内容在右。',
|
||||||
|
'vertical-mix_detail': '左侧双菜单布局,一级菜单在左侧深色区域,二级菜单在右侧浅色区域。',
|
||||||
|
horizontal_detail: '顶部菜单布局,菜单在顶部,内容在下方。',
|
||||||
|
'top-hybrid-sidebar-first_detail': '顶部混合布局,一级菜单在左侧,二级菜单在顶部。',
|
||||||
|
'top-hybrid-header-first_detail': '顶部混合布局,一级菜单在顶部,二级菜单在左侧。'
|
||||||
},
|
},
|
||||||
tab: {
|
tab: {
|
||||||
title: '标签栏设置',
|
title: '标签栏设置',
|
||||||
|
@ -171,14 +171,6 @@ export const useThemeStore = defineStore(SetupStoreId.Theme, () => {
|
|||||||
);
|
);
|
||||||
addThemeVarsToGlobal(themeTokens, darkThemeTokens);
|
addThemeVarsToGlobal(themeTokens, darkThemeTokens);
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Set layout reverse horizontal mix
|
|
||||||
*
|
|
||||||
* @param reverse Reverse horizontal mix
|
|
||||||
*/
|
|
||||||
function setLayoutReverseHorizontalMix(reverse: boolean) {
|
|
||||||
settings.value.layout.reverseHorizontalMix = reverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set watermark enable user name
|
* Set watermark enable user name
|
||||||
@ -291,7 +283,6 @@ export const useThemeStore = defineStore(SetupStoreId.Theme, () => {
|
|||||||
toggleThemeScheme,
|
toggleThemeScheme,
|
||||||
updateThemeColors,
|
updateThemeColors,
|
||||||
setThemeLayout,
|
setThemeLayout,
|
||||||
setLayoutReverseHorizontalMix,
|
|
||||||
setWatermarkEnableUserName,
|
setWatermarkEnableUserName,
|
||||||
setWatermarkEnableTime
|
setWatermarkEnableTime
|
||||||
};
|
};
|
||||||
|
@ -15,8 +15,7 @@ export const themeSettings: App.Theme.ThemeSetting = {
|
|||||||
resetCacheStrategy: 'close',
|
resetCacheStrategy: 'close',
|
||||||
layout: {
|
layout: {
|
||||||
mode: 'vertical',
|
mode: 'vertical',
|
||||||
scrollMode: 'content',
|
scrollMode: 'content'
|
||||||
reverseHorizontalMix: false
|
|
||||||
},
|
},
|
||||||
page: {
|
page: {
|
||||||
animate: true,
|
animate: true,
|
||||||
|
24
src/typings/app.d.ts
vendored
24
src/typings/app.d.ts
vendored
@ -28,12 +28,6 @@ declare namespace App {
|
|||||||
mode: UnionKey.ThemeLayoutMode;
|
mode: UnionKey.ThemeLayoutMode;
|
||||||
/** Scroll mode */
|
/** Scroll mode */
|
||||||
scrollMode: UnionKey.ThemeScrollMode;
|
scrollMode: UnionKey.ThemeScrollMode;
|
||||||
/**
|
|
||||||
* Whether to reverse the horizontal mix
|
|
||||||
*
|
|
||||||
* if true, the vertical child level menus in left and horizontal first level menus in top
|
|
||||||
*/
|
|
||||||
reverseHorizontalMix: boolean;
|
|
||||||
};
|
};
|
||||||
/** Page */
|
/** Page */
|
||||||
page: {
|
page: {
|
||||||
@ -88,11 +82,14 @@ declare namespace App {
|
|||||||
width: number;
|
width: number;
|
||||||
/** Collapsed sider width */
|
/** Collapsed sider width */
|
||||||
collapsedWidth: number;
|
collapsedWidth: number;
|
||||||
/** Sider width when the layout is 'vertical-mix' or 'horizontal-mix' */
|
/** Sider width when the layout is 'vertical-mix', 'top-hybrid-sidebar-first', or 'top-hybrid-header-first' */
|
||||||
mixWidth: number;
|
mixWidth: number;
|
||||||
/** Collapsed sider width when the layout is 'vertical-mix' or 'horizontal-mix' */
|
/**
|
||||||
|
* Collapsed sider width when the layout is 'vertical-mix', 'top-hybrid-sidebar-first', or
|
||||||
|
* 'top-hybrid-header-first'
|
||||||
|
*/
|
||||||
mixCollapsedWidth: number;
|
mixCollapsedWidth: number;
|
||||||
/** Child menu width when the layout is 'vertical-mix' or 'horizontal-mix' */
|
/** Child menu width when the layout is 'vertical-mix', 'top-hybrid-sidebar-first', or 'top-hybrid-header-first' */
|
||||||
mixChildMenuWidth: number;
|
mixChildMenuWidth: number;
|
||||||
};
|
};
|
||||||
/** Footer */
|
/** Footer */
|
||||||
@ -103,7 +100,10 @@ declare namespace App {
|
|||||||
fixed: boolean;
|
fixed: boolean;
|
||||||
/** Footer height */
|
/** Footer height */
|
||||||
height: number;
|
height: number;
|
||||||
/** Whether float the footer to the right when the layout is 'horizontal-mix' */
|
/**
|
||||||
|
* Whether float the footer to the right when the layout is 'top-hybrid-sidebar-first' or
|
||||||
|
* 'top-hybrid-header-first'
|
||||||
|
*/
|
||||||
right: boolean;
|
right: boolean;
|
||||||
};
|
};
|
||||||
/** Watermark */
|
/** Watermark */
|
||||||
@ -380,7 +380,9 @@ declare namespace App {
|
|||||||
recommendColorDesc: string;
|
recommendColorDesc: string;
|
||||||
};
|
};
|
||||||
layout: {
|
layout: {
|
||||||
layoutMode: { title: string; reverseHorizontalMix: string } & Record<UnionKey.ThemeLayoutMode, string>;
|
layoutMode: { title: string } & Record<UnionKey.ThemeLayoutMode, string> & {
|
||||||
|
[K in `${UnionKey.ThemeLayoutMode}_detail`]: string;
|
||||||
|
};
|
||||||
tab: {
|
tab: {
|
||||||
title: string;
|
title: string;
|
||||||
visible: string;
|
visible: string;
|
||||||
|
20
src/typings/components.d.ts
vendored
20
src/typings/components.d.ts
vendored
@ -17,23 +17,14 @@ declare module 'vue' {
|
|||||||
FullScreen: typeof import('./../components/common/full-screen.vue')['default']
|
FullScreen: typeof import('./../components/common/full-screen.vue')['default']
|
||||||
IconAntDesignEnterOutlined: typeof import('~icons/ant-design/enter-outlined')['default']
|
IconAntDesignEnterOutlined: typeof import('~icons/ant-design/enter-outlined')['default']
|
||||||
IconAntDesignReloadOutlined: typeof import('~icons/ant-design/reload-outlined')['default']
|
IconAntDesignReloadOutlined: typeof import('~icons/ant-design/reload-outlined')['default']
|
||||||
IconAntDesignSettingOutlined: typeof import('~icons/ant-design/setting-outlined')['default']
|
|
||||||
IconGridiconsFullscreen: typeof import('~icons/gridicons/fullscreen')['default']
|
IconGridiconsFullscreen: typeof import('~icons/gridicons/fullscreen')['default']
|
||||||
IconGridiconsFullscreenExit: typeof import('~icons/gridicons/fullscreen-exit')['default']
|
IconGridiconsFullscreenExit: typeof import('~icons/gridicons/fullscreen-exit')['default']
|
||||||
'IconIc:roundPlus': typeof import('~icons/ic/round-plus')['default']
|
|
||||||
IconIcRoundDelete: typeof import('~icons/ic/round-delete')['default']
|
|
||||||
IconIcRoundPlus: typeof import('~icons/ic/round-plus')['default']
|
|
||||||
IconIcRoundRefresh: typeof import('~icons/ic/round-refresh')['default']
|
|
||||||
IconIcRoundRemove: typeof import('~icons/ic/round-remove')['default']
|
|
||||||
IconIcRoundSearch: typeof import('~icons/ic/round-search')['default']
|
|
||||||
IconLocalBanner: typeof import('~icons/local/banner')['default']
|
IconLocalBanner: typeof import('~icons/local/banner')['default']
|
||||||
IconLocalLogo: typeof import('~icons/local/logo')['default']
|
IconLocalLogo: typeof import('~icons/local/logo')['default']
|
||||||
IconMdiArrowDownThin: typeof import('~icons/mdi/arrow-down-thin')['default']
|
IconMdiArrowDownThin: typeof import('~icons/mdi/arrow-down-thin')['default']
|
||||||
IconMdiArrowUpThin: typeof import('~icons/mdi/arrow-up-thin')['default']
|
IconMdiArrowUpThin: typeof import('~icons/mdi/arrow-up-thin')['default']
|
||||||
IconMdiDrag: typeof import('~icons/mdi/drag')['default']
|
|
||||||
IconMdiKeyboardEsc: typeof import('~icons/mdi/keyboard-esc')['default']
|
IconMdiKeyboardEsc: typeof import('~icons/mdi/keyboard-esc')['default']
|
||||||
IconMdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default']
|
IconMdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default']
|
||||||
IconMdiRefresh: typeof import('~icons/mdi/refresh')['default']
|
|
||||||
IconUilSearch: typeof import('~icons/uil/search')['default']
|
IconUilSearch: typeof import('~icons/uil/search')['default']
|
||||||
LangSwitch: typeof import('./../components/common/lang-switch.vue')['default']
|
LangSwitch: typeof import('./../components/common/lang-switch.vue')['default']
|
||||||
LookForward: typeof import('./../components/custom/look-forward.vue')['default']
|
LookForward: typeof import('./../components/custom/look-forward.vue')['default']
|
||||||
@ -45,19 +36,14 @@ declare module 'vue' {
|
|||||||
NCard: typeof import('naive-ui')['NCard']
|
NCard: typeof import('naive-ui')['NCard']
|
||||||
NCheckbox: typeof import('naive-ui')['NCheckbox']
|
NCheckbox: typeof import('naive-ui')['NCheckbox']
|
||||||
NColorPicker: typeof import('naive-ui')['NColorPicker']
|
NColorPicker: typeof import('naive-ui')['NColorPicker']
|
||||||
NDataTable: typeof import('naive-ui')['NDataTable']
|
|
||||||
NDescriptions: typeof import('naive-ui')['NDescriptions']
|
|
||||||
NDescriptionsItem: typeof import('naive-ui')['NDescriptionsItem']
|
|
||||||
NDialogProvider: typeof import('naive-ui')['NDialogProvider']
|
NDialogProvider: typeof import('naive-ui')['NDialogProvider']
|
||||||
NDivider: typeof import('naive-ui')['NDivider']
|
NDivider: typeof import('naive-ui')['NDivider']
|
||||||
NDrawer: typeof import('naive-ui')['NDrawer']
|
NDrawer: typeof import('naive-ui')['NDrawer']
|
||||||
NDrawerContent: typeof import('naive-ui')['NDrawerContent']
|
NDrawerContent: typeof import('naive-ui')['NDrawerContent']
|
||||||
NDropdown: typeof import('naive-ui')['NDropdown']
|
NDropdown: typeof import('naive-ui')['NDropdown']
|
||||||
NDynamicInput: typeof import('naive-ui')['NDynamicInput']
|
|
||||||
NEmpty: typeof import('naive-ui')['NEmpty']
|
NEmpty: typeof import('naive-ui')['NEmpty']
|
||||||
NForm: typeof import('naive-ui')['NForm']
|
NForm: typeof import('naive-ui')['NForm']
|
||||||
NFormItem: typeof import('naive-ui')['NFormItem']
|
NFormItem: typeof import('naive-ui')['NFormItem']
|
||||||
NFormItemGi: typeof import('naive-ui')['NFormItemGi']
|
|
||||||
NGi: typeof import('naive-ui')['NGi']
|
NGi: typeof import('naive-ui')['NGi']
|
||||||
NGrid: typeof import('naive-ui')['NGrid']
|
NGrid: typeof import('naive-ui')['NGrid']
|
||||||
NInput: typeof import('naive-ui')['NInput']
|
NInput: typeof import('naive-ui')['NInput']
|
||||||
@ -70,10 +56,6 @@ declare module 'vue' {
|
|||||||
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
|
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
|
||||||
NModal: typeof import('naive-ui')['NModal']
|
NModal: typeof import('naive-ui')['NModal']
|
||||||
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
|
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
|
||||||
NPopconfirm: typeof import('naive-ui')['NPopconfirm']
|
|
||||||
NPopover: typeof import('naive-ui')['NPopover']
|
|
||||||
NRadio: typeof import('naive-ui')['NRadio']
|
|
||||||
NRadioGroup: typeof import('naive-ui')['NRadioGroup']
|
|
||||||
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
||||||
NSelect: typeof import('naive-ui')['NSelect']
|
NSelect: typeof import('naive-ui')['NSelect']
|
||||||
NSpace: typeof import('naive-ui')['NSpace']
|
NSpace: typeof import('naive-ui')['NSpace']
|
||||||
@ -81,10 +63,8 @@ declare module 'vue' {
|
|||||||
NSwitch: typeof import('naive-ui')['NSwitch']
|
NSwitch: typeof import('naive-ui')['NSwitch']
|
||||||
NTab: typeof import('naive-ui')['NTab']
|
NTab: typeof import('naive-ui')['NTab']
|
||||||
NTabs: typeof import('naive-ui')['NTabs']
|
NTabs: typeof import('naive-ui')['NTabs']
|
||||||
NTag: typeof import('naive-ui')['NTag']
|
|
||||||
NThing: typeof import('naive-ui')['NThing']
|
NThing: typeof import('naive-ui')['NThing']
|
||||||
NTooltip: typeof import('naive-ui')['NTooltip']
|
NTooltip: typeof import('naive-ui')['NTooltip']
|
||||||
NTree: typeof import('naive-ui')['NTree']
|
|
||||||
NWatermark: typeof import('naive-ui')['NWatermark']
|
NWatermark: typeof import('naive-ui')['NWatermark']
|
||||||
PinToggler: typeof import('./../components/common/pin-toggler.vue')['default']
|
PinToggler: typeof import('./../components/common/pin-toggler.vue')['default']
|
||||||
ReloadButton: typeof import('./../components/common/reload-button.vue')['default']
|
ReloadButton: typeof import('./../components/common/reload-button.vue')['default']
|
||||||
|
10
src/typings/union-key.d.ts
vendored
10
src/typings/union-key.d.ts
vendored
@ -28,9 +28,15 @@ declare namespace UnionKey {
|
|||||||
* - vertical: the vertical menu in left
|
* - vertical: the vertical menu in left
|
||||||
* - horizontal: the horizontal menu in top
|
* - horizontal: the horizontal menu in top
|
||||||
* - vertical-mix: two vertical mixed menus in left
|
* - vertical-mix: two vertical mixed menus in left
|
||||||
* - horizontal-mix: the vertical first level menus in left and horizontal child level menus in top
|
* - top-hybrid-sidebar-first: the vertical first level menus in left and horizontal child level menus in top
|
||||||
|
* - top-hybrid-header-first: the horizontal first level menus in top and vertical child level menus in left
|
||||||
*/
|
*/
|
||||||
type ThemeLayoutMode = 'vertical' | 'horizontal' | 'vertical-mix' | 'horizontal-mix';
|
type ThemeLayoutMode =
|
||||||
|
| 'vertical'
|
||||||
|
| 'horizontal'
|
||||||
|
| 'vertical-mix'
|
||||||
|
| 'top-hybrid-sidebar-first'
|
||||||
|
| 'top-hybrid-header-first';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The scroll mode when content overflow
|
* The scroll mode when content overflow
|
||||||
|
Loading…
Reference in New Issue
Block a user