diff --git a/packages/vuetify/src/components/VApp/VApp.tsx b/packages/vuetify/src/components/VApp/VApp.tsx
index f067aafe175..98f8f3760c0 100644
--- a/packages/vuetify/src/components/VApp/VApp.tsx
+++ b/packages/vuetify/src/components/VApp/VApp.tsx
@@ -7,6 +7,7 @@ import { makeThemeProps, provideTheme } from '@/composables/theme'
import { useRtl } from '@/composables/rtl'
// Utilities
+import { Suspense } from 'vue'
import { defineComponent, useRender } from '@/util'
export const VApp = defineComponent({
@@ -34,7 +35,11 @@ export const VApp = defineComponent({
style={ layoutStyles.value }
>
- { slots.default?.() }
+
+ <>
+ { slots.default?.() }
+ >
+
))
diff --git a/packages/vuetify/src/components/VAppBar/VAppBar.tsx b/packages/vuetify/src/components/VAppBar/VAppBar.tsx
index bb50ea00981..c6e1dbba7f0 100644
--- a/packages/vuetify/src/components/VAppBar/VAppBar.tsx
+++ b/packages/vuetify/src/components/VAppBar/VAppBar.tsx
@@ -53,12 +53,12 @@ export const VAppBar = defineComponent({
const vToolbarRef = ref()
const isActive = useProxiedModel(props, 'modelValue')
const height = computed(() => {
- const height: number = vToolbarRef.value?.contentHeight ?? 0
+ const height: number = vToolbarRef.value?.contentHeight ?? props.height
const extensionHeight: number = vToolbarRef.value?.extensionHeight ?? 0
return (height + extensionHeight)
})
- const { layoutItemStyles } = useLayoutItem({
+ const { layoutItemStyles, layoutIsReady } = useLayoutItem({
id: props.name,
order: computed(() => parseInt(props.order, 10)),
position: toRef(props, 'location'),
@@ -90,7 +90,7 @@ export const VAppBar = defineComponent({
)
})
- return {}
+ return layoutIsReady
},
})
diff --git a/packages/vuetify/src/components/VBottomNavigation/VBottomNavigation.tsx b/packages/vuetify/src/components/VBottomNavigation/VBottomNavigation.tsx
index 4ff052f8a44..1ecd530a988 100644
--- a/packages/vuetify/src/components/VBottomNavigation/VBottomNavigation.tsx
+++ b/packages/vuetify/src/components/VBottomNavigation/VBottomNavigation.tsx
@@ -67,7 +67,7 @@ export const VBottomNavigation = defineComponent({
(props.density === 'compact' ? 16 : 0)
))
const isActive = useProxiedModel(props, 'modelValue', props.modelValue)
- const { layoutItemStyles } = useLayoutItem({
+ const { layoutItemStyles, layoutIsReady } = useLayoutItem({
id: props.name,
order: computed(() => parseInt(props.order, 10)),
position: computed(() => 'bottom'),
@@ -123,7 +123,7 @@ export const VBottomNavigation = defineComponent({
)
})
- return {}
+ return layoutIsReady
},
})
diff --git a/packages/vuetify/src/components/VBottomNavigation/__tests__/VBottomNavigation.spec.cy.tsx b/packages/vuetify/src/components/VBottomNavigation/__tests__/VBottomNavigation.spec.cy.tsx
index a30ae51818d..8c1c0e662fa 100644
--- a/packages/vuetify/src/components/VBottomNavigation/__tests__/VBottomNavigation.spec.cy.tsx
+++ b/packages/vuetify/src/components/VBottomNavigation/__tests__/VBottomNavigation.spec.cy.tsx
@@ -31,4 +31,14 @@ describe('VBottomNavigation', () => {
cy.get('.v-bottom-navigation').should('have.css', 'height', '40px')
})
+
+ it('should not be visible if modelValue is false', () => {
+ cy.mount(() => (
+
+
+
+ ))
+
+ cy.get('.v-bottom-navigation').should('not.be.visible')
+ })
})
diff --git a/packages/vuetify/src/components/VFooter/VFooter.tsx b/packages/vuetify/src/components/VFooter/VFooter.tsx
index c09c31b23d3..1ca31d110ee 100644
--- a/packages/vuetify/src/components/VFooter/VFooter.tsx
+++ b/packages/vuetify/src/components/VFooter/VFooter.tsx
@@ -47,7 +47,7 @@ export const VFooter = defineComponent({
autoHeight.value = entries[0].target.clientHeight
})
const height = computed(() => props.height === 'auto' ? autoHeight.value : parseInt(props.height, 10))
- const { layoutItemStyles } = useLayoutItem({
+ const { layoutItemStyles, layoutIsReady } = useLayoutItem({
id: props.name,
order: computed(() => parseInt(props.order, 10)),
position: computed(() => 'bottom'),
@@ -76,6 +76,6 @@ export const VFooter = defineComponent({
/>
))
- return {}
+ return props.app ? layoutIsReady : {}
},
})
diff --git a/packages/vuetify/src/components/VLayout/VLayout.tsx b/packages/vuetify/src/components/VLayout/VLayout.tsx
index 733aa2a4283..fc5b4aba022 100644
--- a/packages/vuetify/src/components/VLayout/VLayout.tsx
+++ b/packages/vuetify/src/components/VLayout/VLayout.tsx
@@ -1,12 +1,13 @@
// Styles
import './VLayout.sass'
-// Utilities
-import { defineComponent, useRender } from '@/util'
-
// Composables
import { createLayout, makeLayoutProps } from '@/composables/layout'
+// Utilities
+import { Suspense } from 'vue'
+import { defineComponent, useRender } from '@/util'
+
export const VLayout = defineComponent({
name: 'VLayout',
@@ -17,7 +18,11 @@ export const VLayout = defineComponent({
useRender(() => (
- { slots.default?.() }
+
+ <>
+ { slots.default?.() }
+ >
+
))
diff --git a/packages/vuetify/src/components/VMain/VMain.tsx b/packages/vuetify/src/components/VMain/VMain.tsx
index ce65eb6c736..20a96d414c8 100644
--- a/packages/vuetify/src/components/VMain/VMain.tsx
+++ b/packages/vuetify/src/components/VMain/VMain.tsx
@@ -15,7 +15,7 @@ export const VMain = defineComponent({
props: makeTagProps({ tag: 'main' }),
setup (props, { slots }) {
- const { mainStyles } = useLayout()
+ const { mainStyles, layoutIsReady } = useLayout()
const { ssrBootStyles } = useSsrBoot()
useRender(() => (
@@ -32,6 +32,6 @@ export const VMain = defineComponent({
))
- return {}
+ return layoutIsReady
},
})
diff --git a/packages/vuetify/src/components/VNavigationDrawer/VNavigationDrawer.tsx b/packages/vuetify/src/components/VNavigationDrawer/VNavigationDrawer.tsx
index 668d284cf47..f901d65102e 100644
--- a/packages/vuetify/src/components/VNavigationDrawer/VNavigationDrawer.tsx
+++ b/packages/vuetify/src/components/VNavigationDrawer/VNavigationDrawer.tsx
@@ -16,7 +16,7 @@ import { useSsrBoot } from '@/composables/ssrBoot'
import { useTouch } from './touch'
// Utilities
-import { computed, onBeforeMount, ref, toRef, Transition, watch } from 'vue'
+import { computed, ref, toRef, Transition, watch } from 'vue'
import { convertToUnit, defineComponent, useRender } from '@/util'
// Types
@@ -96,11 +96,9 @@ export const VNavigationDrawer = defineComponent({
if (val) isActive.value = true
})
- onBeforeMount(() => {
- if (props.modelValue != null || isTemporary.value) return
-
+ if (props.modelValue == null && !isTemporary.value) {
isActive.value = props.permanent || !mobile.value
- })
+ }
const rootEl = ref()
@@ -119,7 +117,7 @@ export const VNavigationDrawer = defineComponent({
return isDragging.value ? size * dragProgress.value : size
})
- const { layoutItemStyles, layoutRect, layoutItemScrimStyles } = useLayoutItem({
+ const { layoutItemStyles, layoutRect, layoutItemScrimStyles, layoutIsReady } = useLayoutItem({
id: props.name,
order: computed(() => parseInt(props.order, 10)),
position: toRef(props, 'location'),
@@ -219,7 +217,7 @@ export const VNavigationDrawer = defineComponent({
)
})
- return {}
+ return layoutIsReady
},
})
diff --git a/packages/vuetify/src/composables/layout.ts b/packages/vuetify/src/composables/layout.ts
index d31671b4fba..64cc404b3a9 100644
--- a/packages/vuetify/src/composables/layout.ts
+++ b/packages/vuetify/src/composables/layout.ts
@@ -5,10 +5,10 @@ import { useResizeObserver } from '@/composables/resizeObserver'
import {
computed,
inject,
+ nextTick,
onActivated,
onBeforeUnmount,
onDeactivated,
- onMounted,
provide,
reactive,
ref,
@@ -53,6 +53,7 @@ interface LayoutProvide {
items: Ref
layoutRect: Ref
rootZIndex: Ref
+ layoutIsReady: Promise
}
export const VuetifyLayoutKey: InjectionKey = Symbol.for('vuetify:layout')
@@ -112,6 +113,8 @@ export function useLayoutItem (options: {
onDeactivated(() => isKeptAlive.value = true)
onActivated(() => isKeptAlive.value = false)
+ const layoutIsReady = nextTick()
+
const {
layoutItemStyles,
layoutItemScrimStyles,
@@ -123,7 +126,7 @@ export function useLayoutItem (options: {
onBeforeUnmount(() => layout.unregister(id))
- return { layoutItemStyles, layoutRect: layout.layoutRect, layoutItemScrimStyles }
+ return { layoutItemStyles, layoutRect: layout.layoutRect, layoutItemScrimStyles, layoutIsReady }
}
const generateLayers = (
@@ -167,27 +170,6 @@ export function createLayout (props: { overlaps?: string[], fullHeight?: boolean
const disabledTransitions = reactive(new Map>())
const { resizeRef, contentRect: layoutRect } = useResizeObserver()
- const computedOverlaps = computed(() => {
- const map = new Map()
- const overlaps = props.overlaps ?? []
- for (const overlap of overlaps.filter(item => item.includes(':'))) {
- const [top, bottom] = overlap.split(':')
- if (!registered.value.includes(top) || !registered.value.includes(bottom)) continue
-
- const topPosition = positions.get(top)
- const bottomPosition = positions.get(bottom)
- const topAmount = layoutSizes.get(top)
- const bottomAmount = layoutSizes.get(bottom)
-
- if (!topPosition || !bottomPosition || !topAmount || !bottomAmount) continue
-
- map.set(bottom, { position: topPosition.value, amount: parseInt(topAmount.value, 10) })
- map.set(top, { position: bottomPosition.value, amount: -parseInt(bottomAmount.value, 10) })
- }
-
- return map
- })
-
const layers = computed(() => {
const uniquePriorities = [...new Set([...priorities.values()].map(p => p.value))].sort((a, b) => a - b)
const layout = []
@@ -234,10 +216,7 @@ export function createLayout (props: { overlaps?: string[], fullHeight?: boolean
const rootVm = getCurrentInstance('createLayout')
- const isMounted = ref(false)
- onMounted(() => {
- isMounted.value = true
- })
+ const layoutIsReady = nextTick()
provide(VuetifyLayoutKey, {
register: (
@@ -281,19 +260,12 @@ export function createLayout (props: { overlaps?: string[], fullHeight?: boolean
...(transitionsEnabled.value ? undefined : { transition: 'none' }),
} as const
- if (!isMounted.value) return styles
-
if (index.value < 0) throw new Error(`Layout item "${id}" is missing`)
const item = items.value[index.value]
if (!item) throw new Error(`Could not find layout item "${id}`)
- const overlap = computedOverlaps.value.get(id)
- if (overlap) {
- item[overlap.position] += overlap.amount
- }
-
return {
...styles,
height: isHorizontal ? `calc(100% - ${item.top}px - ${item.bottom}px)` : elementSize.value ? `${elementSize.value}px` : undefined,
@@ -325,6 +297,7 @@ export function createLayout (props: { overlaps?: string[], fullHeight?: boolean
items,
layoutRect,
rootZIndex,
+ layoutIsReady,
})
const layoutClasses = computed(() => [
@@ -342,6 +315,7 @@ export function createLayout (props: { overlaps?: string[], fullHeight?: boolean
getLayoutItem,
items,
layoutRect,
+ layoutIsReady,
layoutRef: resizeRef,
}
}