<script setup lang="ts">
import { nextTick, watch } from 'vue'
import Dialog from 'primevue/dialog'

const props=withDefaults(defineProps<{open:boolean;title:string;size?:'sm'|'md'|'lg';closeable?:boolean;restoreFocus?:boolean}>(),{size:'md',closeable:true,restoreFocus:true})
const emit=defineEmits<{ 'update:open':[boolean] }>()
const widths={sm:'420px',md:'600px',lg:'840px'} as const
let restoreTarget:HTMLElement|null=null

function captureRestoreTarget(){
  const active=document.activeElement
  restoreTarget=active instanceof HTMLElement&&active!==document.body?active:null
}
async function restoreFocus(){
  const target=restoreTarget
  restoreTarget=null
  if(!props.restoreFocus||!target||!target.isConnected||target.matches(':disabled,[aria-disabled="true"]'))return
  await nextTick()
  target.focus({preventScroll:true})
}
watch(()=>props.open,(open,previous)=>{if(open&&!previous)captureRestoreTarget()})
</script>

<template>
  <Dialog
    :visible="open"
    modal
    :header="title"
    :closable="closeable"
    :style="{width:widths[size]}"
    data-kbx-component="dialog"
    @update:visible="emit('update:open',$event)"
    @hide="restoreFocus"
  >
    <slot/>
    <template #footer><slot name="footer"/></template>
  </Dialog>
</template>
