index.ts 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. import { computed, onBeforeMount } from 'vue'
  2. import { isClient } from '@vueuse/core'
  3. import { useGetDerivedNamespace } from '../use-namespace'
  4. import { useIdInjection } from '../use-id'
  5. let cachedContainer: HTMLElement
  6. export const usePopperContainerId = () => {
  7. const namespace = useGetDerivedNamespace()
  8. const idInjection = useIdInjection()
  9. const id = computed(() => {
  10. return `${namespace.value}-popper-container-${idInjection.prefix}`
  11. })
  12. const selector = computed(() => `#${id.value}`)
  13. return {
  14. id,
  15. selector,
  16. }
  17. }
  18. const createContainer = (id: string) => {
  19. const container = document.createElement('div')
  20. container.id = id
  21. document.body.appendChild(container)
  22. return container
  23. }
  24. export const usePopperContainer = () => {
  25. const { id, selector } = usePopperContainerId()
  26. onBeforeMount(() => {
  27. if (!isClient) return
  28. // This is for bypassing the error that when under testing env, we often encounter
  29. // document.body.innerHTML = '' situation
  30. // for this we need to disable the caching since it's not really needed
  31. if (
  32. process.env.NODE_ENV === 'test' ||
  33. (!cachedContainer && !document.body.querySelector(selector.value))
  34. ) {
  35. cachedContainer = createContainer(id.value)
  36. }
  37. })
  38. return {
  39. id,
  40. selector,
  41. }
  42. }