mirror of
https://gitee.com/element-plus/element-plus.git
synced 2024-11-30 02:08:12 +08:00
fix(components): [overlay] namespace issue (#11881)
* Fix namespace issue on global components overlay. * Closes #11877
This commit is contained in:
parent
b29d0b9869
commit
3eda7fc603
@ -5,6 +5,7 @@
|
||||
:z-index="zIndex"
|
||||
:overlay-class="[ns.is('message-box'), modalClass]"
|
||||
:mask="modal"
|
||||
is-global
|
||||
>
|
||||
<div
|
||||
role="dialog"
|
||||
@ -471,7 +472,7 @@ export default defineComponent({
|
||||
|
||||
// locks the screen to prevent scroll
|
||||
if (props.lockScroll) {
|
||||
useLockscreen(visible)
|
||||
useLockscreen(visible, { ns })
|
||||
}
|
||||
|
||||
// restore to prev active element.
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { nextTick, ref } from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { describe, expect, test } from 'vitest'
|
||||
import { ElMessageBox } from '@element-plus/components/message-box'
|
||||
import ConfigProvider from '@element-plus/components/config-provider'
|
||||
import Overlay from '../src/overlay'
|
||||
|
||||
const AXIOM = 'Rem is the best girl'
|
||||
@ -42,4 +44,26 @@ describe('Overlay.vue', () => {
|
||||
|
||||
expect(wrapper.find(selector).exists()).toBe(true)
|
||||
})
|
||||
|
||||
test('global', async () => {
|
||||
const testNamespace = 'test'
|
||||
const callout = () => {
|
||||
ElMessageBox.prompt('Title', 'Description')
|
||||
}
|
||||
const wrapper = mount(() => {
|
||||
return (
|
||||
<ConfigProvider namespace={testNamespace}>
|
||||
<button onClick={callout}>{AXIOM}</button>
|
||||
</ConfigProvider>
|
||||
)
|
||||
})
|
||||
|
||||
expect(document.body.querySelector(`.${testNamespace}-overlay`)).toBeNull()
|
||||
await wrapper.find('button').trigger('click')
|
||||
await nextTick()
|
||||
|
||||
expect(
|
||||
document.body.querySelector(`.${testNamespace}-overlay`)
|
||||
).toBeDefined()
|
||||
})
|
||||
})
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { createVNode, defineComponent, h, renderSlot } from 'vue'
|
||||
import { PatchFlags, buildProps, definePropType } from '@element-plus/utils'
|
||||
import { useNamespace, useSameTarget } from '@element-plus/hooks'
|
||||
import { useGlobalComponentSettings } from '@element-plus/components/config-provider'
|
||||
|
||||
import type { CSSProperties, ExtractPropTypes } from 'vue'
|
||||
import type { ZIndexProperty } from 'csstype'
|
||||
@ -24,6 +25,9 @@ export const overlayProps = buildProps({
|
||||
zIndex: {
|
||||
type: definePropType<ZIndexProperty>([String, Number]),
|
||||
},
|
||||
isGlobal: {
|
||||
type: Boolean,
|
||||
},
|
||||
} as const)
|
||||
export type OverlayProps = ExtractPropTypes<typeof overlayProps>
|
||||
|
||||
@ -32,6 +36,8 @@ export const overlayEmits = {
|
||||
}
|
||||
export type OverlayEmits = typeof overlayEmits
|
||||
|
||||
const BLOCK = 'overlay'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ElOverlay',
|
||||
|
||||
@ -39,7 +45,11 @@ export default defineComponent({
|
||||
emits: overlayEmits,
|
||||
|
||||
setup(props, { slots, emit }) {
|
||||
const ns = useNamespace('overlay')
|
||||
// No reactivity on this prop because when its rendering with a global
|
||||
// component, this will be a constant flag.
|
||||
const ns = props.isGlobal
|
||||
? useGlobalComponentSettings(BLOCK).ns
|
||||
: useNamespace(BLOCK)
|
||||
|
||||
const onMaskClick = (e: MouseEvent) => {
|
||||
emit('click', e)
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { defineComponent, nextTick, onMounted, ref } from 'vue'
|
||||
import { computed, defineComponent, nextTick, onMounted, ref } from 'vue'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { hasClass } from '@element-plus/utils'
|
||||
|
||||
import { useLockscreen } from '../use-lockscreen'
|
||||
import { useNamespace } from '../use-namespace'
|
||||
|
||||
const kls = 'el-popup-parent--hidden'
|
||||
|
||||
@ -52,4 +53,31 @@ describe('useLockscreen', () => {
|
||||
expect(hasClass(document.body, kls)).toBe(false)
|
||||
}, 250)
|
||||
})
|
||||
|
||||
it('should render a different namespace than the given one', async () => {
|
||||
const namespace = 'test'
|
||||
const wrapper = mount({
|
||||
setup() {
|
||||
const ns = useNamespace(
|
||||
'lock',
|
||||
computed(() => namespace)
|
||||
)
|
||||
const trigger = ref(false)
|
||||
useLockscreen(trigger, { ns })
|
||||
onMounted(() => {
|
||||
trigger.value = true
|
||||
})
|
||||
return () => () => undefined
|
||||
},
|
||||
})
|
||||
|
||||
mount(wrapper)
|
||||
|
||||
await nextTick()
|
||||
expect(hasClass(document.body, `${namespace}-lock-parent--hidden`)).toBe(
|
||||
true
|
||||
)
|
||||
|
||||
wrapper.unmount()
|
||||
})
|
||||
})
|
||||
|
@ -12,13 +12,22 @@ import {
|
||||
import { useNamespace } from '../use-namespace'
|
||||
|
||||
import type { Ref } from 'vue'
|
||||
import type { UseNamespaceReturn } from '../use-namespace'
|
||||
|
||||
export type UseLockScreenOptions = {
|
||||
ns?: UseNamespaceReturn
|
||||
// shouldLock?: MaybeRef<boolean>
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook that monitoring the ref value to lock or unlock the screen.
|
||||
* When the trigger became true, it assumes modal is now opened and vice versa.
|
||||
* @param trigger {Ref<boolean>}
|
||||
*/
|
||||
export const useLockscreen = (trigger: Ref<boolean>) => {
|
||||
export const useLockscreen = (
|
||||
trigger: Ref<boolean>,
|
||||
options: UseLockScreenOptions = {}
|
||||
) => {
|
||||
if (!isRef(trigger)) {
|
||||
throwError(
|
||||
'[useLockscreen]',
|
||||
@ -26,7 +35,7 @@ export const useLockscreen = (trigger: Ref<boolean>) => {
|
||||
)
|
||||
}
|
||||
|
||||
const ns = useNamespace('popup')
|
||||
const ns = options.ns || useNamespace('popup')
|
||||
|
||||
const hiddenCls = computed(() => ns.bm('parent', 'hidden'))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user