<template>
- <!-- Mask -->
- <div
- class="fixed left-0 top-0 z-50 flex h-dvh w-dvw items-center justify-center bg-theme-background-tint/40 backdrop-blur-sm"
- :class="{ hidden: !isVisible }"
+ <Modal
+ ref="modal"
+ :class="{ 'border border-l-4 border-l-theme-failure': isDanger }"
+ :title="title"
+ :closeHandler="cancelHandler"
>
- <!-- Modal -->
- <div
- class="max-w-96 grow rounded-lg border border-theme-border bg-theme-background px-6 py-4 shadow-lg"
- :class="{ 'border border-l-4 border-l-theme-failure': isDanger }"
- >
- <!-- Title -->
- <div class="mb-6 text-xl">{{ title }}</div>
- <!-- Message -->
- <div class="mb-6">{{ message }}</div>
- <!-- Buttons -->
- <div class="flex justify-end">
- <CustomButton label="Cancel" @click="cancelHandler" class="mr-2" />
- <CustomButton label="Confirm" @click="confirmHandler" isCta />
- </div>
+ <!-- Message -->
+ <div class="mb-6">{{ message }}</div>
+ <!-- Buttons -->
+ <div class="flex justify-end">
+ <CustomButton label="Cancel" @click="cancelHandler" class="mr-2" />
+ <CustomButton label="Confirm" @click="confirmHandler" isCta />
</div>
- </div>
+ </Modal>
</template>
<script setup>
import { ref } from "vue";
import CustomButton from "./CustomButton.vue";
+import Modal from "./Modal.vue";
const props = defineProps({
title: { type: String, default: "Confirmation" },
});
const emit = defineEmits(["confirm", "cancel"]);
-const isVisible = ref(false);
+const modal = ref();
function toggle() {
- isVisible.value = !isVisible.value;
+ modal.value.toggle();
}
function cancelHandler() {
- isVisible.value = false;
+ modal.value.setVisibility(false);
emit("cancel");
}
function confirmHandler() {
- isVisible.value = false;
+ modal.value.setVisibility(false);
emit("confirm");
}
--- /dev/null
+<template>
+ <!-- Mask -->
+ <div
+ class="fixed left-0 top-0 z-50 flex h-dvh w-dvw items-center justify-center bg-theme-background-tint/40 backdrop-blur-sm"
+ :class="{ hidden: !isVisible }"
+ >
+ <!-- Modal -->
+ <div
+ class="max-w-96 grow rounded-lg border border-theme-border bg-theme-background px-6 py-4 shadow-lg"
+ :class="$attrs.class"
+ >
+ <!-- Title -->
+ <div class="mb-6 flex justify-between">
+ <div class="text-xl">{{ title }}</div>
+ <CustomButton :iconPath="mdiWindowClose" @click="close" />
+ </div>
+ <!-- Slot -->
+ <slot></slot>
+ </div>
+ </div>
+</template>
+
+<script setup>
+import { ref } from "vue";
+import { mdiWindowClose } from "@mdi/js";
+
+defineOptions({
+ inheritAttrs: false,
+});
+
+const props = defineProps({
+ closeHandler: Function,
+ modalClasses: String,
+ title: String,
+});
+
+import CustomButton from "./CustomButton.vue";
+
+const isVisible = ref(false);
+
+function toggle() {
+ isVisible.value = !isVisible.value;
+}
+
+function setVisibility(value) {
+ isVisible.value = value;
+}
+
+function close() {
+ if (props.closeHandler) {
+ props.closeHandler();
+ } else {
+ setVisibility(false);
+ }
+}
+
+defineExpose({ toggle, setVisibility });
+</script>