chore: layout config updates
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
import { useLayout } from '@/layout/composables/layout';
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
|
||||
const { getPrimary, getSurface, isDarkTheme } = useLayout();
|
||||
const { layoutConfig, isDarkTheme } = useLayout();
|
||||
|
||||
const chartData = ref(null);
|
||||
const chartOptions = ref(null);
|
||||
@@ -77,7 +77,7 @@ function setChartOptions() {
|
||||
};
|
||||
}
|
||||
|
||||
watch([getPrimary, getSurface, isDarkTheme], () => {
|
||||
watch([() => layoutConfig.primary, () => layoutConfig.surface, isDarkTheme], () => {
|
||||
chartData.value = setChartData();
|
||||
chartOptions.value = setChartOptions();
|
||||
});
|
||||
|
||||
@@ -6,7 +6,7 @@ import Lara from '@primeuix/themes/lara';
|
||||
import Nora from '@primeuix/themes/nora';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const { layoutConfig, isDarkTheme } = useLayout();
|
||||
const { layoutConfig, isDarkTheme, changeMenuMode } = useLayout();
|
||||
|
||||
const presets = {
|
||||
Aura,
|
||||
@@ -192,10 +192,6 @@ function onPresetChange() {
|
||||
|
||||
$t().preset(presetValue).preset(getPresetExt()).surfacePalette(surfacePalette).use({ useDefaultOptions: true });
|
||||
}
|
||||
|
||||
function onMenuModeChange() {
|
||||
layoutConfig.menuMode = menuMode.value;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -240,7 +236,7 @@ function onMenuModeChange() {
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<span class="text-sm text-muted-color font-semibold">Menu Mode</span>
|
||||
<SelectButton v-model="menuMode" @change="onMenuModeChange" :options="menuModeOptions" :allowEmpty="false" optionLabel="label" optionValue="value" />
|
||||
<SelectButton v-model="menuMode" @change="changeMenuMode" :options="menuModeOptions" :allowEmpty="false" optionLabel="label" optionValue="value" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,71 +1,34 @@
|
||||
<script setup>
|
||||
import { useLayout } from '@/layout/composables/layout';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { computed } from 'vue';
|
||||
import AppFooter from './AppFooter.vue';
|
||||
import AppSidebar from './AppSidebar.vue';
|
||||
import AppTopbar from './AppTopbar.vue';
|
||||
|
||||
const { layoutConfig, layoutState, isSidebarActive } = useLayout();
|
||||
|
||||
const outsideClickListener = ref(null);
|
||||
|
||||
watch(isSidebarActive, (newVal) => {
|
||||
if (newVal) {
|
||||
bindOutsideClickListener();
|
||||
} else {
|
||||
unbindOutsideClickListener();
|
||||
}
|
||||
});
|
||||
const { layoutConfig, layoutState, hideMobileMenu } = useLayout();
|
||||
|
||||
const containerClass = computed(() => {
|
||||
return {
|
||||
'layout-overlay': layoutConfig.menuMode === 'overlay',
|
||||
'layout-static': layoutConfig.menuMode === 'static',
|
||||
'layout-static-inactive': layoutState.staticMenuDesktopInactive && layoutConfig.menuMode === 'static',
|
||||
'layout-overlay-active': layoutState.overlayMenuActive,
|
||||
'layout-mobile-active': layoutState.staticMenuMobileActive
|
||||
'layout-mobile-active': layoutState.mobileMenuActive,
|
||||
'layout-static-inactive': layoutState.staticMenuInactive
|
||||
};
|
||||
});
|
||||
|
||||
function bindOutsideClickListener() {
|
||||
if (!outsideClickListener.value) {
|
||||
outsideClickListener.value = (event) => {
|
||||
if (isOutsideClicked(event)) {
|
||||
layoutState.overlayMenuActive = false;
|
||||
layoutState.staticMenuMobileActive = false;
|
||||
layoutState.menuHoverActive = false;
|
||||
}
|
||||
};
|
||||
document.addEventListener('click', outsideClickListener.value);
|
||||
}
|
||||
}
|
||||
|
||||
function unbindOutsideClickListener() {
|
||||
if (outsideClickListener.value) {
|
||||
document.removeEventListener('click', outsideClickListener);
|
||||
outsideClickListener.value = null;
|
||||
}
|
||||
}
|
||||
|
||||
function isOutsideClicked(event) {
|
||||
const sidebarEl = document.querySelector('.layout-sidebar');
|
||||
const topbarEl = document.querySelector('.layout-menu-button');
|
||||
|
||||
return !(sidebarEl.isSameNode(event.target) || sidebarEl.contains(event.target) || topbarEl.isSameNode(event.target) || topbarEl.contains(event.target));
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="layout-wrapper" :class="containerClass">
|
||||
<app-topbar></app-topbar>
|
||||
<app-sidebar></app-sidebar>
|
||||
<AppTopbar />
|
||||
<AppSidebar />
|
||||
<div class="layout-main-container">
|
||||
<div class="layout-main">
|
||||
<router-view></router-view>
|
||||
<router-view />
|
||||
</div>
|
||||
<app-footer></app-footer>
|
||||
<AppFooter />
|
||||
</div>
|
||||
<div class="layout-mask animate-fadein"></div>
|
||||
<div class="layout-mask animate-fadein" @click="hideMobileMenu" />
|
||||
</div>
|
||||
<Toast />
|
||||
</template>
|
||||
|
||||
@@ -1,41 +1,109 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
|
||||
import AppMenuItem from './AppMenuItem.vue';
|
||||
|
||||
const model = ref([
|
||||
{
|
||||
label: 'Home',
|
||||
items: [{ label: 'Dashboard', icon: 'pi pi-fw pi-home', to: '/' }]
|
||||
items: [
|
||||
{
|
||||
label: 'Dashboard',
|
||||
icon: 'pi pi-fw pi-home',
|
||||
to: '/'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'UI Components',
|
||||
path: '/uikit',
|
||||
items: [
|
||||
{ label: 'Form Layout', icon: 'pi pi-fw pi-id-card', to: '/uikit/formlayout' },
|
||||
{ label: 'Input', icon: 'pi pi-fw pi-check-square', to: '/uikit/input' },
|
||||
{ label: 'Button', icon: 'pi pi-fw pi-mobile', to: '/uikit/button', class: 'rotated-icon' },
|
||||
{ label: 'Table', icon: 'pi pi-fw pi-table', to: '/uikit/table' },
|
||||
{ label: 'List', icon: 'pi pi-fw pi-list', to: '/uikit/list' },
|
||||
{ label: 'Tree', icon: 'pi pi-fw pi-share-alt', to: '/uikit/tree' },
|
||||
{ label: 'Panel', icon: 'pi pi-fw pi-tablet', to: '/uikit/panel' },
|
||||
{ label: 'Overlay', icon: 'pi pi-fw pi-clone', to: '/uikit/overlay' },
|
||||
{ label: 'Media', icon: 'pi pi-fw pi-image', to: '/uikit/media' },
|
||||
{ label: 'Menu', icon: 'pi pi-fw pi-bars', to: '/uikit/menu' },
|
||||
{ label: 'Message', icon: 'pi pi-fw pi-comment', to: '/uikit/message' },
|
||||
{ label: 'File', icon: 'pi pi-fw pi-file', to: '/uikit/file' },
|
||||
{ label: 'Chart', icon: 'pi pi-fw pi-chart-bar', to: '/uikit/charts' },
|
||||
{ label: 'Timeline', icon: 'pi pi-fw pi-calendar', to: '/uikit/timeline' },
|
||||
{ label: 'Misc', icon: 'pi pi-fw pi-circle', to: '/uikit/misc' }
|
||||
{
|
||||
label: 'Form Layout',
|
||||
icon: 'pi pi-fw pi-id-card',
|
||||
to: '/uikit/formlayout'
|
||||
},
|
||||
{
|
||||
label: 'Input',
|
||||
icon: 'pi pi-fw pi-check-square',
|
||||
to: '/uikit/input'
|
||||
},
|
||||
{
|
||||
label: 'Button',
|
||||
icon: 'pi pi-fw pi-mobile',
|
||||
to: '/uikit/button',
|
||||
class: 'rotated-icon'
|
||||
},
|
||||
{
|
||||
label: 'Table',
|
||||
icon: 'pi pi-fw pi-table',
|
||||
to: '/uikit/table'
|
||||
},
|
||||
{
|
||||
label: 'List',
|
||||
icon: 'pi pi-fw pi-list',
|
||||
to: '/uikit/list'
|
||||
},
|
||||
{
|
||||
label: 'Tree',
|
||||
icon: 'pi pi-fw pi-share-alt',
|
||||
to: '/uikit/tree'
|
||||
},
|
||||
{
|
||||
label: 'Panel',
|
||||
icon: 'pi pi-fw pi-tablet',
|
||||
to: '/uikit/panel'
|
||||
},
|
||||
{
|
||||
label: 'Overlay',
|
||||
icon: 'pi pi-fw pi-clone',
|
||||
to: '/uikit/overlay'
|
||||
},
|
||||
{
|
||||
label: 'Media',
|
||||
icon: 'pi pi-fw pi-image',
|
||||
to: '/uikit/media'
|
||||
},
|
||||
{
|
||||
label: 'Menu',
|
||||
icon: 'pi pi-fw pi-bars',
|
||||
to: '/uikit/menu'
|
||||
},
|
||||
{
|
||||
label: 'Message',
|
||||
icon: 'pi pi-fw pi-comment',
|
||||
to: '/uikit/message'
|
||||
},
|
||||
{
|
||||
label: 'File',
|
||||
icon: 'pi pi-fw pi-file',
|
||||
to: '/uikit/file'
|
||||
},
|
||||
{
|
||||
label: 'Chart',
|
||||
icon: 'pi pi-fw pi-chart-bar',
|
||||
to: '/uikit/charts'
|
||||
},
|
||||
{
|
||||
label: 'Timeline',
|
||||
icon: 'pi pi-fw pi-calendar',
|
||||
to: '/uikit/timeline'
|
||||
},
|
||||
{
|
||||
label: 'Misc',
|
||||
icon: 'pi pi-fw pi-circle',
|
||||
to: '/uikit/misc'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Prime Blocks',
|
||||
icon: 'pi pi-fw pi-prime',
|
||||
path: '/blocks',
|
||||
items: [
|
||||
{
|
||||
label: 'Free Blocks',
|
||||
icon: 'pi pi-fw pi-eye',
|
||||
to: '/blocks'
|
||||
to: '/blocks/free'
|
||||
},
|
||||
{
|
||||
label: 'All Blocks',
|
||||
@@ -48,7 +116,7 @@ const model = ref([
|
||||
{
|
||||
label: 'Pages',
|
||||
icon: 'pi pi-fw pi-briefcase',
|
||||
to: '/pages',
|
||||
path: '/pages',
|
||||
items: [
|
||||
{
|
||||
label: 'Landing',
|
||||
@@ -58,6 +126,7 @@ const model = ref([
|
||||
{
|
||||
label: 'Auth',
|
||||
icon: 'pi pi-fw pi-user',
|
||||
path: '/auth',
|
||||
items: [
|
||||
{
|
||||
label: 'Login',
|
||||
@@ -95,43 +164,76 @@ const model = ref([
|
||||
},
|
||||
{
|
||||
label: 'Hierarchy',
|
||||
icon: 'pi pi-fw pi-align-left',
|
||||
path: '/hierarchy',
|
||||
items: [
|
||||
{
|
||||
label: 'Submenu 1',
|
||||
icon: 'pi pi-fw pi-bookmark',
|
||||
icon: 'pi pi-fw pi-align-left',
|
||||
path: '/submenu_1',
|
||||
items: [
|
||||
{
|
||||
label: 'Submenu 1.1',
|
||||
icon: 'pi pi-fw pi-bookmark',
|
||||
icon: 'pi pi-fw pi-align-left',
|
||||
path: '/submenu_1_1',
|
||||
items: [
|
||||
{ label: 'Submenu 1.1.1', icon: 'pi pi-fw pi-bookmark' },
|
||||
{ label: 'Submenu 1.1.2', icon: 'pi pi-fw pi-bookmark' },
|
||||
{ label: 'Submenu 1.1.3', icon: 'pi pi-fw pi-bookmark' }
|
||||
{
|
||||
label: 'Submenu 1.1.1',
|
||||
icon: 'pi pi-fw pi-align-left'
|
||||
},
|
||||
{
|
||||
label: 'Submenu 1.1.2',
|
||||
icon: 'pi pi-fw pi-align-left'
|
||||
},
|
||||
{
|
||||
label: 'Submenu 1.1.3',
|
||||
icon: 'pi pi-fw pi-align-left'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Submenu 1.2',
|
||||
icon: 'pi pi-fw pi-bookmark',
|
||||
items: [{ label: 'Submenu 1.2.1', icon: 'pi pi-fw pi-bookmark' }]
|
||||
icon: 'pi pi-fw pi-align-left',
|
||||
path: '/submenu_1_2',
|
||||
items: [
|
||||
{
|
||||
label: 'Submenu 1.2.1',
|
||||
icon: 'pi pi-fw pi-align-left'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Submenu 2',
|
||||
icon: 'pi pi-fw pi-bookmark',
|
||||
icon: 'pi pi-fw pi-align-left',
|
||||
path: '/submenu_2',
|
||||
items: [
|
||||
{
|
||||
label: 'Submenu 2.1',
|
||||
icon: 'pi pi-fw pi-bookmark',
|
||||
icon: 'pi pi-fw pi-align-left',
|
||||
path: '/submenu_2_1',
|
||||
items: [
|
||||
{ label: 'Submenu 2.1.1', icon: 'pi pi-fw pi-bookmark' },
|
||||
{ label: 'Submenu 2.1.2', icon: 'pi pi-fw pi-bookmark' }
|
||||
{
|
||||
label: 'Submenu 2.1.1',
|
||||
icon: 'pi pi-fw pi-align-left'
|
||||
},
|
||||
{
|
||||
label: 'Submenu 2.1.2',
|
||||
icon: 'pi pi-fw pi-align-left'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Submenu 2.2',
|
||||
icon: 'pi pi-fw pi-bookmark',
|
||||
items: [{ label: 'Submenu 2.2.1', icon: 'pi pi-fw pi-bookmark' }]
|
||||
icon: 'pi pi-fw pi-align-left',
|
||||
path: '/submenu_2_2',
|
||||
items: [
|
||||
{
|
||||
label: 'Submenu 2.2.1',
|
||||
icon: 'pi pi-fw pi-align-left'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -139,11 +241,12 @@ const model = ref([
|
||||
},
|
||||
{
|
||||
label: 'Get Started',
|
||||
path: '/start',
|
||||
items: [
|
||||
{
|
||||
label: 'Documentation',
|
||||
icon: 'pi pi-fw pi-book',
|
||||
to: '/documentation'
|
||||
to: '/start/documentation'
|
||||
},
|
||||
{
|
||||
label: 'View Source',
|
||||
|
||||
@@ -1,92 +1,78 @@
|
||||
<script setup>
|
||||
import { useLayout } from '@/layout/composables/layout';
|
||||
import { onBeforeMount, ref, watch } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { computed } from 'vue';
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const { layoutState, setActiveMenuItem, toggleMenu } = useLayout();
|
||||
const { layoutState, isDesktop } = useLayout();
|
||||
|
||||
const props = defineProps({
|
||||
item: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
root: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
parentItemKey: {
|
||||
parentPath: {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
});
|
||||
|
||||
const isActiveMenu = ref(false);
|
||||
const itemKey = ref(null);
|
||||
const fullPath = computed(() => (props.item.path ? (props.parentPath ? props.parentPath + props.item.path : props.item.path) : null));
|
||||
|
||||
onBeforeMount(() => {
|
||||
itemKey.value = props.parentItemKey ? props.parentItemKey + '-' + props.index : String(props.index);
|
||||
|
||||
const activeItem = layoutState.activeMenuItem;
|
||||
|
||||
isActiveMenu.value = activeItem === itemKey.value || activeItem ? activeItem.startsWith(itemKey.value + '-') : false;
|
||||
const isActive = computed(() => {
|
||||
return props.item.path ? layoutState.activePath?.startsWith(fullPath.value) : layoutState.activePath === props.item.to;
|
||||
});
|
||||
|
||||
watch(
|
||||
() => layoutState.activeMenuItem,
|
||||
(newVal) => {
|
||||
isActiveMenu.value = newVal === itemKey.value || newVal.startsWith(itemKey.value + '-');
|
||||
}
|
||||
);
|
||||
|
||||
function itemClick(event, item) {
|
||||
const itemClick = (event, item) => {
|
||||
if (item.disabled) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
if ((item.to || item.url) && (layoutState.staticMenuMobileActive || layoutState.overlayMenuActive)) {
|
||||
toggleMenu();
|
||||
}
|
||||
|
||||
if (item.command) {
|
||||
item.command({ originalEvent: event, item: item });
|
||||
}
|
||||
|
||||
const foundItemKey = item.items ? (isActiveMenu.value ? props.parentItemKey : itemKey) : itemKey.value;
|
||||
if (item.items) {
|
||||
if (isActive.value) {
|
||||
layoutState.activePath = layoutState.activePath.replace(item.path, '');
|
||||
} else {
|
||||
layoutState.activePath = fullPath.value;
|
||||
layoutState.menuHoverActive = true;
|
||||
}
|
||||
} else {
|
||||
layoutState.overlayMenuActive = false;
|
||||
layoutState.mobileMenuActive = false;
|
||||
layoutState.menuHoverActive = false;
|
||||
}
|
||||
};
|
||||
|
||||
setActiveMenuItem(foundItemKey);
|
||||
}
|
||||
|
||||
function checkActiveRoute(item) {
|
||||
return route.path === item.to;
|
||||
}
|
||||
const onMouseEnter = () => {
|
||||
if (isDesktop() && props.root && props.item.items && layoutState.menuHoverActive) {
|
||||
layoutState.activePath = fullPath.value;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li :class="{ 'layout-root-menuitem': root, 'active-menuitem': isActiveMenu }">
|
||||
<li :class="{ 'layout-root-menuitem': root, 'active-menuitem': isActive }">
|
||||
<div v-if="root && item.visible !== false" class="layout-menuitem-root-text">{{ item.label }}</div>
|
||||
<a v-if="(!item.to || item.items) && item.visible !== false" :href="item.url" @click="itemClick($event, item, index)" :class="item.class" :target="item.target" tabindex="0">
|
||||
<i :class="item.icon" class="layout-menuitem-icon"></i>
|
||||
<a v-if="(!item.to || item.items) && item.visible !== false" :href="item.url" @click="itemClick($event, item)" :class="item.class" :target="item.target" tabindex="0" @mouseenter="onMouseEnter">
|
||||
<i :class="item.icon" class="layout-menuitem-icon" />
|
||||
<span class="layout-menuitem-text">{{ item.label }}</span>
|
||||
<i class="pi pi-fw pi-angle-down layout-submenu-toggler" v-if="item.items"></i>
|
||||
<i class="pi pi-fw pi-angle-down layout-submenu-toggler" v-if="item.items" />
|
||||
</a>
|
||||
<router-link v-if="item.to && !item.items && item.visible !== false" @click="itemClick($event, item, index)" :class="[item.class, { 'active-route': checkActiveRoute(item) }]" tabindex="0" :to="item.to">
|
||||
<i :class="item.icon" class="layout-menuitem-icon"></i>
|
||||
<router-link v-if="item.to && !item.items && item.visible !== false" @click="itemClick($event, item)" exactActiveClass="active-route" :class="item.class" tabindex="0" :to="item.to" @mouseenter="onMouseEnter">
|
||||
<i :class="item.icon" class="layout-menuitem-icon" />
|
||||
<span class="layout-menuitem-text">{{ item.label }}</span>
|
||||
<i class="pi pi-fw pi-angle-down layout-submenu-toggler" v-if="item.items"></i>
|
||||
<i class="pi pi-fw pi-angle-down layout-submenu-toggler" v-if="item.items" />
|
||||
</router-link>
|
||||
<Transition v-if="item.items && item.visible !== false" name="layout-submenu">
|
||||
<ul v-show="root ? true : isActiveMenu" class="layout-submenu">
|
||||
<app-menu-item v-for="(child, i) in item.items" :key="child" :index="i" :item="child" :parentItemKey="itemKey" :root="false"></app-menu-item>
|
||||
<ul v-show="root ? true : isActive" class="layout-submenu">
|
||||
<app-menu-item v-for="child in item.items" :key="child.label + '_' + (child.to || child.path)" :item="child" :root="false" :parentPath="fullPath" />
|
||||
</ul>
|
||||
</Transition>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,11 +1,66 @@
|
||||
<script setup>
|
||||
import { useLayout } from '@/layout/composables/layout';
|
||||
import { onBeforeUnmount, ref, watch } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import AppMenu from './AppMenu.vue';
|
||||
|
||||
const { layoutState, isDesktop, hasOpenOverlay } = useLayout();
|
||||
const route = useRoute();
|
||||
const sidebarRef = ref(null);
|
||||
let outsideClickListener = null;
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
(newPath) => {
|
||||
if (isDesktop()) layoutState.activePath = null;
|
||||
else layoutState.activePath = newPath;
|
||||
|
||||
layoutState.overlayMenuActive = false;
|
||||
layoutState.mobileMenuActive = false;
|
||||
layoutState.menuHoverActive = false;
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
watch(hasOpenOverlay, (newVal) => {
|
||||
if (isDesktop()) {
|
||||
if (newVal) bindOutsideClickListener();
|
||||
else unbindOutsideClickListener();
|
||||
}
|
||||
});
|
||||
|
||||
const bindOutsideClickListener = () => {
|
||||
if (!outsideClickListener) {
|
||||
outsideClickListener = (event) => {
|
||||
if (isOutsideClicked(event)) {
|
||||
layoutState.overlayMenuActive = false;
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('click', outsideClickListener);
|
||||
}
|
||||
};
|
||||
|
||||
const unbindOutsideClickListener = () => {
|
||||
if (outsideClickListener) {
|
||||
document.removeEventListener('click', outsideClickListener);
|
||||
outsideClickListener = null;
|
||||
}
|
||||
};
|
||||
|
||||
const isOutsideClicked = (event) => {
|
||||
const topbarButtonEl = document.querySelector('.layout-menu-button');
|
||||
|
||||
return !(sidebarRef.value.isSameNode(event.target) || sidebarRef.value.contains(event.target) || topbarButtonEl?.isSameNode(event.target) || topbarButtonEl?.contains(event.target));
|
||||
};
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
unbindOutsideClickListener();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="layout-sidebar">
|
||||
<app-menu></app-menu>
|
||||
<div ref="sidebarRef" class="layout-sidebar">
|
||||
<AppMenu />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -9,20 +9,17 @@ const layoutConfig = reactive({
|
||||
});
|
||||
|
||||
const layoutState = reactive({
|
||||
staticMenuDesktopInactive: false,
|
||||
staticMenuInactive: false,
|
||||
overlayMenuActive: false,
|
||||
profileSidebarVisible: false,
|
||||
configSidebarVisible: false,
|
||||
staticMenuMobileActive: false,
|
||||
sidebarExpanded: false,
|
||||
menuHoverActive: false,
|
||||
activeMenuItem: null
|
||||
activeMenuItem: null,
|
||||
activePath: null
|
||||
});
|
||||
|
||||
export function useLayout() {
|
||||
const setActiveMenuItem = (item) => {
|
||||
layoutState.activeMenuItem = item.value || item;
|
||||
};
|
||||
|
||||
const toggleDarkMode = () => {
|
||||
if (!document.startViewTransition) {
|
||||
executeDarkModeToggle();
|
||||
@@ -39,34 +36,51 @@ export function useLayout() {
|
||||
};
|
||||
|
||||
const toggleMenu = () => {
|
||||
if (layoutConfig.menuMode === 'overlay') {
|
||||
layoutState.overlayMenuActive = !layoutState.overlayMenuActive;
|
||||
}
|
||||
if (isDesktop()) {
|
||||
if (layoutConfig.menuMode === 'static') {
|
||||
layoutState.staticMenuInactive = !layoutState.staticMenuInactive;
|
||||
}
|
||||
|
||||
if (window.innerWidth > 991) {
|
||||
layoutState.staticMenuDesktopInactive = !layoutState.staticMenuDesktopInactive;
|
||||
if (layoutConfig.menuMode === 'overlay') {
|
||||
layoutState.overlayMenuActive = !layoutState.overlayMenuActive;
|
||||
}
|
||||
} else {
|
||||
layoutState.staticMenuMobileActive = !layoutState.staticMenuMobileActive;
|
||||
layoutState.mobileMenuActive = !layoutState.mobileMenuActive;
|
||||
}
|
||||
};
|
||||
|
||||
const isSidebarActive = computed(() => layoutState.overlayMenuActive || layoutState.staticMenuMobileActive);
|
||||
const toggleConfigSidebar = () => {
|
||||
layoutState.configSidebarVisible = !layoutState.configSidebarVisible;
|
||||
};
|
||||
|
||||
const hideMobileMenu = () => {
|
||||
layoutState.mobileMenuActive = false;
|
||||
};
|
||||
|
||||
const changeMenuMode = (event) => {
|
||||
layoutConfig.menuMode = event.value;
|
||||
layoutState.staticMenuInactive = false;
|
||||
layoutState.mobileMenuActive = false;
|
||||
layoutState.sidebarExpanded = false;
|
||||
layoutState.menuHoverActive = false;
|
||||
layoutState.anchored = false;
|
||||
};
|
||||
|
||||
const isDarkTheme = computed(() => layoutConfig.darkTheme);
|
||||
const isDesktop = () => window.innerWidth > 991;
|
||||
|
||||
const getPrimary = computed(() => layoutConfig.primary);
|
||||
|
||||
const getSurface = computed(() => layoutConfig.surface);
|
||||
const hasOpenOverlay = computed(() => layoutState.overlayMenuActive);
|
||||
|
||||
return {
|
||||
layoutConfig,
|
||||
layoutState,
|
||||
toggleMenu,
|
||||
isSidebarActive,
|
||||
isDarkTheme,
|
||||
getPrimary,
|
||||
getSurface,
|
||||
setActiveMenuItem,
|
||||
toggleDarkMode
|
||||
toggleDarkMode,
|
||||
toggleConfigSidebar,
|
||||
toggleMenu,
|
||||
hideMobileMenu,
|
||||
changeMenuMode,
|
||||
isDesktop,
|
||||
hasOpenOverlay
|
||||
};
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ const router = createRouter({
|
||||
component: () => import('@/views/uikit/TimelineDoc.vue')
|
||||
},
|
||||
{
|
||||
path: '/blocks',
|
||||
path: '/blocks/free',
|
||||
name: 'blocks',
|
||||
meta: {
|
||||
breadcrumb: ['Prime Blocks', 'Free Blocks']
|
||||
@@ -108,7 +108,7 @@ const router = createRouter({
|
||||
component: () => import('@/views/pages/Crud.vue')
|
||||
},
|
||||
{
|
||||
path: '/documentation',
|
||||
path: '/start/documentation',
|
||||
name: 'documentation',
|
||||
component: () => import('@/views/pages/Documentation.vue')
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { useLayout } from '@/layout/composables/layout';
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
|
||||
const { getPrimary, getSurface, isDarkTheme } = useLayout();
|
||||
const { layoutConfig, isDarkTheme } = useLayout();
|
||||
const lineData = ref(null);
|
||||
const pieData = ref(null);
|
||||
const polarData = ref(null);
|
||||
@@ -219,7 +219,7 @@ function setColorOptions() {
|
||||
}
|
||||
|
||||
watch(
|
||||
[getPrimary, getSurface, isDarkTheme],
|
||||
[() => layoutConfig.primary, () => layoutConfig.surface, isDarkTheme],
|
||||
() => {
|
||||
setColorOptions();
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user