Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/content/docs/guides/animation.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ import { DialogClose, DialogContent, DialogDescription, DialogOverlay, DialogPor
Edit profile
</DialogTrigger>
<DialogPortal>
<AnimatePresence multiple>
<AnimatePresence>
<DialogOverlay as-child>
<Motion
:initial="{ opacity: 0, scale: 0 }"
Expand Down
7 changes: 7 additions & 0 deletions docs/content/meta/DialogRoot.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@
'description': '<p>The controlled open state of the dialog. Can be binded as <code>v-model:open</code>.</p>\n',
'type': 'boolean',
'required': false
},
{
'name': 'unmountOnHide',
'description': '<p>When <code>true</code>, the element will be unmounted on closed state.</p>\n',
'type': 'boolean',
'required': false,
'default': 'true'
}
]" />

Expand Down
9 changes: 8 additions & 1 deletion packages/core/src/Dialog/DialogContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,23 @@ const { forwardRef } = useForwardExpose()
</script>

<template>
<Presence :present="forceMount || rootContext.open.value">
<Presence
v-slot="{ present }"
:present="forceMount || rootContext.open.value"
:force-mount="forceMount || !rootContext.unmountOnHide.value"
>
<DialogContentModal
v-if="rootContext.modal.value"
v-show="present"
:ref="forwardRef"
v-bind="{ ...props, ...emitsAsProps, ...$attrs }"
:present
>
<slot />
</DialogContentModal>
<DialogContentNonModal
v-else
v-show="present"
:ref="forwardRef"
v-bind="{ ...props, ...emitsAsProps, ...$attrs }"
>
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/Dialog/DialogContentImpl.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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
/**
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/Dialog/DialogContentModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useEmitAsProps, useForwardExpose, useHideOthers } from '@/shared'
import DialogContentImpl from './DialogContentImpl.vue'
import { injectDialogRootContext } from './DialogRoot.vue'

const props = defineProps<DialogContentImplProps>()
const props = defineProps<DialogContentImplProps & { present: boolean }>()
Comment thread
MickL marked this conversation as resolved.
const emits = defineEmits<DialogContentImplEmits>()

const rootContext = injectDialogRootContext()
Expand All @@ -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) {
Expand Down
11 changes: 10 additions & 1 deletion packages/core/src/Dialog/DialogRoot.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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. <br>
* 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 = {
Expand All @@ -22,6 +28,7 @@ export type DialogRootEmits = {
export interface DialogRootContext {
open: Readonly<Ref<boolean>>
modal: Ref<boolean>
unmountOnHide: Ref<boolean>
openModal: () => void
onOpenChange: (value: boolean) => void
onOpenToggle: () => void
Expand All @@ -48,6 +55,7 @@ const props = withDefaults(defineProps<DialogRootProps>(), {
open: undefined,
defaultOpen: false,
modal: true,
unmountOnHide: true,
})
const emit = defineEmits<DialogRootEmits>()

Expand All @@ -67,11 +75,12 @@ const open = useVModel(props, 'open', emit, {

const triggerElement = ref<HTMLElement>()
const contentElement = ref<HTMLElement>()
const { modal } = toRefs(props)
const { modal, unmountOnHide } = toRefs(props)

provideDialogRootContext({
open,
modal,
unmountOnHide,
openModal: () => {
open.value = true
},
Expand Down