mirror of
https://github.com/pretix/pretix.git
synced 2026-05-05 15:14:04 +00:00
Widget: add lightbox for product images (Z#23123811) (#3439)
This commit is contained in:
committed by
GitHub
parent
586f42557f
commit
1d49c98cf2
@@ -450,7 +450,7 @@ Vue.component('item', {
|
||||
|
||||
// Product description
|
||||
+ '<div class="pretix-widget-item-info-col">'
|
||||
+ '<img :src="item.picture" v-if="item.picture" class="pretix-widget-item-picture">'
|
||||
+ '<a :href="item.picture_fullsize" v-if="item.picture" class="pretix-widget-item-picture-link" @click.prevent.stop="lightbox"><img :src="item.picture" class="pretix-widget-item-picture"></a>'
|
||||
+ '<div class="pretix-widget-item-title-and-description">'
|
||||
+ '<a v-if="item.has_variations && show_toggle" class="pretix-widget-item-title" :href="\'#\' + item.id + \'-variants\'"'
|
||||
+ ' @click.prevent.stop="expand" role="button" tabindex="0"'
|
||||
@@ -530,6 +530,12 @@ Vue.component('item', {
|
||||
methods: {
|
||||
expand: function () {
|
||||
this.expanded = !this.expanded;
|
||||
},
|
||||
lightbox: function () {
|
||||
this.$root.overlay.lightbox = {
|
||||
image: this.item.picture_fullsize,
|
||||
description: this.item.name,
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -784,12 +790,44 @@ var shared_alert_fragment = (
|
||||
+ '</div>'
|
||||
);
|
||||
|
||||
var shared_lightbox_fragment = (
|
||||
'<div :class="lightboxClasses" role="dialog" aria-modal="true" v-if="$root.lightbox" @click="lightboxClose">'
|
||||
+ '<div class="pretix-widget-lightbox-loading" v-if="$root.lightbox?.loading">'
|
||||
+ '<svg width="256" height="256" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path class="pretix-widget-primary-color" d="M1152 896q0-106-75-181t-181-75-181 75-75 181 75 181 181 75 181-75 75-181zm512-109v222q0 12-8 23t-20 13l-185 28q-19 54-39 91 35 50 107 138 10 12 10 25t-9 23q-27 37-99 108t-94 71q-12 0-26-9l-138-108q-44 23-91 38-16 136-29 186-7 28-36 28h-222q-14 0-24.5-8.5t-11.5-21.5l-28-184q-49-16-90-37l-141 107q-10 9-25 9-14 0-25-11-126-114-165-168-7-10-7-23 0-12 8-23 15-21 51-66.5t54-70.5q-27-50-41-99l-183-27q-13-2-21-12.5t-8-23.5v-222q0-12 8-23t19-13l186-28q14-46 39-92-40-57-107-138-10-12-10-24 0-10 9-23 26-36 98.5-107.5t94.5-71.5q13 0 26 10l138 107q44-23 91-38 16-136 29-186 7-28 36-28h222q14 0 24.5 8.5t11.5 21.5l28 184q49 16 90 37l142-107q9-9 24-9 13 0 25 10 129 119 165 170 7 8 7 22 0 12-8 23-15 21-51 66.5t-54 70.5q26 50 41 98l183 28q13 2 21 12.5t8 23.5z"/></svg>'
|
||||
+ '</div>'
|
||||
+ '<div class="pretix-widget-lightbox-inner" @click.stop="">'
|
||||
+ '<figure class="pretix-widget-lightbox-image">'
|
||||
+ '<img :src="$root.lightbox.image" :alt="$root.lightbox.description" @load="lightboxLoaded" ref="lightboxImage">'
|
||||
+ '<figcaption v-if="$root.lightbox.description">{{$root.lightbox.description}}</figcaption>'
|
||||
+ '</figure>'
|
||||
+ '<button type="button" class="pretix-widget-lightbox-close" @click="lightboxClose" aria-label="'+strings.close+'">'
|
||||
+ '<svg height="16" viewBox="0 0 512 512" width="16" xmlns="http://www.w3.org/2000/svg"><path fill="#fff" d="M437.5,386.6L306.9,256l130.6-130.6c14.1-14.1,14.1-36.8,0-50.9c-14.1-14.1-36.8-14.1-50.9,0L256,205.1L125.4,74.5 c-14.1-14.1-36.8-14.1-50.9,0c-14.1,14.1-14.1,36.8,0,50.9L205.1,256L74.5,386.6c-14.1,14.1-14.1,36.8,0,50.9 c14.1,14.1,36.8,14.1,50.9,0L256,306.9l130.6,130.6c14.1,14.1,36.8,14.1,50.9,0C451.5,423.4,451.5,400.6,437.5,386.6z"/></svg>'
|
||||
+ '</button>'
|
||||
+ '</div>'
|
||||
+ '</div>'
|
||||
);
|
||||
|
||||
Vue.component('pretix-overlay', {
|
||||
template: ('<div class="pretix-widget-overlay">'
|
||||
+ shared_iframe_fragment
|
||||
+ shared_alert_fragment
|
||||
+ shared_lightbox_fragment
|
||||
+ '</div>'
|
||||
),
|
||||
watch: {
|
||||
'$root.lightbox': function (newValue, oldValue) {
|
||||
if (newValue) {
|
||||
if (newValue.image != oldValue?.image) {
|
||||
this.$set(newValue, "loading", true);
|
||||
}
|
||||
if (!oldValue) {
|
||||
window.addEventListener('keyup', this.lightboxCloseOnKeyup);
|
||||
}
|
||||
} else {
|
||||
window.removeEventListener('keyup', this.lightboxCloseOnKeyup);
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
frameClasses: function () {
|
||||
return {
|
||||
@@ -803,8 +841,27 @@ Vue.component('pretix-overlay', {
|
||||
'pretix-widget-alert-shown': this.$root.error_message,
|
||||
};
|
||||
},
|
||||
lightboxClasses: function () {
|
||||
return {
|
||||
'pretix-widget-lightbox-holder': true,
|
||||
'pretix-widget-lightbox-shown': this.$root.lightbox,
|
||||
'pretix-widget-lightbox-isloading': this.$root.lightbox?.loading,
|
||||
};
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
lightboxCloseOnKeyup: function (event) {
|
||||
if (event.keyCode === 27) {
|
||||
// abort on ESC-key
|
||||
this.lightboxClose();
|
||||
}
|
||||
},
|
||||
lightboxClose: function () {
|
||||
this.$root.lightbox = null;
|
||||
},
|
||||
lightboxLoaded: function () {
|
||||
this.$root.lightbox.loading = false;
|
||||
},
|
||||
errorClose: function () {
|
||||
this.$root.error_message = null;
|
||||
this.$root.error_url_after = null;
|
||||
@@ -1795,6 +1852,7 @@ var create_overlay = function (app) {
|
||||
error_url_after: null,
|
||||
error_url_after_new_tab: true,
|
||||
error_message: null,
|
||||
lightbox: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -768,6 +768,102 @@
|
||||
}
|
||||
}
|
||||
|
||||
.pretix-widget-lightbox-holder {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
z-index: 16777271;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: opacity 0.5s, visibility 0.5s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.pretix-widget-lightbox-loading svg {
|
||||
margin: 40px;
|
||||
-webkit-animation: pretix-widget-spin 6s linear infinite;
|
||||
-moz-animation: pretix-widget-spin 6s linear infinite;
|
||||
animation: pretix-widget-spin 6s linear infinite;
|
||||
}
|
||||
|
||||
&.pretix-widget-lightbox-shown {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
transition: opacity 0.5s, visibility 0.5s;
|
||||
}
|
||||
|
||||
.pretix-widget-lightbox-inner {
|
||||
position: relative;
|
||||
background: white;
|
||||
border-radius: 5px 5px 5px 5px;
|
||||
-moz-border-radius: 5px 5px 5px 5px;
|
||||
-webkit-border-radius: 5px 5px 5px 5px;
|
||||
box-shadow: 0 4px 18px 0 rgba(0, 0, 0, 0.1), 0 6px 20px 0 rgba(0, 0, 0, 0.09);
|
||||
-webkit-box-shadow: 0 4px 18px 0 rgba(0, 0, 0, 0.1), 0 6px 20px 0 rgba(0, 0, 0, 0.09);
|
||||
-moz-box-shadow: 0 4px 18px 0 rgba(0, 0, 0, 0.1), 0 6px 20px 0 rgba(0, 0, 0, 0.09);
|
||||
box-sizing: border-box;
|
||||
padding: 10px;
|
||||
max-width: 90%;
|
||||
max-height: 90%;
|
||||
}
|
||||
&.pretix-widget-lightbox-isloading .pretix-widget-lightbox-inner {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0,0,0,0);
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.pretix-widget-lightbox-image {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
}
|
||||
.pretix-widget-lightbox-image img {
|
||||
max-width: 80vw;
|
||||
max-height: 80vh;
|
||||
object-fit: scale-down;
|
||||
}
|
||||
.pretix-widget-lightbox-image figcaption {
|
||||
margin: 0.5em 0 0;
|
||||
}
|
||||
|
||||
.pretix-widget-lightbox-close {
|
||||
position: absolute;
|
||||
right: -12px;
|
||||
top: -12px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background: $brand-primary;
|
||||
margin: 0;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
-moz-border-radius: 12px;
|
||||
-webkit-border-radius: 12px;
|
||||
text-align: center;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-family: sans-serif;
|
||||
text-decoration: none;
|
||||
padding: 4px 0;
|
||||
display: inline-block;
|
||||
line-height: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.pretix-widget-lightbox-close svg {
|
||||
display: inline-block;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.pretix-widget-primary-color {
|
||||
/* in SVG */
|
||||
fill: $brand-primary;
|
||||
|
||||
Reference in New Issue
Block a user