<template>
  <transition name="modal">
    <div class="modal-mask">
      <!-- :: styles bootstrap :: -->
      <div
        class="modal fade show"
        style="display: block"
        aria-modal="true"
        role="dialog"
      >
        <div class="modal-dialog" :class="props.modalDialogClass || {}">
          <div class="modal-content">
            <div class="modal-header">
              <slot name="header"></slot>
              <button class="close btn" @click="emits('close')">
                <i class="fa fa-times" aria-hidden="true"></i>
              </button>
            </div>
            <div class="modal-body">
              <div class="body-head">
                <slot name="body-head"></slot>
              </div>
              <slot name="body"></slot>
            </div>
            <div class="modal-footer" v-if="!hideFooter">
              <button class="btn btn-cancel" @click="emits('close')">
                {{ trans(MODAL_ACTION_CLOSE) }}
              </button>
              <slot name="footer"></slot>
            </div>
          </div>
        </div>
      </div>
      <!-- :: end styles bootstrap :: -->
    </div>
  </transition>
</template>

<script lang="ts" setup>
/*
 *    This Modal component is a mix between Vue3 modal implementation
 *    [+] with 'v-if:showModal' directive:parameter, html scope is added/removed not just shown/hidden
 *    [+] with slot we can pass content from parent component
 *    [+] some classes are passed from parent component
 *    and Bootstrap 5 _modal.scss module
 *    [+] using bootstrap css classes, the modal have a responsive behaviour,
 *    [+] modal design can be configured using css classes (size, scroll)
 */
import { trans, MODAL_ACTION_CLOSE } from "translator";
import { defineProps } from "vue";

defineSlots<{
  header?: () => any;
  body?: () => any;
  footer?: () => any;
  "body-head"?: () => any;
}>();

export interface ModalProps {
  modalDialogClass?: string | Record<string, boolean>;
  hideFooter?: boolean;
  show?: boolean;
}

const props = withDefaults(defineProps<ModalProps>(), {
  modalDialogClass: "",
  hideFooter: false,
  show: true,
});

const emits = defineEmits<{
  close: [];
}>();
</script>

<style lang="scss">
/**
    * This is a mask behind the modal.
    */
.modal-mask {
  position: fixed;
  z-index: 9998;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.75);
  transition: opacity 0.3s ease;
}
.modal-header .close {
  border-top-right-radius: 0.3rem;
  margin-right: 0;
  margin-left: auto;
}
/*
   * The following styles are auto-applied to elements with
   * transition="modal" when their visibility is toggled
   * by Vue.js.
   *
   * You can easily play with the modal transition by editing
   * these styles.
   */
.modal-enter {
  opacity: 0;
}
.modal-leave-active {
  opacity: 0;
}
.modal-enter .modal-container,
.modal-leave-active .modal-container {
  -webkit-transform: scale(1.1);
  transform: scale(1.1);
}
h3.modal-title {
  font-size: 1.5rem;
  font-weight: bold;
}
div.modal-footer {
  button:first-child {
    margin-right: auto;
  }
}
</style>
