Skip to content
Snippets Groups Projects
ADialog.vue 2.11 KiB
Newer Older
  • Learn to ignore specific revisions
  • <template>
      <dialog
        v-if="modelValue"
        ref="dialogEl"
        class="tw-shadow-xl tw-border tw-border-gray-200 tw-rounded tw-max-w-[95%] tw-p-0 tw-bg-white tw-z-30 tw-flex tw-flex-col"
    
      >
        <header class="tw-flex tw-justify-between tw-p-4 flex-none">
          <div>
    
            <slot name="header" :title-class="titleClass">
              <p :class="titleClass">{{ title }}</p>
            </slot>
    
          </div>
          <button
            type="button"
    
            class="btn btn-default tw-w-8 tw-h-8 tw-ml-auto tw-p-0 tw-flex tw-items-center tw-justify-center tw-rounded-full"
    
            tabindex="-1"
            @click="close"
          >
            <icon-system-uicons-close class="tw-w-6 tw-h-6" />
          </button>
        </header>
        <div class="tw-flex-1 tw-p-4 tw-overflow-y-auto tw-shadow-inner">
          <slot />
        </div>
        <footer
          v-if="slots.footer"
          class="tw-flex-none tw-p-4 tw-border-0 tw-border-t tw-border-solid tw-border-gray-200"
        >
          <slot name="footer" />
        </footer>
      </dialog>
    </template>
    
    <script lang="ts" setup>
    import { nextTick, ref, useSlots, watch } from 'vue'
    
    
    const titleClass = 'tw-text-lg tw-font-semibold tw-m-0'
    
    
    const props = withDefaults(
      defineProps<{
        modelValue: boolean
        isModal?: boolean
    
        isModal: false,
      },
    )
    const emit = defineEmits<{
      (e: 'update:modelValue', value: boolean): void
    }>()
    const slots = useSlots()
    
    const dialogEl = ref<HTMLDialogElement>()
    
    function close() {
      emit('update:modelValue', false)
    }
    
    watch(
      () => props.modelValue,
      async (isOpen) => {
        if (isOpen && !dialogEl.value) {
          await nextTick()
        }
    
        if (dialogEl.value) {
          if (isOpen) {
            if (props.isModal) {
              dialogEl.value.showModal()
            } else {
              dialogEl.value.show()
            }
          } else if (dialogEl.value.open) {
            dialogEl.value.close()
          }
        }
      },
      { immediate: true },
    )
    </script>
    
    <script lang="ts">
    export default {
      compatConfig: {
        MODE: 3,
      },
    }
    </script>
    
    <style lang="postcss" scoped>
    dialog::backdrop {
      background: rgba(0, 0, 0, 0.5);
      backdrop-filter: blur(3px);
    }
    </style>