<script setup>
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'

const props = defineProps({
  as: { type: String, default: 'div' },
  delay: { type: Number, default: 0 },
  y: { type: Number, default: 14 },
  once: { type: Boolean, default: true },
  threshold: { type: Number, default: 0.12 },
  rootMargin: { type: String, default: '0px 0px -10% 0px' },
})

const el = ref(null)
const isVisible = ref(false)
let observer = null

onMounted(() => {
  if (typeof window === 'undefined') return
  if (!('IntersectionObserver' in window)) {
    isVisible.value = true
    return
  }

  observer = new IntersectionObserver(
    (entries) => {
      for (const entry of entries) {
        if (!entry.isIntersecting) continue
        isVisible.value = true
        if (props.once && observer) observer.disconnect()
      }
    },
    {
      threshold: props.threshold,
      rootMargin: props.rootMargin,
    },
  )

  if (el.value) observer.observe(el.value)
})

onBeforeUnmount(() => {
  if (observer) observer.disconnect()
})

const styleVars = computed(() => ({
  '--reveal-delay': `${props.delay}ms`,
  '--reveal-y': `${props.y}px`,
}))
</script>

<template>
  <component :is="as" ref="el" class="reveal" :class="{ 'is-visible': isVisible }" :style="styleVars">
    <slot></slot>
  </component>
</template>

