feat(Modal/Popover/Slideover): add close:prevent event (#3958)

Co-authored-by: Benjamin Canac <canacb1@gmail.com>
This commit is contained in:
kyyy
2025-04-23 22:38:44 +07:00
committed by GitHub
parent 975331a7b1
commit f486423381
6 changed files with 39 additions and 26 deletions

View File

@@ -55,6 +55,7 @@ export interface ModalProps extends DialogRootProps {
export interface ModalEmits extends DialogRootEmits {
'after:leave': []
'close:prevent': []
}
export interface ModalSlots {
@@ -97,20 +98,23 @@ const rootProps = useForwardPropsEmits(reactivePick(props, 'open', 'defaultOpen'
const portalProps = usePortal(toRef(() => props.portal))
const contentProps = toRef(() => props.content)
const contentEvents = computed(() => {
const events = {
const defaultEvents = {
closeAutoFocus: (e: Event) => e.preventDefault()
}
if (!props.dismissible) {
return {
pointerDownOutside: (e: Event) => e.preventDefault(),
interactOutside: (e: Event) => e.preventDefault(),
escapeKeyDown: (e: Event) => e.preventDefault(),
...events
}
const events = ['pointerDownOutside', 'interactOutside', 'escapeKeyDown', 'closeAutoFocus'] as const
type EventType = typeof events[number]
return events.reduce((acc, curr) => {
acc[curr] = (e: Event) => {
e.preventDefault()
emits('close:prevent')
}
return acc
}, {} as Record<EventType, (e: Event) => void>)
}
return events
return defaultEvents
})
const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.modal || {}) })({

View File

@@ -36,7 +36,9 @@ export interface PopoverProps extends PopoverRootProps, Pick<HoverCardRootProps,
ui?: Popover['slots']
}
export interface PopoverEmits extends PopoverRootEmits {}
export interface PopoverEmits extends PopoverRootEmits {
'close:prevent': []
}
export interface PopoverSlots {
default(props: { open: boolean }): any
@@ -72,11 +74,15 @@ const portalProps = usePortal(toRef(() => props.portal))
const contentProps = toRef(() => defu(props.content, { side: 'bottom', sideOffset: 8, collisionPadding: 8 }) as PopoverContentProps)
const contentEvents = computed(() => {
if (!props.dismissible) {
return {
pointerDownOutside: (e: Event) => e.preventDefault(),
interactOutside: (e: Event) => e.preventDefault(),
escapeKeyDown: (e: Event) => e.preventDefault()
}
const events = ['pointerDownOutside', 'interactOutside', 'escapeKeyDown'] as const
type EventType = typeof events[number]
return events.reduce((acc, curr) => {
acc[curr] = (e: Event) => {
e.preventDefault()
emits('close:prevent')
}
return acc
}, {} as Record<EventType, (e: Event) => void>)
}
return {}

View File

@@ -55,6 +55,7 @@ export interface SlideoverProps extends DialogRootProps {
export interface SlideoverEmits extends DialogRootEmits {
'after:leave': []
'close:prevent': []
}
export interface SlideoverSlots {
@@ -98,20 +99,22 @@ const rootProps = useForwardPropsEmits(reactivePick(props, 'open', 'defaultOpen'
const portalProps = usePortal(toRef(() => props.portal))
const contentProps = toRef(() => props.content)
const contentEvents = computed(() => {
const events = {
const defaultEvents = {
closeAutoFocus: (e: Event) => e.preventDefault()
}
if (!props.dismissible) {
return {
pointerDownOutside: (e: Event) => e.preventDefault(),
interactOutside: (e: Event) => e.preventDefault(),
escapeKeyDown: (e: Event) => e.preventDefault(),
...events
}
const events = ['pointerDownOutside', 'interactOutside', 'escapeKeyDown', 'closeAutoFocus'] as const
type EventType = typeof events[number]
return events.reduce((acc, curr) => {
acc[curr] = (e: Event) => {
e.preventDefault()
emits('close:prevent')
}
return acc
}, {} as Record<EventType, (e: Event) => void>)
}
return events
return defaultEvents
})
const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.slideover || {}) })({