diff --git a/docs/content/docs/guides/animation.md b/docs/content/docs/guides/animation.md
index f31d68428c..a6a5e7566d 100644
--- a/docs/content/docs/guides/animation.md
+++ b/docs/content/docs/guides/animation.md
@@ -104,7 +104,7 @@ import { DialogClose, DialogContent, DialogDescription, DialogOverlay, DialogPor
Edit profile
-
+
The controlled open state of the dialog. Can be binded as v-model:open.
\n',
'type': 'boolean',
'required': false
+ },
+ {
+ 'name': 'unmountOnHide',
+ 'description': 'When true, the element will be unmounted on closed state.
\n',
+ 'type': 'boolean',
+ 'required': false,
+ 'default': 'true'
}
]" />
diff --git a/packages/core/src/Dialog/DialogContent.vue b/packages/core/src/Dialog/DialogContent.vue
index 0bbd22b3d4..e202793bae 100644
--- a/packages/core/src/Dialog/DialogContent.vue
+++ b/packages/core/src/Dialog/DialogContent.vue
@@ -32,16 +32,23 @@ const { forwardRef } = useForwardExpose()
-
+
diff --git a/packages/core/src/Dialog/DialogContentImpl.vue b/packages/core/src/Dialog/DialogContentImpl.vue
index 79732966fe..3c03b3577b 100644
--- a/packages/core/src/Dialog/DialogContentImpl.vue
+++ b/packages/core/src/Dialog/DialogContentImpl.vue
@@ -21,7 +21,7 @@ export type DialogContentImplEmits = DismissableLayerEmits & {
export interface DialogContentImplProps extends DismissableLayerProps {
/**
* Used to force mounting when more control is needed. Useful when
- * controlling transntion with Vue native transition or other animation libraries.
+ * controlling transition with Vue native transition or other animation libraries.
*/
forceMount?: boolean
/**
diff --git a/packages/core/src/Dialog/DialogContentModal.vue b/packages/core/src/Dialog/DialogContentModal.vue
index a6342da356..70918daba8 100644
--- a/packages/core/src/Dialog/DialogContentModal.vue
+++ b/packages/core/src/Dialog/DialogContentModal.vue
@@ -4,7 +4,7 @@ import { useEmitAsProps, useForwardExpose, useHideOthers } from '@/shared'
import DialogContentImpl from './DialogContentImpl.vue'
import { injectDialogRootContext } from './DialogRoot.vue'
-const props = defineProps()
+const props = defineProps()
const emits = defineEmits()
const rootContext = injectDialogRootContext()
@@ -20,7 +20,7 @@ useHideOthers(currentElement)
v-bind="{ ...props, ...emitsAsProps }"
:ref="forwardRef"
:trap-focus="rootContext.open.value"
- :disable-outside-pointer-events="true"
+ :disable-outside-pointer-events="present"
@close-auto-focus="
(event) => {
if (!event.defaultPrevented) {
diff --git a/packages/core/src/Dialog/DialogRoot.vue b/packages/core/src/Dialog/DialogRoot.vue
index 2e865a4996..3809782a56 100644
--- a/packages/core/src/Dialog/DialogRoot.vue
+++ b/packages/core/src/Dialog/DialogRoot.vue
@@ -12,6 +12,12 @@ export interface DialogRootProps {
* interaction with outside elements will be disabled and only dialog content will be visible to screen readers.
*/
modal?: boolean
+ /**
+ * When set to `false`, the dialog content and overlay will not be unmounted when closed, but instead hidden with CSS.
+ * Useful for SEO or when you want to improve performance by not remounting the component on every open.
+ * @defaultValue true
+ */
+ unmountOnHide?: boolean
}
export type DialogRootEmits = {
@@ -22,6 +28,7 @@ export type DialogRootEmits = {
export interface DialogRootContext {
open: Readonly[>
modal: Ref
+ unmountOnHide: Ref
openModal: () => void
onOpenChange: (value: boolean) => void
onOpenToggle: () => void
@@ -48,6 +55,7 @@ const props = withDefaults(defineProps(), {
open: undefined,
defaultOpen: false,
modal: true,
+ unmountOnHide: true,
})
const emit = defineEmits()
@@ -67,11 +75,12 @@ const open = useVModel(props, 'open', emit, {
const triggerElement = ref()
const contentElement = ref()
-const { modal } = toRefs(props)
+const { modal, unmountOnHide } = toRefs(props)
provideDialogRootContext({
open,
modal,
+ unmountOnHide,
openModal: () => {
open.value = true
},
]