traxxx/assets/components/album/album.vue

210 lines
3.4 KiB
Vue

<template>
<teleport to="body">
<div class="album">
<div class="album-header">
<h3 class="album-title">{{ title }}</h3>
<Icon
icon="cross2"
class="close"
@click.native="$emit('close')"
/>
</div>
<div
class="album-items"
:class="{ portrait }"
>
<div
v-for="item in items"
:key="item.id"
class="item-container"
>
<a
:href="`${path}/${item.path}`"
class="item-link"
target="_blank"
>
<img
:src="`${path}/${item.thumbnail}`"
:title="item.comment"
loading="lazy"
class="item image"
>
<span
v-if="comments && item.comment"
class="item-comment"
>{{ item.comment }}</span>
</a>
</div>
</div>
</div>
</teleport>
</template>
<script>
export default {
props: {
items: {
type: Array,
default: () => [],
},
title: {
type: String,
default: null,
},
path: {
type: String,
default: '/media',
},
portrait: {
type: Boolean,
default: false,
},
comments: {
type: Boolean,
default: true,
},
},
emits: ['close'],
};
</script>
<style lang="scss" scoped>
@import 'breakpoints';
.album {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
position: fixed;
top: 0;
left: 0;
background: var(--shadow-extreme);
z-index: 10;
}
.album-header {
display: flex;
justify-content: space-between;
flex-shrink: 0;
}
.album-title {
display: block;
flex-grow: 1;
align-items: center;
padding: 1rem;
margin: 0;
color: var(--text-light);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-align: center;
text-transform: capitalize;
}
.close {
width: 1.5rem;
height: 1.5rem;
padding: 1rem;
fill: var(--lighten);
&:hover {
cursor: pointer;
fill: var(--text-light);
}
}
.album-items {
display: grid;
align-items: center;
justify-content: center;
grid-template-columns: repeat(auto-fit, minmax(25rem, 1fr));
grid-gap: 0 1rem;
padding: 1rem;
margin: auto 0;
overflow-y: auto;
&.portrait {
grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
}
}
.item-container {
display: flex;
align-items: center;
justify-content: center;
}
.item-link {
position: relative;
margin: 0 0 1rem 0;
overflow: hidden;
&:hover .item-comment {
transform: translateY(0);
}
}
.item {
max-width: 100%;
max-height: 100%;
}
.item-comment {
width: 100%;
position: absolute;
bottom: 0;
left: 0;
box-sizing: border-box;
padding: .5rem;
color: var(--text-light);
background: var(--shadow);
font-size: .9rem;
text-shadow: 0 0 3px var(--shadow);
white-space: normal;
line-height: 1.25;
transform: translateY(100%);
transition: transform .25s ease;
}
@media(max-width: $breakpoint-giga) {
.album-items.portrait {
grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
}
}
@media(max-width: $breakpoint-mega) {
.album-items.portrait {
grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
}
}
@media(max-width: $breakpoint-kilo) {
.album-items {
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
}
}
@media(max-width: $breakpoint) {
.album-items {
grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
}
}
@media(max-width: $breakpoint-micro) {
.album-items {
grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
}
}
@media(max-width: $breakpoint-pico) {
.album-items {
grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr));
}
}
</style>