mirror of
https://gitee.com/element-plus/element-plus.git
synced 2024-12-14 09:20:51 +08:00
62 lines
1.3 KiB
TypeScript
62 lines
1.3 KiB
TypeScript
|
import { h, ref, Teleport, onUnmounted } from 'vue'
|
||
|
import { NOOP } from '@vue/shared'
|
||
|
import isServer from '@element-plus/utils/isServer'
|
||
|
import { createGlobalNode, removeGlobalNode } from '@element-plus/utils/global-nodes'
|
||
|
|
||
|
import type { VNode, Ref } from 'vue'
|
||
|
|
||
|
export default (contentRenderer: () => VNode, appendToBody: Ref<boolean>) => {
|
||
|
const isTeleportVisible = ref(false)
|
||
|
|
||
|
if (isServer) {
|
||
|
return {
|
||
|
isTeleportVisible,
|
||
|
showTeleport: NOOP,
|
||
|
hideTeleport: NOOP,
|
||
|
renderTeleport: NOOP,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
let $el: HTMLElement = null
|
||
|
|
||
|
const showTeleport = () => {
|
||
|
isTeleportVisible.value = true
|
||
|
// this allows the delayed showing strategy since the the content itself could be enterable
|
||
|
// e.g. el-popper
|
||
|
if ($el !== null) return
|
||
|
|
||
|
$el = createGlobalNode()
|
||
|
}
|
||
|
|
||
|
const hideTeleport = () => {
|
||
|
isTeleportVisible.value = false
|
||
|
if ($el !== null) {
|
||
|
removeGlobalNode($el)
|
||
|
$el = null
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const renderTeleport = () => {
|
||
|
return appendToBody.value !== true
|
||
|
? contentRenderer()
|
||
|
: isTeleportVisible.value
|
||
|
? [
|
||
|
h(
|
||
|
Teleport,
|
||
|
{ to: $el },
|
||
|
contentRenderer(),
|
||
|
),
|
||
|
]
|
||
|
: void 0
|
||
|
}
|
||
|
|
||
|
onUnmounted(hideTeleport)
|
||
|
|
||
|
return {
|
||
|
isTeleportVisible,
|
||
|
showTeleport,
|
||
|
hideTeleport,
|
||
|
renderTeleport,
|
||
|
}
|
||
|
}
|