refactor(ui): 界面升级与代码规范优化

This commit is contained in:
Ray.Hao
2026-06-18 18:38:12 +08:00
parent 288ea9b43d
commit 14035cfa4d
130 changed files with 7813 additions and 5893 deletions

View File

@@ -0,0 +1,359 @@
<template>
<BaseLayout>
<aside
v-show="!appStore.contentFullscreen"
class="layout__double-sidebar"
:class="{ 'layout__double-sidebar--collapsed': !isSidebarOpen }"
>
<div class="layout__double-primary">
<LayoutLogo v-if="showLogo" :collapse="true" />
<el-scrollbar class="layout__double-primary-scroll">
<button
v-for="item in topMenuItems"
:key="item.path"
class="layout__primary-item"
:class="{ 'is-active': item.path === activeTopMenuPath }"
:title="item.meta?.title ? translateRouteTitle(item.meta.title) : undefined"
type="button"
@click="handleTopMenuSelect(item.path)"
>
<MenuIcon :icon="item.meta?.icon" />
<span v-if="item.meta?.title">{{ translateRouteTitle(item.meta.title) }}</span>
</button>
</el-scrollbar>
<button
class="layout__primary-toggle"
:title="isSidebarOpen ? '收起菜单' : '展开菜单'"
type="button"
@click="toggleSidebar"
>
<svg
class="layout__primary-toggle-icon"
:class="{ 'is-collapsed': !isSidebarOpen }"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
d="M12 5l-5 5 5 5"
fill="none"
stroke="currentColor"
stroke-width="1.8"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
</div>
<div class="layout__double-secondary">
<div v-if="showLogo" class="layout__double-title">
{{ appConfig.title }}
</div>
<el-scrollbar class="layout__double-secondary-scroll">
<LayoutSidebar
:data="sideMenuRoutes"
:base-path="activeTopMenuPath"
:always-expand="true"
/>
</el-scrollbar>
</div>
</aside>
<main
class="layout__main"
:class="{
hasTagsView: showTagsView,
'layout__main--collapsed': !isSidebarOpen,
'layout__main--fullscreen': appStore.contentFullscreen,
}"
>
<LayoutNavbar v-show="!appStore.contentFullscreen" />
<LayoutTagsView v-if="showTagsView" />
<LayoutMain />
</main>
</BaseLayout>
</template>
<script setup lang="ts">
import { useLayout } from "./useLayout";
import { useMixMenu } from "./composables/useMixMenu";
import { useAppStore } from "@/stores";
import { appConfig } from "@/settings";
import { translateRouteTitle } from "@/lang/utils";
import BaseLayout from "./BaseLayout.vue";
import LayoutLogo from "./components/LayoutLogo.vue";
import LayoutNavbar from "./components/LayoutNavbar.vue";
import LayoutTagsView from "./components/LayoutTagsView.vue";
import LayoutMain from "./components/LayoutMain.vue";
import LayoutSidebar from "./components/LayoutSidebar.vue";
const appStore = useAppStore();
const { showTagsView, showLogo, isSidebarOpen, toggleSidebar } = useLayout();
const { MenuIcon, topMenuItems, activeTopMenuPath, sideMenuRoutes, handleTopMenuSelect } =
useMixMenu();
</script>
<style lang="scss" scoped>
@use "@/styles/mixins" as *;
$double-sidebar-width: $sidebar-primary-width + $sidebar-secondary-width;
.layout {
&__double-sidebar {
position: fixed;
top: 0;
bottom: 0;
left: 0;
z-index: 999;
display: flex;
width: $double-sidebar-width;
overflow: hidden;
background-color: var(--menu-background);
border-right: 1px solid var(--menu-border);
transition: width 0.28s;
&--collapsed {
width: $sidebar-width-collapsed + $sidebar-secondary-width;
.layout__double-primary {
flex-basis: $sidebar-width-collapsed;
width: $sidebar-width-collapsed;
}
.layout__primary-item {
gap: 0;
min-height: 48px;
padding: 8px 4px;
span {
display: none;
}
}
.layout__primary-toggle-icon {
transform: rotate(180deg);
}
.layout__double-secondary {
flex: 0 0 $sidebar-secondary-width;
width: $sidebar-secondary-width;
min-width: $sidebar-secondary-width;
border-right: 1px solid var(--menu-border);
}
}
}
&__double-primary {
display: flex;
flex: 0 0 $sidebar-primary-width;
flex-direction: column;
width: $sidebar-primary-width;
overflow: hidden;
background:
linear-gradient(
180deg,
color-mix(in srgb, var(--menu-background) 94%, var(--el-color-primary) 6%),
var(--menu-background)
),
var(--menu-background);
border-right: 1px solid var(--menu-border);
transition:
flex-basis 0.28s,
width 0.28s;
:deep(.logo) {
height: $navbar-height;
background-color: transparent;
}
}
&__double-primary-scroll {
flex: 1;
min-height: 0;
}
&__primary-item {
position: relative;
display: flex;
flex-direction: column;
gap: 6px;
align-items: center;
justify-content: center;
width: calc(100% - 12px);
min-height: 64px;
padding: 8px 4px;
margin: 6px;
font: inherit;
font-size: 12px;
line-height: 1.2;
color: var(--menu-text);
cursor: pointer;
background: transparent;
border: 0;
border-radius: 8px;
transition:
color 0.18s,
background-color 0.18s;
:deep(.el-icon),
:deep([class^="i-svg:"]) {
width: 20px;
height: 20px;
font-size: 20px;
color: currentcolor !important;
}
span {
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
text-align: center;
white-space: nowrap;
}
&:hover {
color: var(--menu-active-text);
background-color: var(--menu-hover);
}
&.is-active {
color: var(--menu-active-text);
background-color: var(--menu-active-bg);
}
&:focus-visible {
outline: none;
background-color: var(--menu-hover);
}
}
&__primary-toggle {
display: flex;
flex: 0 0 48px;
align-items: center;
justify-content: center;
width: 100%;
padding: 0;
font: inherit;
color: var(--menu-text);
cursor: pointer;
background: transparent;
border: none;
border-top: 1px solid var(--menu-border);
transition:
color 0.18s,
background-color 0.18s;
&:hover {
color: var(--menu-active-text);
background-color: var(--menu-hover);
}
}
&__primary-toggle-icon {
width: 16px;
height: 16px;
transition: transform 0.28s;
&.is-collapsed {
transform: rotate(180deg);
}
}
&__double-secondary {
display: flex;
flex: 0 0 auto;
flex-direction: column;
width: $sidebar-secondary-width;
min-width: 0;
overflow: hidden;
background-color: var(--menu-background);
transition: width 0.28s;
:deep(.el-menu) {
border: none;
}
/* 恢复 .hideSidebar 被隐藏的文字(第二列始终展开) */
:deep(.el-menu-item span),
:deep(.el-sub-menu__title span) {
visibility: visible !important;
width: auto !important;
height: auto !important;
overflow: visible !important;
}
:deep(.el-sub-menu__icon-arrow) {
display: inline-flex !important;
}
}
&__double-secondary-scroll {
flex: 1;
min-height: 0;
}
&__double-title {
display: flex;
flex: 0 0 $navbar-height;
align-items: center;
min-width: $sidebar-secondary-width;
padding: 0 18px;
font-size: 16px;
font-weight: 600;
color: var(--sidebar-logo-text-color);
white-space: nowrap;
}
&__main {
position: relative;
height: 100%;
margin-left: $double-sidebar-width;
overflow-y: auto;
transition: margin-left 0.28s;
&--collapsed {
margin-left: $sidebar-width-collapsed + $sidebar-secondary-width;
}
&--fullscreen {
margin-left: 0 !important;
}
}
}
.hasTagsView {
:deep(.app-main) {
@include app-main-height-with-tags;
}
}
.mobile {
.layout__double-sidebar {
width: $double-sidebar-width;
transition:
transform 0.28s,
width 0s;
}
&.hideSidebar {
.layout__double-sidebar {
transform: translateX(-$double-sidebar-width);
}
}
&.openSidebar {
.layout__double-sidebar {
transform: translateX(0);
}
}
.layout__main {
margin-left: 0 !important;
}
}
</style>

View File

@@ -45,7 +45,7 @@ const appStore = useAppStore();
</script>
<style lang="scss" scoped>
@use "@/styles/base/mixins" as *;
@use "@/styles/mixins" as *;
.layout {
&__sidebar {

View File

@@ -89,7 +89,6 @@ import LayoutMain from "./components/LayoutMain.vue";
import LayoutSidebarItem from "./components/LayoutSidebarItem.vue";
import Hamburger from "@/components/Hamburger/index.vue";
import variables from "@/styles/variables.module.scss";
const { width } = useWindowSize();
const appStore = useAppStore();
@@ -123,7 +122,7 @@ const useMenuColors = computed(
</script>
<style lang="scss" scoped>
@use "@/styles/base/mixins" as *;
@use "@/styles/mixins" as *;
.layout {
&__header {
@@ -133,8 +132,7 @@ const useMenuColors = computed(
width: 100%;
height: $navbar-height;
background-color: var(--menu-background);
border-bottom: 1px solid var(--card-border);
box-shadow: 0 1px 3px 0 rgb(0 0 0 / 6%);
border-bottom: 1px solid var(--menu-border);
&-content {
display: flex;
@@ -167,16 +165,33 @@ const useMenuColors = computed(
:deep(.el-menu--horizontal) {
display: flex;
gap: 4px;
align-items: center;
height: 100%;
.el-menu-item {
position: relative;
height: 100%;
padding: 0 12px;
line-height: $navbar-height;
border-bottom: none;
border-radius: 0;
transition:
color 0.16s ease,
background-color 0.16s ease,
border-color 0.16s ease;
&:hover {
background-color: var(--menu-hover) !important;
}
&.is-active {
background-color: rgba(255, 255, 255, 0.12);
color: var(--el-color-primary) !important;
background-color: color-mix(
in srgb,
var(--el-color-primary) 10%,
var(--el-bg-color-overlay)
) !important;
border-bottom: 2px solid var(--el-color-primary);
}
}
@@ -202,7 +217,7 @@ const useMenuColors = computed(
width: $sidebar-width;
height: 100%;
background-color: var(--menu-background);
border-right: 1px solid var(--card-border);
border-right: 1px solid var(--menu-border);
transition: width 0.28s;
&.layout__sidebar--collapsed {
@@ -228,7 +243,7 @@ const useMenuColors = computed(
height: $sidebar-toggle-height;
line-height: $sidebar-toggle-height;
background-color: var(--menu-background);
box-shadow: 0 0 6px -2px var(--el-color-primary);
border-top: 1px solid var(--menu-border);
}
}
@@ -267,4 +282,20 @@ const useMenuColors = computed(
@include app-main-height-with-tags;
}
}
:global(html.dark),
:global(html.sidebar-color-blue) {
.layout__header-menu {
:deep(.el-menu--horizontal) {
.el-menu-item.is-active {
color: var(--menu-active-text) !important;
background-color: color-mix(
in srgb,
var(--el-color-primary) 18%,
var(--menu-background)
) !important;
}
}
}
}
</style>

View File

@@ -49,7 +49,7 @@ const isLogoCollapsed = computed(() => width.value < 768);
</script>
<style lang="scss" scoped>
@use "@/styles/base/mixins" as *;
@use "@/styles/mixins" as *;
.layout {
&__header {

View File

@@ -33,10 +33,10 @@ function toggleSideBar() {
align-items: center;
justify-content: space-between;
height: $navbar-height;
padding: 0 16px 0 4px;
padding: 0 14px 0 6px;
background-color: var(--content-bg);
border-bottom: 1px solid var(--card-border);
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 3%);
box-shadow: 0 1px 0 rgb(15 23 42 / 3%);
&__actions {
display: flex;

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
<el-menu
ref="menuRef"
:default-active="activeMenuPath"
:collapse="!appStore.sidebar.opened"
:collapse="props.alwaysExpand ? false : !appStore.sidebar.opened"
:background-color="menuThemeProps.backgroundColor"
:text-color="menuThemeProps.textColor"
:active-text-color="menuThemeProps.activeTextColor"
@@ -34,7 +34,6 @@ import { useSettingsStore, useAppStore } from "@/stores";
import { isExternal } from "@/utils/index";
import LayoutSidebarItem from "./LayoutSidebarItem.vue";
import variables from "@/styles/variables.module.scss";
const props = defineProps({
data: {
type: Array as PropType<RouteRecordRaw[]>,
@@ -50,6 +49,11 @@ const props = defineProps({
default: "vertical",
validator: (value: string) => ["vertical", "horizontal"].includes(value),
},
/** 强制展开,忽略全局 sidebar.opened 状态DoubleLayout 第二列需要始终展开) */
alwaysExpand: {
type: Boolean,
default: false,
},
});
const menuRef = ref<MenuInstance>();

View File

@@ -284,11 +284,11 @@ html.sidebar-color-blue {
// 深色主题下的父菜单激活状态"
html.dark & {
&.has-active-child > .el-sub-menu__title {
color: var(--el-color-primary-light-3) !important;
background-color: rgba(64, 128, 255, 0.15) !important;
color: var(--menu-active-text) !important;
background-color: var(--menu-active-bg) !important;
.menu-icon {
color: var(--el-color-primary-light-3) !important;
color: var(--menu-active-text) !important;
}
}
}
@@ -296,11 +296,11 @@ html.sidebar-color-blue {
// 深蓝色侧边栏配色下的父菜单激活状态"
html.sidebar-color-blue & {
&.has-active-child > .el-sub-menu__title {
color: var(--el-color-primary-light-3) !important;
background-color: rgba(64, 128, 255, 0.2) !important;
color: var(--menu-active-text) !important;
background-color: var(--menu-active-bg) !important;
.menu-icon {
color: var(--el-color-primary-light-3) !important;
color: var(--menu-active-text) !important;
}
}
}

View File

@@ -1,5 +1,5 @@
<template>
<div class="tags-container">
<div :class="['tags-container', tagsStyleClass]">
<!-- 页签滚动区 -->
<el-scrollbar
ref="scrollbarRef"
@@ -129,8 +129,10 @@
<script setup lang="ts">
import { useRoute, useRouter, type RouteRecordRaw } from "vue-router";
import { resolve } from "path-browserify";
import { TagsViewStyle } from "@/enums";
import { translateRouteTitle } from "@/lang/utils";
import { useAppStore, usePermissionStore, useTagsViewStore } from "@/stores";
import { useAppStore, usePermissionStore, useSettingsStore, useTagsViewStore } from "@/stores";
import type { TagView } from "@/stores/tags-view";
interface ContextMenu {
visible: boolean;
@@ -143,6 +145,7 @@ const route = useRoute();
const appStore = useAppStore();
const permissionStore = usePermissionStore();
const settingsStore = useSettingsStore();
const tagsViewStore = useTagsViewStore();
const { visitedViews } = storeToRefs(tagsViewStore);
@@ -161,6 +164,16 @@ const currentTag = computed(() => {
return visitedViews.value.find((tag) => tagsViewStore.isActive(tag)) || null;
});
const tagsStyleClass = computed(() => {
switch (settingsStore.tagsViewStyle) {
case TagsViewStyle.CARD:
return "tags-container--card";
case TagsViewStyle.LINE:
default:
return "tags-container--line";
}
});
// 图标兼容:判断是否为 Element Plus 图标 (el-icon-xxx)
const isEpIcon = (icon: string) => icon.startsWith("el-icon");
@@ -338,7 +351,8 @@ const handleScroll = (event: WheelEvent) => {
const hasHorizontalScroll = scrollWrapper.scrollWidth > scrollWrapper.clientWidth;
if (!hasHorizontalScroll) return;
const deltaY = event.deltaY || -(event as any).wheelDelta || 0;
const legacyEvent = event as WheelEvent & { wheelDelta?: number };
const deltaY = event.deltaY || -(legacyEvent.wheelDelta ?? 0);
const newScrollLeft = scrollWrapper.scrollLeft + deltaY;
scrollbarRef.value.setScrollLeft(newScrollLeft);
@@ -358,7 +372,7 @@ const refreshSelectedTag = (tag: TagView | null) => {
const closeSelectedTag = (tag: TagView | null) => {
if (!tag) return;
tagsViewStore.delView(tag).then((result: any) => {
tagsViewStore.delView(tag).then((result) => {
if (tagsViewStore.isActive(tag)) {
tagsViewStore.toLastView(result.visitedViews, tag);
}
@@ -421,7 +435,7 @@ const closeOtherTags = () => {
// 关闭所有标签页
const closeAllTags = (tag: TagView | null) => {
tagsViewStore.delAllViews().then((result: any) => {
tagsViewStore.delAllViews().then((result) => {
tagsViewStore.toLastView(result.visitedViews, tag || undefined);
});
};
@@ -475,9 +489,9 @@ useContextMenuManager();
align-items: center;
width: 100%;
height: $tags-view-height;
padding: 0 4px 0 8px;
padding: 0 12px;
background-color: var(--content-bg);
border-bottom: 1px solid var(--border-color);
border-bottom: 1px solid var(--card-border);
}
.scroll-container {
@@ -496,31 +510,30 @@ useContextMenuManager();
.tags-wrapper {
display: flex;
gap: 6px;
gap: 4px;
align-items: center;
height: 100%;
}
// ============================================
// 标签项
// 未激活: 透明底,融入白色容器背景
// 激活: 浅主色底 + 边框,从背景中"跳"出来
// ============================================
.tags-item {
position: relative;
display: inline-flex;
flex-shrink: 0;
gap: 6px;
align-items: center;
height: 30px;
padding: 0 14px;
height: 26px;
padding: 0 12px;
font-size: 13px;
color: var(--el-text-color-regular);
cursor: pointer;
user-select: none;
background: transparent;
border: 1px solid transparent;
border-radius: 8px;
background: #f8fafc;
border: 1px solid var(--card-border);
border-radius: 2px;
transition:
color 0.15s ease,
background-color 0.15s ease,
@@ -562,10 +575,10 @@ useContextMenuManager();
}
}
// 悬浮态 — 浅灰底浮现
&:hover {
color: var(--el-text-color-primary);
background-color: var(--el-fill-color-light);
background-color: var(--content-bg);
border-color: var(--el-border-color);
.tags-item__close {
opacity: 1;
@@ -576,12 +589,11 @@ useContextMenuManager();
}
}
// 激活态 — 浅主色块突出显示
&.is-active {
font-weight: 500;
color: var(--el-color-primary);
background-color: var(--el-color-primary-light-9);
border-color: var(--el-color-primary-light-7);
background-color: var(--content-bg);
border-color: var(--el-color-primary-light-5);
.tags-item__icon {
color: var(--el-color-primary);
@@ -606,6 +618,78 @@ useContextMenuManager();
}
}
.tags-container--line {
.tags-wrapper {
gap: 8px;
}
.tags-item {
height: 100%;
padding: 0 8px;
color: var(--el-text-color-secondary);
background: transparent;
border: 0;
border-radius: 0;
&::after {
position: absolute;
right: 6px;
bottom: 0;
left: 6px;
height: 2px;
content: "";
background: var(--el-color-primary);
transform: scaleX(0);
transform-origin: center;
transition: transform 0.16s ease;
}
&:hover {
color: var(--el-text-color-primary);
background: var(--el-fill-color-lighter);
border-color: transparent;
border-radius: 4px 4px 0 0;
}
&.is-active {
color: var(--el-color-primary);
background: transparent;
border-color: transparent;
&::after {
transform: scaleX(1);
}
}
}
}
.tags-container--card {
.tags-wrapper {
gap: 8px;
}
.tags-item {
height: 28px;
padding: 0 10px;
color: var(--el-text-color-secondary);
background: transparent;
border-color: transparent;
border-radius: 4px;
&:hover {
color: var(--el-text-color-primary);
background: var(--el-fill-color-lighter);
border-color: transparent;
}
&.is-active {
color: var(--el-color-primary);
background: var(--el-color-primary-light-9);
border-color: var(--el-color-primary-light-6);
}
}
}
// ============================================
// 右侧操作按钮
// ============================================
@@ -613,23 +697,23 @@ useContextMenuManager();
.tags-actions {
display: flex;
flex-shrink: 0;
gap: 2px;
gap: 4px;
align-items: center;
height: 100%;
padding-left: 4px;
padding-left: 8px;
&__btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
width: 30px;
height: 30px;
cursor: pointer;
border-radius: 6px;
transition: background-color 0.15s ease;
&:hover {
background-color: var(--el-fill-color-light);
background-color: var(--el-fill-color);
}
:deep(.el-icon),

View File

@@ -178,23 +178,27 @@ function handleSettingsClick() {
<style lang="scss" scoped>
.navbar-actions {
display: flex;
gap: 4px;
align-items: center;
min-height: 44px;
min-height: 32px;
&__item {
position: relative;
display: flex;
align-items: center;
justify-content: center;
min-width: 44px; /* 增加最小点击区域到44px符合人机交互标准 */
height: 44px;
padding: 0 8px;
min-width: 32px;
height: 32px;
padding: 0 6px;
text-align: center;
cursor: pointer;
transition: all 0.3s;
border-radius: 8px;
transition:
background-color 0.16s,
color 0.16s;
// 只对需要居中的子元素生效,不使用通配符避免影响选择器组件
> [class^="i-svg:"] {
> [class*="i-svg:"] {
display: flex;
align-items: center;
justify-content: center;
@@ -207,7 +211,7 @@ function handleSettingsClick() {
align-items: center;
justify-content: center;
width: 100%;
height: 44px;
height: 32px;
}
:deep(.i-svg\:language) {
@@ -220,7 +224,7 @@ function handleSettingsClick() {
}
// 图标样式
:deep([class^="i-svg:"]) {
:deep([class*="i-svg:"]) {
font-size: 16px;
line-height: 1;
color: var(--el-text-color-secondary);
@@ -228,9 +232,9 @@ function handleSettingsClick() {
}
&:hover {
background: var(--el-fill-color-light);
background: var(--el-fill-color);
:deep([class^="i-svg:"]) {
:deep([class*="i-svg:"]) {
color: var(--el-color-primary);
}
}
@@ -240,8 +244,8 @@ function handleSettingsClick() {
display: flex;
align-items: center;
justify-content: center;
height: 44px;
padding: 0 8px;
height: 32px;
padding: 0 6px 0 2px;
&__avatar {
flex-shrink: 0;
@@ -252,6 +256,7 @@ function handleSettingsClick() {
&__name {
margin-left: 8px;
font-size: 13px;
color: var(--el-text-color-regular);
white-space: nowrap;
transition: color 0.3s;
@@ -262,14 +267,14 @@ function handleSettingsClick() {
// 白色文字样式(用于深色背景:暗黑主题、顶部布局、混合布局等)
.navbar-actions--white-text {
.navbar-actions__item {
:deep([class^="i-svg:"]) {
:deep([class*="i-svg:"]) {
color: color-mix(in srgb, var(--el-color-white) 85%, transparent);
}
&:hover {
background: color-mix(in srgb, var(--el-color-white) 10%, transparent);
:deep([class^="i-svg:"]) {
:deep([class*="i-svg:"]) {
color: var(--el-color-white);
}
}
@@ -298,14 +303,14 @@ function handleSettingsClick() {
// 深色文字样式(用于浅色背景:明亮主题下的左侧布局等)
.navbar-actions--dark-text {
.navbar-actions__item {
:deep([class^="i-svg:"]) {
:deep([class*="i-svg:"]) {
color: var(--el-text-color-secondary) !important;
}
&:hover {
background: rgba(0, 0, 0, 0.04);
:deep([class^="i-svg:"]) {
:deep([class*="i-svg:"]) {
color: var(--el-color-primary) !important;
}
}
@@ -333,7 +338,7 @@ function handleSettingsClick() {
// 确保下拉菜单中的图标不受影响
::v-deep(.el-dropdown-menu) {
[class^="i-svg:"] {
[class*="i-svg:"] {
color: var(--el-text-color-regular) !important;
&:hover {

View File

@@ -12,6 +12,7 @@ import { LayoutMode } from "@/enums/settings";
import LeftLayout from "./LeftLayout.vue";
import TopLayout from "./TopLayout.vue";
import MixLayout from "./MixLayout.vue";
import DoubleLayout from "./DoubleLayout.vue";
import Settings from "./components/LayoutSettings.vue";
const route = useRoute();
@@ -26,6 +27,8 @@ const currentLayoutComponent = computed(() => {
return TopLayout;
case LayoutMode.MIX:
return MixLayout;
case LayoutMode.DOUBLE:
return DoubleLayout;
default:
return LeftLayout;
}