Skip to content

Commit 3a949cc

Browse files
feat: add slider on gallery images
1 parent 1b521a8 commit 3a949cc

File tree

3 files changed

+170
-1
lines changed

3 files changed

+170
-1
lines changed

assets/js/src/shop/app.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,53 @@ function initShop() {
2020
) {
2121
handleExclusiveSlider();
2222
}
23+
24+
if (
25+
document.body.classList.contains('single-product') &&
26+
!document.body.classList.contains('sp-slider-gallery')
27+
) {
28+
handleGallerySlider();
29+
}
30+
}
31+
32+
const svgs = {
33+
vertical: {
34+
prev: '<svg width="30px" height="25px" viewBox="0 0 50 80" xml:space="preserve" style="transform: rotate(90deg)"><polyline fill="none" stroke="currentColor" stroke-width="7" points="25,76 10,38 25,0"/></svg>',
35+
next: '<svg width="30px" height="25px" viewBox="0 0 50 80" xml:space="preserve" style="transform: rotate(90deg)"><polyline fill="none" stroke="currentColor" stroke-width="7" points="25,0 40,38 25,75"/></svg>',
36+
},
37+
horizontal: {
38+
prev: '<svg width="25px" height="30px" viewBox="0 0 50 80" xml:space="preserve"><polyline fill="none" stroke="currentColor" stroke-width="7" points="25,76 10,38 25,0"/></svg>',
39+
next: '<svg width="25px" height="30px" viewBox="0 0 50 80" xml:space="preserve"><polyline fill="none" stroke="currentColor" stroke-width="7" points="25,0 40,38 25,75"/></svg>',
40+
},
41+
};
42+
43+
/**
44+
* Add prev and next
45+
*
46+
* @param {Node} targetNode
47+
* @param {Node} slider
48+
* @param {string} vertical
49+
*/
50+
function addNextPrev(targetNode, slider, vertical = false) {
51+
const next = document.createElement('span');
52+
const prev = document.createElement('span');
53+
54+
next.classList.add('neve-slider-control', 'next');
55+
prev.classList.add('neve-slider-control', 'prev');
56+
57+
prev.innerHTML = vertical ? svgs.vertical.prev : svgs.horizontal.prev;
58+
next.innerHTML = vertical ? svgs.vertical.next : svgs.horizontal.next;
59+
60+
prev.addEventListener('click', function () {
61+
slider.goTo('prev');
62+
});
63+
64+
next.addEventListener('click', function () {
65+
slider.goTo('next');
66+
});
67+
68+
targetNode.parentNode.insertBefore(prev, targetNode);
69+
targetNode.parentNode.appendChild(next);
2370
}
2471

2572
/**
@@ -89,6 +136,36 @@ function handleExclusiveSlider() {
89136
}
90137
}
91138

139+
/**
140+
* Handle Gallery Image Slider
141+
*/
142+
function handleGallerySlider() {
143+
const galleryNav = document.querySelector('ol.flex-control-nav');
144+
145+
if (!galleryNav) return;
146+
147+
const isDesktop = window.innerWidth >= 992;
148+
149+
const slider = tns({
150+
container: 'ol.flex-control-nav',
151+
items: isDesktop ? 4 : 4,
152+
axis: isDesktop ? 'vertical' : 'horizontal',
153+
slideBy: 'page',
154+
rewind: true,
155+
loop: false,
156+
nav: false,
157+
controls: false,
158+
mouseDrag: true,
159+
speed: 400,
160+
});
161+
162+
addNextPrev(
163+
document.querySelector('.woocommerce-product-gallery .tns-inner'),
164+
slider,
165+
isDesktop
166+
);
167+
}
168+
92169
/**
93170
* Run JS on load.
94171
*/

assets/scss/components/compat/woocommerce/_sidebar.scss

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,95 @@
5656
}
5757
}
5858
}
59+
60+
body:not(.sp-slider-gallery) {
61+
62+
.tns-ovh {
63+
display: flex;
64+
align-items: center;
65+
cursor: pointer;
66+
}
67+
68+
.tns-inner {
69+
overflow: hidden;
70+
}
71+
72+
/* Make WooCommerce gallery vertical on desktop */
73+
@media (min-width: 992px) {
74+
75+
.tns-visually-hidden {
76+
display: none;
77+
}
78+
79+
div.product {
80+
81+
.onsale {
82+
left: 110px;
83+
}
84+
85+
div.images {
86+
display: flex;
87+
flex-direction: row-reverse;
88+
gap: 10px;
89+
90+
.tns-ovh {
91+
width: 100px;
92+
flex-direction: column;
93+
position: relative;
94+
95+
.neve-slider-control {
96+
position: absolute;
97+
z-index: 1;
98+
color: var(--nv-text-color);
99+
width: 100px;
100+
text-align: center;
101+
102+
&.prev {
103+
top: 0;
104+
}
105+
106+
&.next {
107+
bottom: 0;
108+
}
109+
110+
&:hover {
111+
background-color: var(--nv-site-bg);
112+
}
113+
}
114+
}
115+
116+
.flex-viewport {
117+
width: calc(100% - 100px);
118+
}
119+
120+
.flex-control-nav {
121+
display: flex;
122+
flex-direction: column;
123+
width: 100px;
124+
margin-top: -5px;
125+
126+
li {
127+
width: 100px;
128+
}
129+
}
130+
}
131+
}
132+
}
133+
134+
/* On mobile, keep horizontal layout */
135+
@media (max-width: 991px) {
136+
137+
div.product {
138+
139+
div.images {
140+
141+
.flex-control-nav {
142+
flex-direction: row;
143+
width: auto;
144+
max-height: none;
145+
display: flex;
146+
}
147+
}
148+
}
149+
}
150+
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
{
3636
"gzip": false,
3737
"running": false,
38-
"limit": "33 KB",
38+
"limit": "34.1 KB",
3939
"path": "assets/js/build/modern/shop.js"
4040
},
4141
{

0 commit comments

Comments
 (0)