mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
feat(components): [dialog] add modal-penetrable prop (#21511)
* feat(components): [dialog] add `modal-penetrable` prop * refactor(components): [dialog] optimize code * test(components): [dialog] update test * test(components): [test] update test
This commit is contained in:
@@ -173,6 +173,7 @@ dialog/events
|
||||
| fullscreen | whether the Dialog takes up full screen | ^[boolean] | false |
|
||||
| top | value for `margin-top` of Dialog CSS, default is 15vh | ^[string] | '' |
|
||||
| modal | whether a mask is displayed | ^[boolean] | true |
|
||||
| modal-penetrable ^(2.10.5) | whether the mask is penetrable. The modal attribute must be `false`. | ^[boolean] | false |
|
||||
| modal-class | custom class names for mask | ^[string] | — |
|
||||
| header-class ^(2.9.3) | custom class names for header wrapper | ^[string] | — |
|
||||
| body-class ^(2.9.3) | custom class names for body wrapper | ^[string] | — |
|
||||
|
||||
@@ -225,6 +225,29 @@ describe('Dialog.vue', () => {
|
||||
await triggerCompositeClick(wrapper.find('.el-overlay-dialog'))
|
||||
expect(wrapper.vm.visible).toBe(false)
|
||||
})
|
||||
|
||||
test('should not click the mask to close when it is penetrable', async () => {
|
||||
const onClick = vi.fn()
|
||||
|
||||
const wrapper = mount(() => (
|
||||
<>
|
||||
<Dialog modelValue={true} modal={false} modalPenetrable={true}>
|
||||
{AXIOM}
|
||||
</Dialog>
|
||||
<button onClick={onClick}>button</button>
|
||||
</>
|
||||
))
|
||||
|
||||
const overlay = wrapper.findComponent({ name: 'ElOverlay' })
|
||||
const dialog = wrapper.findComponent({ name: 'ElDialog' })
|
||||
expect(overlay.exists()).toBe(true)
|
||||
expect(overlay.classes()).toContain('is-penetrable')
|
||||
|
||||
await overlay.trigger('click')
|
||||
await wrapper.find('button').trigger('click')
|
||||
expect(dialog.vm.visible).toBe(true)
|
||||
expect(onClick).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe('life cycles', () => {
|
||||
|
||||
@@ -68,6 +68,10 @@ export const dialogProps = buildProps({
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/**
|
||||
* @description whether the mask is penetrable
|
||||
*/
|
||||
modalPenetrable: Boolean,
|
||||
/**
|
||||
* @description the Time(milliseconds) before open
|
||||
*/
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
v-show="visible"
|
||||
custom-mask-event
|
||||
:mask="modal"
|
||||
:overlay-class="modalClass"
|
||||
:overlay-class="[
|
||||
modalClass ?? '',
|
||||
`${ns.namespace.value}-modal-dialog`,
|
||||
ns.is('penetrable', penetrable),
|
||||
]"
|
||||
:z-index="zIndex"
|
||||
>
|
||||
<div
|
||||
@@ -138,6 +142,10 @@ const overlayEvent = useSameTarget(onModalClick)
|
||||
|
||||
const draggable = computed(() => props.draggable && !props.fullscreen)
|
||||
|
||||
const penetrable = computed(
|
||||
() => props.modalPenetrable && !props.modal && !props.fullscreen
|
||||
)
|
||||
|
||||
const resetPosition = () => {
|
||||
dialogContentRef.value?.resetPosition()
|
||||
}
|
||||
|
||||
@@ -128,6 +128,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
.#{$namespace}-modal-dialog {
|
||||
&.is-penetrable {
|
||||
pointer-events: none;
|
||||
|
||||
.#{$namespace}-dialog {
|
||||
pointer-events: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.#{$namespace}-overlay-dialog {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
|
||||
Reference in New Issue
Block a user