initial commit
This commit is contained in:
@@ -0,0 +1,204 @@
|
||||
import { AppContentLayoutNav, NavbarType } from '../enums'
|
||||
import { config } from '@layouts/config'
|
||||
import { injectionKeyIsVerticalNavHovered } from '@layouts'
|
||||
|
||||
export const useLayouts = () => {
|
||||
const navbarType = computed({
|
||||
get() {
|
||||
return config.navbar.type.value
|
||||
},
|
||||
set(value) {
|
||||
config.navbar.type.value = value
|
||||
},
|
||||
})
|
||||
|
||||
const isNavbarBlurEnabled = computed({
|
||||
get() {
|
||||
return config.navbar.navbarBlur.value
|
||||
},
|
||||
set(value) {
|
||||
config.navbar.navbarBlur.value = value
|
||||
localStorage.setItem(`${config.app.title}-navbarBlur`, value.toString())
|
||||
},
|
||||
})
|
||||
|
||||
const _setAppDir = dir => {
|
||||
document.documentElement.setAttribute('dir', dir)
|
||||
}
|
||||
|
||||
const footerType = computed({
|
||||
get() {
|
||||
return config.footer.type.value
|
||||
},
|
||||
set(value) {
|
||||
config.footer.type.value = value
|
||||
},
|
||||
})
|
||||
|
||||
const isVerticalNavCollapsed = computed({
|
||||
get() {
|
||||
return config.verticalNav.isVerticalNavCollapsed.value
|
||||
},
|
||||
set(val) {
|
||||
config.verticalNav.isVerticalNavCollapsed.value = val
|
||||
localStorage.setItem(`${config.app.title}-isVerticalNavCollapsed`, val.toString())
|
||||
},
|
||||
})
|
||||
|
||||
const appContentWidth = computed({
|
||||
get() {
|
||||
return config.app.contentWidth.value
|
||||
},
|
||||
set(val) {
|
||||
config.app.contentWidth.value = val
|
||||
localStorage.setItem(`${config.app.title}-contentWidth`, val.toString())
|
||||
},
|
||||
})
|
||||
|
||||
const appContentLayoutNav = computed({
|
||||
get() {
|
||||
return config.app.contentLayoutNav.value
|
||||
},
|
||||
set(val) {
|
||||
config.app.contentLayoutNav.value = val
|
||||
|
||||
// If Navbar type is hidden while switching to horizontal nav => Reset it to sticky
|
||||
if (val === AppContentLayoutNav.Horizontal) {
|
||||
if (navbarType.value === NavbarType.Hidden)
|
||||
navbarType.value = NavbarType.Sticky
|
||||
isVerticalNavCollapsed.value = false
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const horizontalNavType = computed({
|
||||
get() {
|
||||
return config.horizontalNav.type.value
|
||||
},
|
||||
set(value) {
|
||||
config.horizontalNav.type.value = value
|
||||
},
|
||||
})
|
||||
|
||||
const isLessThanOverlayNavBreakpoint = computed(() => {
|
||||
return windowWidth => unref(windowWidth) < config.app.overlayNavFromBreakpoint
|
||||
})
|
||||
|
||||
const _layoutClasses = computed(() => (windowWidth, windowScrollY) => {
|
||||
const route = useRoute()
|
||||
|
||||
return [
|
||||
`layout-nav-type-${appContentLayoutNav.value}`,
|
||||
`layout-navbar-${navbarType.value}`,
|
||||
`layout-footer-${footerType.value}`,
|
||||
{
|
||||
'layout-vertical-nav-collapsed': isVerticalNavCollapsed.value
|
||||
&& appContentLayoutNav.value === 'vertical'
|
||||
&& !isLessThanOverlayNavBreakpoint.value(windowWidth),
|
||||
},
|
||||
{ [`horizontal-nav-${horizontalNavType.value}`]: appContentLayoutNav.value === 'horizontal' },
|
||||
`layout-content-width-${appContentWidth.value}`,
|
||||
{ 'layout-overlay-nav': isLessThanOverlayNavBreakpoint.value(windowWidth) },
|
||||
{ 'window-scrolled': unref(windowScrollY) },
|
||||
route.meta.layoutWrapperClasses ? route.meta.layoutWrapperClasses : null,
|
||||
]
|
||||
})
|
||||
|
||||
const switchToVerticalNavOnLtOverlayNavBreakpoint = windowWidth => {
|
||||
/*
|
||||
ℹ️ This is flag will hold nav type need to render when switching between lgAndUp from mdAndDown window width
|
||||
|
||||
Requirement: When we nav is set to `horizontal` and we hit the `mdAndDown` breakpoint nav type shall change to `vertical` nav
|
||||
Now if we go back to `lgAndUp` breakpoint from `mdAndDown` how we will know which was previous nav type in large device?
|
||||
|
||||
Let's assign value of `appContentLayoutNav` as default value of lgAndUpNav. Why 🤔?
|
||||
If template is viewed in lgAndUp
|
||||
We will assign `appContentLayoutNav` value to `lgAndUpNav` because at this point both constant is same
|
||||
Hence, for `lgAndUpNav` it will take value from theme config file
|
||||
else
|
||||
It will always show vertical nav and if user increase the window width it will fallback to `appContentLayoutNav` value
|
||||
But `appContentLayoutNav` will be value set in theme config file
|
||||
*/
|
||||
const lgAndUpNav = ref(appContentLayoutNav.value)
|
||||
|
||||
|
||||
/*
|
||||
There might be case where we manually switch from vertical to horizontal nav and vice versa in `lgAndUp` screen
|
||||
So when user comes back from `mdAndDown` to `lgAndUp` we can set updated nav type
|
||||
For this we need to update the `lgAndUpNav` value if screen is `lgAndUp`
|
||||
*/
|
||||
watch(appContentLayoutNav, value => {
|
||||
if (!isLessThanOverlayNavBreakpoint.value(windowWidth))
|
||||
lgAndUpNav.value = value
|
||||
})
|
||||
|
||||
/*
|
||||
This is layout switching part
|
||||
If it's `mdAndDown` => We will use vertical nav no matter what previous nav type was
|
||||
Or if it's `lgAndUp` we need to switch back to `lgAndUp` nav type. For this we will tracker property `lgAndUpNav`
|
||||
*/
|
||||
watch(() => isLessThanOverlayNavBreakpoint.value(windowWidth), val => {
|
||||
if (!val)
|
||||
appContentLayoutNav.value = lgAndUpNav.value
|
||||
else
|
||||
appContentLayoutNav.value = AppContentLayoutNav.Vertical
|
||||
}, { immediate: true })
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This function will return true if current state is mini. Mini state means vertical nav is:
|
||||
- Collapsed
|
||||
- Isn't hovered by mouse
|
||||
- nav is not less than overlay breakpoint (hence, isn't overlay menu)
|
||||
|
||||
ℹ️ We are getting `isVerticalNavHovered` as param instead of via `inject` because
|
||||
we are using this in `VerticalNav.vue` component which provide it and I guess because
|
||||
same component is providing & injecting we are getting undefined error
|
||||
*/
|
||||
const isVerticalNavMini = (windowWidth, isVerticalNavHovered = null) => {
|
||||
const isVerticalNavHoveredLocal = isVerticalNavHovered || inject(injectionKeyIsVerticalNavHovered) || ref(false)
|
||||
|
||||
return computed(() => isVerticalNavCollapsed.value && !isVerticalNavHoveredLocal.value && !isLessThanOverlayNavBreakpoint.value(unref(windowWidth)))
|
||||
}
|
||||
|
||||
const dynamicI18nProps = computed(() => (key, tag = 'span') => {
|
||||
if (config.app.enableI18n) {
|
||||
return {
|
||||
keypath: key,
|
||||
tag,
|
||||
scope: 'global',
|
||||
}
|
||||
}
|
||||
|
||||
return {}
|
||||
})
|
||||
|
||||
const isAppRtl = computed({
|
||||
get() {
|
||||
return config.app.isRtl.value
|
||||
},
|
||||
set(value) {
|
||||
config.app.isRtl.value = value
|
||||
localStorage.setItem(`${config.app.title}-isRtl`, value.toString())
|
||||
_setAppDir(value ? 'rtl' : 'ltr')
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
navbarType,
|
||||
isNavbarBlurEnabled,
|
||||
footerType,
|
||||
isVerticalNavCollapsed,
|
||||
appContentWidth,
|
||||
appContentLayoutNav,
|
||||
horizontalNavType,
|
||||
isLessThanOverlayNavBreakpoint,
|
||||
_layoutClasses,
|
||||
switchToVerticalNavOnLtOverlayNavBreakpoint,
|
||||
isVerticalNavMini,
|
||||
dynamicI18nProps,
|
||||
isAppRtl,
|
||||
_setAppDir,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user