PronounsPage/components/Lightbox.vue
2024-05-20 12:53:15 +02:00

107 lines
2.4 KiB
Vue

<template>
<div ref="wrapper" :class="['lightbox-wrapper', currentUrl === undefined ? 'd-none' : '']" @click.self="hide">
<div ref="inner" :class="['lightbox-inner', 'align-items-center']" @click.self="hide">
<img ref="image" class="lightbox-image" :src="currentUrl">
</div>
<span class="lightbox-menu">
<span class="lightbox-close fal fa-times" @click="hide"></span>
</span>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
interface Data {
currentUrl: string | undefined;
}
interface Refs {
inner: HTMLDataElement;
}
export default Vue.extend({
data(): Data {
return {
currentUrl: undefined,
};
},
computed: {
$tRefs(): Refs {
return this.$refs as unknown as Refs;
},
},
mounted() {
this.$eventHub.$on('lightbox', this.show);
document.body.addEventListener('keyup', (e) => {
if (!this.currentUrl) {
return;
}
if (e.keyCode === 27) { // ESC
this.hide();
e.preventDefault();
e.stopPropagation();
}
});
},
methods: {
show(url: string): void {
this.currentUrl = url;
this.$tRefs.inner.focus();
},
hide(): void {
this.currentUrl = undefined;
this.$tRefs.inner.blur();
},
},
});
</script>
<style lang="scss" scoped>
@import "../assets/variables";
.lightbox-wrapper {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.75);
z-index: 10000;
padding: 2*$spacer 2*$spacer;
@include media-breakpoint-up('sm') {
padding: 2*$spacer 4*$spacer;
}
.lightbox-inner {
width: 100%;
height: 100%;
overflow-y: auto;
display: flex;
justify-content: center;
align-items: flex-start;
img {
max-width: 100%;
max-height: 100%;
}
}
.lightbox-menu {
position: absolute;
top: $spacer;
right: $spacer;
font-size: 2*$spacer;
color: $white;
}
.lightbox-close {
cursor: pointer;
}
}
</style>