ngx-edge-slider 2.1.6 → 2.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 3.5 23.71 17">
2
+ <path fill="#212121" fill-rule="evenodd" d="M15.354 3.646a.5.5 0 0 0-.708.708l7.147 7.146H.5a.5.5 0 0 0 0 1h21.293l-7.147 7.146a.5.5 0 0 0 .708.708l8-8 .353-.354-.353-.354-8-8Z" clip-rule="evenodd"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 3.5 23.71 17">
2
+ <path fill="#B3B3B3" fill-rule="evenodd" d="M15.354 3.646a.5.5 0 0 0-.708.708l7.147 7.146H.5a.5.5 0 0 0 0 1h21.293l-7.147 7.146a.5.5 0 0 0 .708.708l8-8 .353-.354-.353-.354-8-8Z" clip-rule="evenodd"/>
3
+ </svg>
@@ -0,0 +1,496 @@
1
+ $base-duration: 300ms;
2
+ $base-ease: cubic-bezier(0.25, 0.46, 0.45, 0.84);
3
+ $thumb-gap: 8px;
4
+ $thumb-size: 80px; // uniform square size for thumbs
5
+ $main-height: 520px; // main slider height
6
+
7
+ :host {
8
+ display: block;
9
+ position: relative; // ✅ anchor for nav
10
+ }
11
+
12
+ /* ---------------- Main Slider ---------------- */
13
+ .slider-main-product {
14
+ display: inline-flex;
15
+ height: $main-height;
16
+ }
17
+
18
+ .slider-main {
19
+ width: 100%;
20
+ height: 600px;
21
+ justify-content: center;
22
+ display: flex;
23
+ }
24
+
25
+ @media (max-width: 577px) {
26
+ .slider-main {
27
+ height: 100%;
28
+ display: block;
29
+ }
30
+ }
31
+
32
+ .slider--main {
33
+ height: 100%;
34
+ overflow: hidden;
35
+
36
+ .slider__wrapper {
37
+ display: flex;
38
+ will-change: transform;
39
+ // transform: translateZ(0);
40
+
41
+ .slide {
42
+ flex: 0 0 100%;
43
+
44
+ .slide-content,
45
+ picture {
46
+ position: relative;
47
+ width: 100%;
48
+ height: 100%;
49
+ display: flex;
50
+ align-items: center;
51
+ justify-content: center;
52
+
53
+ .drag-handle {
54
+ width: 100%;
55
+ height: 100%;
56
+ cursor: grab;
57
+ z-index: 10;
58
+ pointer-events: all;
59
+ }
60
+
61
+ img {
62
+ max-width: 100%;
63
+ max-height: 100%;
64
+ object-fit: contain;
65
+ display: block;
66
+
67
+ transform-origin: center;
68
+ transform: translateZ(0); // 🔴 GPU promote
69
+ pointer-events: none;
70
+ }
71
+ }
72
+ }
73
+ }
74
+ }
75
+
76
+ /* ---------------- Thumbs Slider ---------------- */
77
+ .slider--thumbs {
78
+ margin-top: 24px;
79
+ margin-bottom: 36px;
80
+ height: 70px !important;
81
+
82
+ .slider__wrapper {
83
+ display: flex;
84
+ gap: $thumb-gap;
85
+
86
+ will-change: transform;
87
+ transform: translateZ(0);
88
+ }
89
+
90
+ .slide {
91
+ flex: 0 0 auto;
92
+ pointer-events: auto;
93
+
94
+ .slide-content {
95
+ width: 54px;
96
+ height: 68px;
97
+
98
+ display: flex;
99
+ align-items: center;
100
+ justify-content: center;
101
+
102
+ border: 1px solid #ebebeb;
103
+ cursor: pointer;
104
+
105
+ img {
106
+ max-width: 100%;
107
+ max-height: 100%;
108
+ object-fit: contain;
109
+ display: block;
110
+ transform: scale(0.9); // depth effect
111
+ }
112
+
113
+ &.slide--current {
114
+ border-color: #212121;
115
+ }
116
+ }
117
+ }
118
+ }
119
+
120
+ /* ---------------- Main Slider Container ---------------- */
121
+ .slider {
122
+ width: 100%;
123
+ height: 100%;
124
+ overflow: hidden;
125
+ position: relative;
126
+ touch-action: none; // 🔥 slider owns the gesture
127
+ cursor: grab;
128
+ user-select: none;
129
+ -webkit-user-drag: none;
130
+ -webkit-tap-highlight-color: transparent;
131
+
132
+ &.slider-can-drag {
133
+ cursor: grab;
134
+ }
135
+
136
+ &.slider-is-dragging {
137
+ cursor: grabbing;
138
+ }
139
+
140
+ &.slider-dragged {
141
+ /* optional, e.g., subtle shadow after drag */
142
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
143
+ }
144
+
145
+ &.slider-drag-prevent-click {
146
+ pointer-events: none; /* prevent accidental clicks while dragging */
147
+ }
148
+
149
+ .slider__wrapper {
150
+ display: flex;
151
+ transition: transform $base-duration $base-ease;
152
+ //transition: none !important;
153
+ will-change: transform;
154
+ transform: none;
155
+ width: auto;
156
+ height: 100%;
157
+ //transform: translate3d(0,0,0);
158
+ }
159
+
160
+ .slide {
161
+ display: flex;
162
+ align-items: center;
163
+ justify-content: center;
164
+ height: 100%;
165
+ overflow: hidden;
166
+ flex-shrink: 0;
167
+ position: relative;
168
+ transition: transform $base-duration $base-ease;
169
+ }
170
+ }
171
+
172
+ @media (min-width: 1441px) {
173
+ .slider--thumbs .slide {
174
+ flex: 0 0 20%;
175
+ }
176
+ }
177
+
178
+ @media (max-width: 1024px) {
179
+ .slider--thumbs .slide {
180
+ flex: 0 0 33.333%;
181
+ }
182
+ }
183
+
184
+ @media (max-width: 1023px) {
185
+ .slider--thumbs .slide {
186
+ flex: 0 0 50%;
187
+ }
188
+ }
189
+
190
+ /* ---------------- Optional Arrows ---------------- */
191
+ .slider-arrow-next,
192
+ .slider-arrow-prev {
193
+ position: absolute;
194
+ top: 50%;
195
+ transform: translateY(-50%);
196
+ width: 32px;
197
+ height: 32px;
198
+ background: rgba(255, 255, 255, 0.8) no-repeat center center;
199
+ cursor: pointer;
200
+ z-index: 10;
201
+
202
+ &.next {
203
+ right: 10px;
204
+ }
205
+
206
+ &.prev {
207
+ left: 10px;
208
+ }
209
+ }
210
+
211
+ /* ---------------- Arrows L/R on Thumbs ---------------- */
212
+ .thumbs-wrapper {
213
+ position: relative;
214
+ }
215
+
216
+ .thumb-nav {
217
+ position: absolute;
218
+ top: 50%;
219
+ transform: translateY(-50%);
220
+ z-index: 20;
221
+ width: 48px;
222
+ height: 48px;
223
+
224
+ background: rgba(255, 255, 255, 0.9)
225
+ url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='4.51 0.01 10.99 19.97'%3E%3Cpath fill='%23000' d='m4.508 18.968 1.006 1.006 9.983-9.984L5.514.005 4.508 1.011l8.984 8.984-8.984 8.973Z'/%3E%3C/svg%3E")
226
+ no-repeat center center/11px 18px;
227
+
228
+ font-size: 36px;
229
+ line-height: 56px;
230
+
231
+ opacity: 0; // default hidden
232
+ pointer-events: none; // default non-clickable
233
+ transition: opacity 200ms ease;
234
+
235
+ &.activeArrow {
236
+ opacity: 1;
237
+ pointer-events: all;
238
+ }
239
+
240
+ &--left {
241
+ left: -73px;
242
+ transform: translateY(-50%) rotate(180deg) !important;
243
+ }
244
+
245
+ &--right {
246
+ right: -65px;
247
+ }
248
+ }
249
+
250
+ .slider-pagination {
251
+ .thumb-dots-wrapper {
252
+ display: flex;
253
+ align-items: center;
254
+ justify-content: center;
255
+ gap: 7px;
256
+
257
+ .thumb-dot {
258
+ display: inline-block;
259
+ width: 4px;
260
+ height: 4px;
261
+ margin: 0 0 0 8px;
262
+ border-radius: 50%;
263
+ background: #b3b3b3;
264
+
265
+ &.active {
266
+ background: #212121;
267
+ border: 1px solid #212121;
268
+ }
269
+
270
+ &:hover {
271
+ background: #212121;
272
+ border: 1px solid #212121;
273
+ }
274
+
275
+ &.hidden {
276
+ opacity: 0;
277
+ pointer-events: none;
278
+ }
279
+ }
280
+ }
281
+ }
282
+
283
+ .slider-container {
284
+ position: relative;
285
+ z-index: 10; // base container
286
+
287
+ .slider {
288
+ position: relative;
289
+ z-index: 1; // slider itself below nav buttons
290
+ }
291
+ .slider.slider-is-dragging {
292
+ pointer-events: none; // disables clicks on slides while dragging
293
+ }
294
+ .slider-nav {
295
+ position: absolute;
296
+ inset: 0; // top:0; right:0; bottom:0; left:0
297
+ pointer-events: none; // container itself doesn't block
298
+ z-index: 20; // nav above slider
299
+
300
+ .nav-btn {
301
+ pointer-events: auto; // buttons always clickable
302
+ z-index: 30; // highest layer
303
+
304
+ position: absolute;
305
+
306
+ width: 42px;
307
+ height: 42px;
308
+ border-radius: 2px;
309
+ display: inline-flex;
310
+ align-items: center;
311
+ justify-content: center;
312
+ border: 0;
313
+ cursor: pointer;
314
+ background: transparent;
315
+ font-size: 32px;
316
+ line-height: 1;
317
+ transition:
318
+ transform 0.15s ease,
319
+ opacity 0.15s ease;
320
+
321
+ &:hover {
322
+ transform: translateY(-1px);
323
+ background: rgba(0, 0, 0, 0.6); // slightly darker on hover
324
+ }
325
+
326
+ &.is-hidden {
327
+ color: #a0a0a58d;
328
+ opacity: 0.3;
329
+ cursor: not-allowed;
330
+ pointer-events: auto; // still catches clicks
331
+ }
332
+ }
333
+
334
+ // ---------------- TOP ----------------
335
+ &.nav--top-left {
336
+ .nav-btn--prev {
337
+ top: -50px;
338
+ left: -20px; // outside container large screen
339
+ }
340
+ .nav-btn--next {
341
+ top: -50px;
342
+ left: 42px; // next to prev
343
+ }
344
+ }
345
+
346
+ &.nav--top-center {
347
+ .nav-btn--prev {
348
+ top: -50px;
349
+ left: 50%;
350
+ transform: translateX(-50px); // prev left of center
351
+ }
352
+ .nav-btn--next {
353
+ top: -50px;
354
+ left: 50%;
355
+ transform: translateX(10px); // next right of center
356
+ }
357
+ }
358
+
359
+ &.nav--top-right {
360
+ .nav-btn--prev {
361
+ top: -50px;
362
+ right: 42px; // prev left of next
363
+ }
364
+ .nav-btn--next {
365
+ top: -50px;
366
+ right: -20px; // outside container
367
+ }
368
+ }
369
+
370
+ // ---------------- BOTTOM ----------------
371
+ &.nav--bottom-left {
372
+ .nav-btn--prev {
373
+ bottom: 30px;
374
+ left: -20px; // outside container
375
+ }
376
+ .nav-btn--next {
377
+ bottom: 30px;
378
+ left: 42px; // next to prev
379
+ }
380
+ }
381
+
382
+ &.nav--bottom-center {
383
+ .nav-btn--prev {
384
+ bottom: 30px;
385
+ left: 50%;
386
+ transform: translateX(-50px); // prev left of center
387
+ }
388
+ .nav-btn--next {
389
+ bottom: 30px;
390
+ left: 50%;
391
+ transform: translateX(10px); // next right of center
392
+ }
393
+ }
394
+
395
+ &.nav--bottom-right {
396
+ .nav-btn--prev {
397
+ bottom: 30px;
398
+ right: 42px; // prev left of next
399
+ }
400
+ .nav-btn--next {
401
+ bottom: 30px;
402
+ right: -20px; // outside container
403
+ }
404
+ }
405
+
406
+ // ---------------- CENTER SIDES ----------------
407
+ &.nav--center-sides {
408
+ .nav-btn {
409
+ background: rgba(0, 0, 0, 0.7); // black semi-transparent background
410
+ color: white;
411
+ }
412
+ .nav-btn--prev {
413
+ top: 50%;
414
+ left: -50px; // outside container large screen
415
+ transform: translateY(-50%);
416
+ }
417
+ .nav-btn--next {
418
+ top: 50%;
419
+ right: -50px; // outside container large screen
420
+ transform: translateY(-50%);
421
+ }
422
+ }
423
+
424
+ // ---------------- RESPONSIVE ----------------
425
+ @media (max-width: 1024px) {
426
+ // reduce offsets so buttons stay inside viewport
427
+ .nav--top-left,
428
+ .nav--top-center,
429
+ .nav--top-right,
430
+ .nav--bottom-left,
431
+ .nav--bottom-center,
432
+ .nav--bottom-right,
433
+ .nav--center-sides {
434
+ .nav-btn--prev {
435
+ left: clamp(8px, 5%, 40px);
436
+ right: auto;
437
+ }
438
+ .nav-btn--next {
439
+ right: clamp(8px, 5%, 20px);
440
+ left: auto;
441
+ }
442
+ }
443
+ }
444
+
445
+ @media (max-width: 768px) {
446
+ .nav-btn {
447
+ width: 36px;
448
+ height: 36px;
449
+ font-size: 24px;
450
+ }
451
+ }
452
+
453
+ @media (max-width: 480px) {
454
+ .slider-container {
455
+ .slider-nav.nav--center-sides {
456
+ pointer-events: auto; // make nav container clickable
457
+
458
+ .nav-btn {
459
+ width: 32px;
460
+ height: 32px;
461
+ font-size: 20px;
462
+
463
+ pointer-events: auto; // buttons always catch clicks
464
+ z-index: 20; // ensure above slide content
465
+ background: rgba(0, 0, 0, 0.7); // semi-transparent circle
466
+ color: white;
467
+ }
468
+ }
469
+
470
+ // Make the slide content ignore pointer events **under the nav buttons**
471
+ .slider__wrapper {
472
+ position: relative;
473
+
474
+ .slide-content {
475
+ pointer-events: auto; // normal click on slides
476
+ }
477
+ }
478
+ }
479
+ .nav-btn {
480
+ width: 32px;
481
+ height: 32px;
482
+ font-size: 20px;
483
+ }
484
+
485
+ // keep nav buttons fully inside mobile viewport
486
+ .nav-btn--prev {
487
+ left: 8px !important;
488
+ right: auto !important;
489
+ }
490
+ .nav-btn--next {
491
+ right: 8px !important;
492
+ left: auto !important;
493
+ }
494
+ }
495
+ }
496
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngx-edge-slider",
3
- "version": "2.1.6",
3
+ "version": "2.1.7",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=18.0.0",
6
6
  "@angular/core": ">=18.0.0",