79 lines
1.9 KiB
Vue
79 lines
1.9 KiB
Vue
<template>
|
|
<div v-if="state.show !== 'none'" class="modal is-active" @click="dismiss()">
|
|
<div class="modal-background" />
|
|
|
|
<div class="modal-content" style="max-height: 100vh; max-width: 95vw">
|
|
<template v-if="state.show === 'loading'">
|
|
<progress class="progress is-primary" max="100" />
|
|
</template>
|
|
<template v-else-if="state.show === 'image'">
|
|
<figure>
|
|
<figcaption class="tag is-primary">
|
|
{{ state.caption }}
|
|
</figcaption>
|
|
<div class="image is-square">
|
|
<img :src="state.src" alt="Kalender-Bild" />
|
|
</div>
|
|
</figure>
|
|
</template>
|
|
</div>
|
|
|
|
<button
|
|
v-if="state.show !== 'loading'"
|
|
class="modal-close is-large has-background-primary"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { onBeforeUnmount, onMounted, ref } from "vue";
|
|
|
|
type ModalState =
|
|
| { show: "none" }
|
|
| { show: "loading" }
|
|
| { show: "image"; src: string; caption: string };
|
|
|
|
const state = ref<ModalState>({ show: "none" });
|
|
|
|
export type HMultiModal = {
|
|
show_image(src: string, caption: string): void;
|
|
show_loading(): void;
|
|
hide(): void;
|
|
};
|
|
|
|
const emit = defineEmits<{
|
|
(event: "handle", handle: HMultiModal): void;
|
|
}>();
|
|
|
|
function hide(): void {
|
|
state.value = { show: "none" };
|
|
}
|
|
|
|
function dismiss(): void {
|
|
if (state.value.show !== "loading") {
|
|
hide();
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
emit("handle", {
|
|
show_image(src: string, caption: string = ""): void {
|
|
state.value = { show: "image", src: src, caption: caption };
|
|
},
|
|
show_loading(): void {
|
|
state.value = { show: "loading" };
|
|
},
|
|
hide,
|
|
});
|
|
|
|
const on_keydown = (e: KeyboardEvent) => {
|
|
if (e.key === "Escape") dismiss();
|
|
};
|
|
|
|
window.addEventListener("keydown", on_keydown);
|
|
|
|
onBeforeUnmount(() => {
|
|
window.removeEventListener("keydown", on_keydown);
|
|
});
|
|
});
|
|
</script>
|