main
vue 161 lines 3.78 KB
Raw
1 <template>
2 <div
3 id="app-main"
4 class="main"
5 :class="{ 'sidebar-collapsed': sidebarCollapsed, 'sidebar-opened': !sidebarCollapsed }"
6 >
7 <n-scrollbar
8 ref="scrollbar"
9 trigger="none"
10 :y-placement="isRTL ? 'left' : 'right'"
11 content-class="flex min-h-full flex-col"
12 :theme-overrides="{
13 railInsetVerticalRight: `${toolbarHeight}px 4px 4px auto`,
14 railInsetVerticalLeft: `${toolbarHeight}px auto 4px 4px`
15 }"
16 >
17 <Toolbar :boxed="toolbarBoxed" gradient="body" />
18 <div
19 id="app-view"
20 class="view"
21 :class="{ boxed, 'view-padded': overridePadded === true, 'view-no-padded': overridePadded === false }"
22 >
23 <slot />
24 </div>
25 <MainFooter v-if="footerShown" :boxed />
26 </n-scrollbar>
27 </div>
28 </template>
29
30 <script lang="ts" setup>
31 import type { RouteLocationNormalizedGeneric } from "vue-router"
32 import { NScrollbar } from "naive-ui"
33 import { computed, onMounted, ref } from "vue"
34 import { useRoute, useRouter } from "vue-router"
35 import MainFooter from "@/app-layouts/common/MainFooter.vue"
36 import Toolbar from "@/app-layouts/common/Toolbar"
37 import { useThemeStore } from "@/stores/theme"
38
39 const themeStore = useThemeStore()
40 const router = useRouter()
41 const route = useRoute()
42 const sidebarCollapsed = computed(() => themeStore.sidebar.collapsed)
43 const footerShown = computed(() => themeStore.isFooterShown)
44 const themeBoxed = computed<boolean>(() => themeStore.isBoxed)
45 const overrideBoxed = ref<boolean | undefined>(undefined)
46 const overridePadded = ref<boolean | undefined>(undefined)
47 const boxed = computed<boolean>(() => (overrideBoxed.value !== undefined ? overrideBoxed.value : themeBoxed.value))
48 const isRTL = computed<boolean>(() => themeStore.isRTL)
49 const toolbarBoxed = computed(() => themeStore.isToolbarBoxed)
50 const toolbarHeight = computed(() => themeStore.toolbarHeight)
51 const scrollbar = ref()
52
53 function checkThemeOverrides(currentRoute: RouteLocationNormalizedGeneric) {
54 if (currentRoute.meta?.theme?.boxed?.enabled !== undefined) {
55 overrideBoxed.value = currentRoute.meta.theme.boxed.enabled
56 } else {
57 overrideBoxed.value = undefined
58 }
59
60 if (currentRoute.meta?.theme?.padded?.enabled !== undefined) {
61 overridePadded.value = currentRoute.meta.theme.padded.enabled
62 } else {
63 overridePadded.value = undefined
64 }
65 }
66
67 router.beforeEach(checkThemeOverrides)
68
69 onMounted(() => {
70 checkThemeOverrides(route)
71
72 router.afterEach(() => {
73 if (scrollbar?.value?.scrollTo) {
74 scrollbar?.value.scrollTo({ top: 0, behavior: "smooth" })
75 }
76 })
77 })
78 </script>
79
80 <style lang="scss" scoped>
81 @import "./variables";
82
83 .main {
84 width: 100%;
85 position: relative;
86 padding-left: var(--sidebar-open-width);
87 background-color: var(--bg-body-color);
88 transition: all var(--sidebar-anim-ease) var(--sidebar-anim-duration);
89 display: flex;
90 flex-direction: column;
91
92 &.sidebar-collapsed {
93 padding-left: var(--sidebar-close-width);
94 }
95
96 .view {
97 padding: 0 var(--view-padding);
98 flex-grow: 1;
99 width: 100%;
100 margin: 0 auto;
101 display: flex;
102 flex-direction: column;
103
104 &.boxed {
105 max-width: var(--boxed-width);
106 }
107 &.view-no-padded {
108 padding: 0;
109 }
110 }
111
112 @media (max-width: $sidebar-bp) {
113 padding-left: 0px;
114
115 &.sidebar-collapsed {
116 padding-left: 0px;
117 }
118
119 &.sidebar-opened {
120 /*
121 transform: scale(0.8) translateX(100%) rotateY(35deg);
122 transform-origin: center left;
123 border-radius: 16px;
124 */
125
126 overflow: hidden;
127 opacity: 0.5;
128 }
129 }
130
131 @media (min-width: ($sidebar-bp + 1px)) {
132 :deep() {
133 header.toolbar {
134 .logo-box {
135 display: none;
136 }
137 }
138 }
139 }
140 }
141
142 .direction-rtl {
143 .main {
144 padding-left: unset;
145 padding-right: var(--sidebar-open-width);
146
147 &.sidebar-collapsed {
148 padding-left: unset;
149 padding-right: var(--sidebar-close-width);
150 }
151
152 @media (max-width: $sidebar-bp) {
153 padding-right: 0px;
154
155 &.sidebar-collapsed {
156 padding-right: 0px;
157 }
158 }
159 }
160 }
161 </style>