<template>
  <Teleport to="body">
    <Transition name="sheet">
      <div
        v-if="modelValue"
        class="sheet-overlay"
        role="dialog"
        :aria-label="label"
        aria-modal="true"
        @click.self="close"
        @keydown.esc="close"
      >
        <div
          ref="sheetRef"
          class="sheet"
          tabindex="-1"
        >
          <div class="sheet__handle" aria-hidden="true" />
          <slot />
        </div>
      </div>
    </Transition>
  </Teleport>
</template>

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

const props = defineProps<{
  modelValue: boolean
  label: string
}>()

const emit = defineEmits<{
  'update:modelValue': [value: boolean]
}>()

const sheetRef = ref<HTMLElement | null>(null)
let triggerEl: HTMLElement | null = null

function close() {
  emit('update:modelValue', false)
}

watch(() => props.modelValue, async (open) => {
  if (open) {
    triggerEl = document.activeElement as HTMLElement
    await nextTick()
    sheetRef.value?.focus()
  } else {
    triggerEl?.focus()
    triggerEl = null
  }
})
</script>

<style scoped lang="scss">
.sheet-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  z-index: 100;
  display: flex;
  align-items: flex-end;
}

.sheet {
  width: 100%;
  background: var(--color-surface);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: var(--space-3) var(--space-4) var(--space-6);
  max-height: 90dvh;
  overflow-y: auto;
  outline: none;

  &__handle {
    width: 36px;
    height: 4px;
    border-radius: var(--radius-full);
    background: var(--color-border);
    margin: 0 auto var(--space-4);
  }
}

.sheet-enter-active {
  .sheet-overlay { transition: background var(--duration-base) var(--ease-out); }
  .sheet { transition: transform 250ms var(--ease-out); }
}

.sheet-leave-active {
  .sheet { transition: transform 200ms ease-in; }
  transition: background 200ms ease-in;
}

.sheet-enter-from {
  background: rgba(0, 0, 0, 0);
  .sheet { transform: translateY(100%); }
}

.sheet-leave-to {
  background: rgba(0, 0, 0, 0);
  .sheet { transform: translateY(100%); }
}
</style>
