<template>
  <teleport to="body">
    <!-- 遮罩层 -->
    <div
      v-if="isClose2 || isVisible" 
      :class="[
        'popup-overlay',
        isVisible ? 'open' : '',
        isClose2 ? 'close' : '',
      ]" 
      @click="emit('update:show', false)"
    >
      <!-- 弹出框内容 -->
      <div class="popup-content" @click.stop>
        <slot />
      </div>
    </div>
  </teleport>
</template>

<script lang="ts" setup>
import { ref, watch } from 'vue';

const emit = defineEmits([ 'change', 'update:show' ]);

const isVisible = ref(false);
const isClose2 = ref(false);

const props = defineProps({
  show: {
    type: Boolean,
    default: false
  },
})

let timer = 0;

const open = () => {
  if (timer) {
    clearTimeout(timer);
    timer = 0;
  }
  isClose2.value = true;
  timer = setTimeout(() => {
    isClose2.value = false;
    isVisible.value = true;
    timer = 0;
    emit('change', true);
  }, 100);
};
const close = () => {
  if (timer) {
    clearTimeout(timer);
    timer = 0;
  }
  isClose2.value = true;
  isVisible.value = false;
  timer = setTimeout(() => {
    isClose2.value = false;
    timer = 0;
    emit('change', false);
  }, 300);
};

watch(() => props.show, (v) => {
  if (v) {
    open();
  } else {
    close();
  }
}, { immediate: true })

</script>

<style lang="scss">
.popup-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 10;
  opacity: 0;
  transition: all 0.3s ease-in-out;

  &.open {
    opacity: 1;

    .popup-content {
      opacity: 1;
      transform: scale(1);
    }
  }
  &.close {
    pointer-events: none;

    .popup-content {
      opacity: 0;
    }
  }
}
.popup-content {
  position: relative;
  transition: all 0.3s ease-in-out;
  transform: scale(0.9);
}
</style>