react-image-gallery 1.2.11 → 1.3.0

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.
@@ -1,42 +1,31 @@
1
- import clsx from 'clsx';
2
- import React from 'react';
3
- import throttle from 'lodash-es/throttle';
4
- import debounce from 'lodash-es/debounce';
5
- import isEqual from 'react-fast-compare';
6
- import ResizeObserver from 'resize-observer-polyfill';
7
- import {
8
- LEFT,
9
- RIGHT,
10
- UP,
11
- DOWN,
12
- } from 'react-swipeable';
13
- import {
14
- arrayOf,
15
- bool,
16
- func,
17
- number,
18
- oneOf,
19
- shape,
20
- string,
21
- } from 'prop-types';
22
- import Item from 'src/Item';
23
- import Fullscreen from 'src/controls/Fullscreen';
24
- import LeftNav from 'src/controls/LeftNav';
25
- import RightNav from 'src/controls/RightNav';
26
- import PlayPause from 'src/controls/PlayPause';
27
- import SwipeWrapper from 'src/SwipeWrapper';
1
+ import clsx from "clsx";
2
+ import React from "react";
3
+ import throttle from "lodash-es/throttle";
4
+ import debounce from "lodash-es/debounce";
5
+ import isEqual from "react-fast-compare";
6
+ import ResizeObserver from "resize-observer-polyfill";
7
+ import { LEFT, RIGHT, UP, DOWN } from "react-swipeable";
8
+ import { arrayOf, bool, func, number, oneOf, shape, string } from "prop-types";
9
+ import Item from "src/components/Item";
10
+ import Fullscreen from "src/components/controls/Fullscreen";
11
+ import LeftNav from "src/components/controls/LeftNav";
12
+ import RightNav from "src/components/controls/RightNav";
13
+ import PlayPause from "src/components/controls/PlayPause";
14
+ import SwipeWrapper from "src/components/SwipeWrapper";
28
15
 
29
16
  const screenChangeEvents = [
30
- 'fullscreenchange',
31
- 'MSFullscreenChange',
32
- 'mozfullscreenchange',
33
- 'webkitfullscreenchange',
17
+ "fullscreenchange",
18
+ "MSFullscreenChange",
19
+ "mozfullscreenchange",
20
+ "webkitfullscreenchange",
34
21
  ];
35
22
 
36
- const imageSetType = arrayOf(shape({
37
- srcSet: string,
38
- media: string,
39
- }));
23
+ const imageSetType = arrayOf(
24
+ shape({
25
+ srcSet: string,
26
+ media: string,
27
+ })
28
+ );
40
29
 
41
30
  function isEnterOrSpaceKey(event) {
42
31
  const key = parseInt(event.keyCode || event.which || 0, 10);
@@ -91,7 +80,9 @@ class ImageGallery extends React.Component {
91
80
  // Used to update the throttle if slideDuration changes
92
81
  this.unthrottledSlideToIndex = this.slideToIndex;
93
82
  this.slideToIndex = throttle(
94
- this.unthrottledSlideToIndex, props.slideDuration, { trailing: false },
83
+ this.unthrottledSlideToIndex,
84
+ props.slideDuration,
85
+ { trailing: false }
95
86
  );
96
87
 
97
88
  if (props.lazyLoad) {
@@ -105,12 +96,14 @@ class ImageGallery extends React.Component {
105
96
  this.play();
106
97
  }
107
98
  if (useWindowKeyDown) {
108
- window.addEventListener('keydown', this.handleKeyDown);
99
+ window.addEventListener("keydown", this.handleKeyDown);
109
100
  } else {
110
- this.imageGallery.current.addEventListener('keydown', this.handleKeyDown);
101
+ this.imageGallery.current.addEventListener("keydown", this.handleKeyDown);
111
102
  }
112
- window.addEventListener('mousedown', this.handleMouseDown);
113
- window.addEventListener('touchmove', this.handleTouchMove, { passive: false });
103
+ window.addEventListener("mousedown", this.handleMouseDown);
104
+ window.addEventListener("touchmove", this.handleTouchMove, {
105
+ passive: false,
106
+ });
114
107
  // we're using resize observer to help with detecting containers size changes as images load
115
108
  this.initSlideWrapperResizeObserver(this.imageGallerySlideWrapper);
116
109
  this.initThumbnailWrapperResizeObserver(this.thumbnailsWrapper);
@@ -132,10 +125,14 @@ class ImageGallery extends React.Component {
132
125
  const itemsSizeChanged = prevProps.items.length !== items.length;
133
126
  const itemsChanged = !isEqual(prevProps.items, items);
134
127
  const startIndexUpdated = prevProps.startIndex !== startIndex;
135
- const thumbnailsPositionChanged = prevProps.thumbnailPosition !== thumbnailPosition;
128
+ const thumbnailsPositionChanged =
129
+ prevProps.thumbnailPosition !== thumbnailPosition;
136
130
  const showThumbnailsChanged = prevProps.showThumbnails !== showThumbnails;
137
131
 
138
- if (slideInterval !== prevProps.slideInterval || slideDuration !== prevProps.slideDuration) {
132
+ if (
133
+ slideInterval !== prevProps.slideInterval ||
134
+ slideDuration !== prevProps.slideDuration
135
+ ) {
139
136
  // refresh setInterval
140
137
  if (isPlaying) {
141
138
  this.pause();
@@ -170,7 +167,9 @@ class ImageGallery extends React.Component {
170
167
  // if slideDuration changes, update slideToIndex throttle
171
168
  if (prevProps.slideDuration !== slideDuration) {
172
169
  this.slideToIndex = throttle(
173
- this.unthrottledSlideToIndex, slideDuration, { trailing: false },
170
+ this.unthrottledSlideToIndex,
171
+ slideDuration,
172
+ { trailing: false }
174
173
  );
175
174
  }
176
175
  if (lazyLoad && (!prevProps.lazyLoad || itemsChanged)) {
@@ -179,11 +178,17 @@ class ImageGallery extends React.Component {
179
178
 
180
179
  if (useWindowKeyDown !== prevProps.useWindowKeyDown) {
181
180
  if (useWindowKeyDown) {
182
- this.imageGallery.current.removeEventListener('keydown', this.handleKeyDown);
183
- window.addEventListener('keydown', this.handleKeyDown);
181
+ this.imageGallery.current.removeEventListener(
182
+ "keydown",
183
+ this.handleKeyDown
184
+ );
185
+ window.addEventListener("keydown", this.handleKeyDown);
184
186
  } else {
185
- window.removeEventListener('keydown', this.handleKeyDown);
186
- this.imageGallery.current.addEventListener('keydown', this.handleKeyDown);
187
+ window.removeEventListener("keydown", this.handleKeyDown);
188
+ this.imageGallery.current.addEventListener(
189
+ "keydown",
190
+ this.handleKeyDown
191
+ );
187
192
  }
188
193
  }
189
194
 
@@ -192,15 +197,15 @@ class ImageGallery extends React.Component {
192
197
  // do not transition when new items are added
193
198
  this.setState({
194
199
  currentIndex: startIndex,
195
- slideStyle: { transition: 'none' },
200
+ slideStyle: { transition: "none" },
196
201
  });
197
202
  }
198
203
  }
199
204
 
200
205
  componentWillUnmount() {
201
206
  const { useWindowKeyDown } = this.props;
202
- window.removeEventListener('mousedown', this.handleMouseDown);
203
- window.removeEventListener('touchmove', this.handleTouchMove);
207
+ window.removeEventListener("mousedown", this.handleMouseDown);
208
+ window.removeEventListener("touchmove", this.handleTouchMove);
204
209
  this.removeScreenChangeEvent();
205
210
  this.removeResizeObserver();
206
211
  if (this.playPauseIntervalId) {
@@ -211,9 +216,12 @@ class ImageGallery extends React.Component {
211
216
  window.clearTimeout(this.transitionTimer);
212
217
  }
213
218
  if (useWindowKeyDown) {
214
- window.removeEventListener('keydown', this.handleKeyDown);
219
+ window.removeEventListener("keydown", this.handleKeyDown);
215
220
  } else {
216
- this.imageGallery.current.removeEventListener('keydown', this.handleKeyDown);
221
+ this.imageGallery.current.removeEventListener(
222
+ "keydown",
223
+ this.handleKeyDown
224
+ );
217
225
  }
218
226
  }
219
227
 
@@ -236,15 +244,39 @@ class ImageGallery extends React.Component {
236
244
  }
237
245
 
238
246
  onThumbnailClick(event, index) {
239
- const { onThumbnailClick } = this.props;
247
+ const { onThumbnailClick, items } = this.props;
248
+ const { currentIndex } = this.state;
240
249
  // blur element to remove outline cause by focus
241
250
  event.target.parentNode.parentNode.blur();
242
- this.slideToIndex(index, event);
251
+ if (currentIndex !== index) {
252
+ if (items.length === 2) {
253
+ this.slideToIndexWithStyleReset(index, event);
254
+ } else {
255
+ this.slideToIndex(index, event);
256
+ }
257
+ }
243
258
  if (onThumbnailClick) {
244
259
  onThumbnailClick(event, index);
245
260
  }
246
261
  }
247
262
 
263
+ onBulletClick = (event, index) => {
264
+ const { onBulletClick, items } = this.props;
265
+ const { currentIndex } = this.state;
266
+ // blur element to remove outline caused by focus
267
+ event.target.blur();
268
+ if (currentIndex !== index) {
269
+ if (items.length === 2) {
270
+ this.slideToIndexWithStyleReset(index, event);
271
+ } else {
272
+ this.slideToIndex(index, event);
273
+ }
274
+ }
275
+ if (onBulletClick) {
276
+ onBulletClick(event, index);
277
+ }
278
+ };
279
+
248
280
  onThumbnailMouseOver(event, index) {
249
281
  if (this.thumbnailMouseOverTimer) {
250
282
  window.clearTimeout(this.thumbnailMouseOverTimer);
@@ -290,7 +322,6 @@ class ImageGallery extends React.Component {
290
322
 
291
323
  if (disableThumbnailScroll) return 0;
292
324
 
293
-
294
325
  if (thumbsElement) {
295
326
  // total scroll required to see the last thumbnail
296
327
  if (this.isThumbnailVertical()) {
@@ -299,7 +330,10 @@ class ImageGallery extends React.Component {
299
330
  }
300
331
  hiddenScroll = thumbsElement.scrollHeight - thumbnailsWrapperHeight;
301
332
  } else {
302
- if (thumbsElement.scrollWidth <= thumbnailsWrapperWidth || thumbnailsWrapperWidth <= 0) {
333
+ if (
334
+ thumbsElement.scrollWidth <= thumbnailsWrapperWidth ||
335
+ thumbnailsWrapperWidth <= 0
336
+ ) {
303
337
  return 0;
304
338
  }
305
339
  hiddenScroll = thumbsElement.scrollWidth - thumbnailsWrapperWidth;
@@ -312,23 +346,50 @@ class ImageGallery extends React.Component {
312
346
  return 0;
313
347
  }
314
348
 
349
+ getThumbnailPositionClassName(thumbnailPosition) {
350
+ // get the specific thumbnailPosition className
351
+ const leftClassName = "image-gallery-thumbnails-left";
352
+ const rightClassName = "image-gallery-thumbnails-right";
353
+ const bottomClassName = "image-gallery-thumbnails-bottom";
354
+ const topClassName = "image-gallery-thumbnails-top";
355
+
356
+ switch (thumbnailPosition) {
357
+ case "left":
358
+ thumbnailPosition = ` ${leftClassName}`;
359
+ break;
360
+ case "right":
361
+ thumbnailPosition = ` ${rightClassName}`;
362
+ break;
363
+ case "bottom":
364
+ thumbnailPosition = ` ${bottomClassName}`;
365
+ break;
366
+ case "top":
367
+ thumbnailPosition = ` ${topClassName}`;
368
+ break;
369
+ default:
370
+ break;
371
+ }
372
+
373
+ return thumbnailPosition;
374
+ }
375
+
315
376
  getAlignmentClassName(index) {
316
377
  // Necessary for lazing loading
317
378
  const { currentIndex } = this.state;
318
379
  const { infinite, items } = this.props;
319
- let alignment = '';
320
- const leftClassName = 'left';
321
- const centerClassName = 'center';
322
- const rightClassName = 'right';
380
+ let alignment = "";
381
+ const leftClassName = "image-gallery-left";
382
+ const centerClassName = "image-gallery-center";
383
+ const rightClassName = "image-gallery-right";
323
384
 
324
385
  switch (index) {
325
- case (currentIndex - 1):
386
+ case currentIndex - 1:
326
387
  alignment = ` ${leftClassName}`;
327
388
  break;
328
- case (currentIndex):
389
+ case currentIndex:
329
390
  alignment = ` ${centerClassName}`;
330
391
  break;
331
- case (currentIndex + 1):
392
+ case currentIndex + 1:
332
393
  alignment = ` ${rightClassName}`;
333
394
  break;
334
395
  default:
@@ -358,39 +419,44 @@ class ImageGallery extends React.Component {
358
419
  const secondSlideIsNextSlide = index === 1 && currentIndex === 0;
359
420
  const swipingEnded = currentSlideOffset === 0;
360
421
  const baseTranslateX = -100 * currentIndex;
361
- let translateX = baseTranslateX + (index * 100) + currentSlideOffset;
422
+ let translateX = baseTranslateX + index * 100 + currentSlideOffset;
362
423
 
363
424
  // keep track of user swiping direction
364
425
  // important to understand how to translateX based on last direction
365
426
  if (currentSlideOffset > 0) {
366
- this.direction = 'left';
427
+ this.direction = "left";
367
428
  } else if (currentSlideOffset < 0) {
368
- this.direction = 'right';
429
+ this.direction = "right";
369
430
  }
370
431
 
371
-
372
432
  // when swiping between two slides make sure the next and prev slides
373
433
  // are on both left and right
374
- if (secondSlideIsNextSlide && currentSlideOffset > 0) { // swiping right
434
+ if (secondSlideIsNextSlide && currentSlideOffset > 0) {
435
+ // swiping right
375
436
  translateX = -100 + currentSlideOffset;
376
437
  }
377
- if (firstSlideIsNextSlide && currentSlideOffset < 0) { // swiping left
438
+ if (firstSlideIsNextSlide && currentSlideOffset < 0) {
439
+ // swiping left
378
440
  translateX = 100 + currentSlideOffset;
379
441
  }
380
442
 
381
443
  if (indexChanged) {
382
444
  // when indexChanged move the slide to the correct side
383
- if (firstSlideWasPrevSlide && swipingEnded && this.direction === 'left') {
445
+ if (firstSlideWasPrevSlide && swipingEnded && this.direction === "left") {
384
446
  translateX = 100;
385
- } else if (secondSlideWasPrevSlide && swipingEnded && this.direction === 'right') {
447
+ } else if (
448
+ secondSlideWasPrevSlide &&
449
+ swipingEnded &&
450
+ this.direction === "right"
451
+ ) {
386
452
  translateX = -100;
387
453
  }
388
454
  } else {
389
455
  // keep the slide on the correct side if the swipe was not successful
390
- if (secondSlideIsNextSlide && swipingEnded && this.direction === 'left') {
456
+ if (secondSlideIsNextSlide && swipingEnded && this.direction === "left") {
391
457
  translateX = -100;
392
458
  }
393
- if (firstSlideIsNextSlide && swipingEnded && this.direction === 'right') {
459
+ if (firstSlideIsNextSlide && swipingEnded && this.direction === "right") {
394
460
  translateX = 100;
395
461
  }
396
462
  }
@@ -408,18 +474,14 @@ class ImageGallery extends React.Component {
408
474
 
409
475
  getSlideStyle(index) {
410
476
  const { currentIndex, currentSlideOffset, slideStyle } = this.state;
411
- const {
412
- infinite,
413
- items,
414
- useTranslate3D,
415
- isRTL,
416
- } = this.props;
477
+ const { infinite, items, useTranslate3D, isRTL } = this.props;
417
478
  const baseTranslateX = -100 * currentIndex;
418
479
  const totalSlides = items.length - 1;
419
480
 
420
481
  // calculates where the other slides belong based on currentIndex
421
482
  // if it is RTL the base line should be reversed
422
- let translateX = (baseTranslateX + (index * 100)) * (isRTL ? -1 : 1) + currentSlideOffset;
483
+ let translateX =
484
+ (baseTranslateX + index * 100) * (isRTL ? -1 : 1) + currentSlideOffset;
423
485
 
424
486
  if (infinite && items.length > 2) {
425
487
  if (currentIndex === 0 && index === totalSlides) {
@@ -448,13 +510,13 @@ class ImageGallery extends React.Component {
448
510
  const isVisible = this.isSlideVisible(index);
449
511
 
450
512
  return {
451
- display: isVisible ? 'inherit' : 'none',
513
+ display: isVisible ? "inherit" : "none",
452
514
  WebkitTransform: translate,
453
515
  MozTransform: translate,
454
516
  msTransform: translate,
455
517
  OTransform: translate,
456
518
  transform: translate,
457
- ...slideStyle
519
+ ...slideStyle,
458
520
  };
459
521
  }
460
522
 
@@ -467,7 +529,9 @@ class ImageGallery extends React.Component {
467
529
  let translate;
468
530
  const { useTranslate3D, isRTL } = this.props;
469
531
  const { thumbsTranslate, thumbsStyle } = this.state;
470
- const verticalTranslateValue = isRTL ? thumbsTranslate * -1 : thumbsTranslate;
532
+ const verticalTranslateValue = isRTL
533
+ ? thumbsTranslate * -1
534
+ : thumbsTranslate;
471
535
 
472
536
  if (this.isThumbnailVertical()) {
473
537
  translate = `translate(0, ${thumbsTranslate}px)`;
@@ -514,11 +578,13 @@ class ImageGallery extends React.Component {
514
578
 
515
579
  items.forEach((item, index) => {
516
580
  const alignment = this.getAlignmentClassName(index);
517
- const originalClass = item.originalClass ? ` ${item.originalClass}` : '';
518
- const thumbnailClass = item.thumbnailClass ? ` ${item.thumbnailClass}` : '';
581
+ const originalClass = item.originalClass ? ` ${item.originalClass}` : "";
582
+ const thumbnailClass = item.thumbnailClass
583
+ ? ` ${item.thumbnailClass}`
584
+ : "";
519
585
  const handleRenderItem = item.renderItem || renderItem || this.renderItem;
520
- const handleRenderThumbInner = item.renderThumbInner
521
- || renderThumbInner || this.renderThumbInner;
586
+ const handleRenderThumbInner =
587
+ item.renderThumbInner || renderThumbInner || this.renderThumbInner;
522
588
 
523
589
  const showItem = !lazyLoad || alignment || this.lazyLoaded[index];
524
590
  if (showItem && lazyLoad && !this.lazyLoaded[index]) {
@@ -544,7 +610,11 @@ class ImageGallery extends React.Component {
544
610
  onMouseLeave={onMouseLeave}
545
611
  role="button"
546
612
  >
547
- {showItem ? handleRenderItem(item) : <div style={{ height: '100%' }} />}
613
+ {showItem ? (
614
+ handleRenderItem(item)
615
+ ) : (
616
+ <div style={{ height: "100%" }} />
617
+ )}
548
618
  </div>
549
619
  );
550
620
 
@@ -553,53 +623,44 @@ class ImageGallery extends React.Component {
553
623
  // Don't add thumbnails if there is none
554
624
  if (showThumbnails && item.thumbnail) {
555
625
  const igThumbnailClass = clsx(
556
- 'image-gallery-thumbnail',
626
+ "image-gallery-thumbnail",
557
627
  thumbnailClass,
558
- { active: currentIndex === index },
628
+ { active: currentIndex === index }
559
629
  );
560
630
  thumbnails.push(
561
631
  <button
562
632
  key={`thumbnail-${index}`}
563
633
  type="button"
564
634
  tabIndex="0"
565
- aria-pressed={currentIndex === index ? 'true' : 'false'}
635
+ aria-pressed={currentIndex === index ? "true" : "false"}
566
636
  aria-label={`Go to Slide ${index + 1}`}
567
637
  className={igThumbnailClass}
568
- onMouseLeave={slideOnThumbnailOver ? this.onThumbnailMouseLeave : null}
569
- onMouseOver={event => this.handleThumbnailMouseOver(event, index)}
570
- onFocus={event => this.handleThumbnailMouseOver(event, index)}
571
- onKeyUp={event => this.handleThumbnailKeyUp(event, index)}
572
- onClick={event => this.onThumbnailClick(event, index)}
638
+ onMouseLeave={
639
+ slideOnThumbnailOver ? this.onThumbnailMouseLeave : null
640
+ }
641
+ onMouseOver={(event) => this.handleThumbnailMouseOver(event, index)}
642
+ onFocus={(event) => this.handleThumbnailMouseOver(event, index)}
643
+ onKeyUp={(event) => this.handleThumbnailKeyUp(event, index)}
644
+ onClick={(event) => this.onThumbnailClick(event, index)}
573
645
  >
574
646
  {handleRenderThumbInner(item)}
575
- </button>,
647
+ </button>
576
648
  );
577
649
  }
578
650
 
579
651
  if (showBullets) {
580
- // generate bullet elements and store them in array
581
- const bulletOnClick = (event) => {
582
- if (item.bulletOnClick) {
583
- item.bulletOnClick({ item, itemIndex: index, currentIndex });
584
- }
585
- // blur element to remove outline caused by focus
586
- event.target.blur();
587
- return this.slideToIndex.call(this, index, event);
588
- };
589
- const igBulletClass = clsx(
590
- 'image-gallery-bullet',
591
- item.bulletClass,
592
- { active: currentIndex === index },
593
- );
652
+ const igBulletClass = clsx("image-gallery-bullet", item.bulletClass, {
653
+ active: currentIndex === index,
654
+ });
594
655
  bullets.push(
595
656
  <button
596
657
  type="button"
597
658
  key={`bullet-${index}`}
598
659
  className={igBulletClass}
599
- onClick={bulletOnClick}
600
- aria-pressed={currentIndex === index ? 'true' : 'false'}
660
+ onClick={(event) => this.onBulletClick(event, index)}
661
+ aria-pressed={currentIndex === index ? "true" : "false"}
601
662
  aria-label={`Go to Slide ${index + 1}`}
602
- />,
663
+ />
603
664
  );
604
665
  }
605
666
  });
@@ -621,13 +682,20 @@ class ImageGallery extends React.Component {
621
682
  const totalSlides = items.length - 1;
622
683
 
623
684
  // we want to show the in between slides transition
624
- const slidingMoreThanOneSlideLeftOrRight = Math.abs(previousIndex - currentIndex) > 1;
625
- const notGoingFromFirstToLast = !(previousIndex === 0 && currentIndex === totalSlides);
626
- const notGoingFromLastToFirst = !(previousIndex === totalSlides && currentIndex === 0);
685
+ const slidingMoreThanOneSlideLeftOrRight =
686
+ Math.abs(previousIndex - currentIndex) > 1;
687
+ const notGoingFromFirstToLast = !(
688
+ previousIndex === 0 && currentIndex === totalSlides
689
+ );
690
+ const notGoingFromLastToFirst = !(
691
+ previousIndex === totalSlides && currentIndex === 0
692
+ );
627
693
 
628
- return slidingMoreThanOneSlideLeftOrRight
629
- && notGoingFromFirstToLast
630
- && notGoingFromLastToFirst;
694
+ return (
695
+ slidingMoreThanOneSlideLeftOrRight &&
696
+ notGoingFromFirstToLast &&
697
+ notGoingFromLastToFirst
698
+ );
631
699
  }
632
700
 
633
701
  isFirstOrLastSlide(index) {
@@ -638,14 +706,15 @@ class ImageGallery extends React.Component {
638
706
  return isLastSlide || isFirstSlide;
639
707
  }
640
708
 
641
-
642
709
  slideIsTransitioning(index) {
643
710
  /*
644
711
  returns true if the gallery is transitioning and the index is not the
645
712
  previous or currentIndex
646
713
  */
647
714
  const { isTransitioning, previousIndex, currentIndex } = this.state;
648
- const indexIsNotPreviousOrNextSlide = !(index === previousIndex || index === currentIndex);
715
+ const indexIsNotPreviousOrNextSlide = !(
716
+ index === previousIndex || index === currentIndex
717
+ );
649
718
  return isTransitioning && indexIsNotPreviousOrNextSlide;
650
719
  }
651
720
 
@@ -662,8 +731,10 @@ class ImageGallery extends React.Component {
662
731
  so unless were going from first to last or vice versa we don't want the first
663
732
  or last slide to show up during the transition
664
733
  */
665
- return !this.slideIsTransitioning(index)
666
- || (this.ignoreIsTransitioning() && !this.isFirstOrLastSlide(index));
734
+ return (
735
+ !this.slideIsTransitioning(index) ||
736
+ (this.ignoreIsTransitioning() && !this.isFirstOrLastSlide(index))
737
+ );
667
738
  }
668
739
 
669
740
  slideThumbnailBar() {
@@ -689,13 +760,13 @@ class ImageGallery extends React.Component {
689
760
  }
690
761
 
691
762
  canSlideLeft() {
692
- const { infinite, isRTL } = this.props;
693
- return infinite || (isRTL ? this.canSlideNext() : this.canSlidePrevious());
763
+ const { infinite } = this.props;
764
+ return infinite || this.canSlidePrevious();
694
765
  }
695
766
 
696
767
  canSlideRight() {
697
- const { infinite, isRTL } = this.props;
698
- return infinite || (isRTL ? this.canSlidePrevious() : this.canSlideNext());
768
+ const { infinite } = this.props;
769
+ return infinite || this.canSlideNext();
699
770
  }
700
771
 
701
772
  canSlidePrevious() {
@@ -711,12 +782,8 @@ class ImageGallery extends React.Component {
711
782
 
712
783
  handleSwiping({ event, absX, dir }) {
713
784
  const { disableSwipe, stopPropagation } = this.props;
714
- const {
715
- galleryWidth,
716
- isTransitioning,
717
- swipingUpDown,
718
- swipingLeftRight,
719
- } = this.state;
785
+ const { galleryWidth, isTransitioning, swipingUpDown, swipingLeftRight } =
786
+ this.state;
720
787
 
721
788
  // if the initial swiping is up/down prevent moving the slides until swipe ends
722
789
  if ((dir === UP || dir === DOWN || swipingUpDown) && !swipingLeftRight) {
@@ -740,7 +807,7 @@ class ImageGallery extends React.Component {
740
807
  if (!isTransitioning) {
741
808
  const side = dir === RIGHT ? 1 : -1;
742
809
 
743
- let currentSlideOffset = (absX / galleryWidth * 100);
810
+ let currentSlideOffset = (absX / galleryWidth) * 100;
744
811
  if (Math.abs(currentSlideOffset) >= 100) {
745
812
  currentSlideOffset = 100;
746
813
  }
@@ -759,16 +826,8 @@ class ImageGallery extends React.Component {
759
826
  }
760
827
  }
761
828
 
762
- handleThumbnailSwiping({
763
- event,
764
- absX,
765
- absY,
766
- dir,
767
- }) {
768
- const {
769
- stopPropagation,
770
- swipingThumbnailTransitionDuration,
771
- } = this.props;
829
+ handleThumbnailSwiping({ event, absX, absY, dir }) {
830
+ const { stopPropagation, swipingThumbnailTransitionDuration } = this.props;
772
831
  const {
773
832
  thumbsSwipedTranslate,
774
833
  thumbnailsWrapperHeight,
@@ -779,7 +838,10 @@ class ImageGallery extends React.Component {
779
838
 
780
839
  if (this.isThumbnailVertical()) {
781
840
  // if the initial swiping is left/right, prevent moving the thumbnail bar until swipe ends
782
- if ((dir === LEFT || dir === RIGHT || swipingLeftRight) && !swipingUpDown) {
841
+ if (
842
+ (dir === LEFT || dir === RIGHT || swipingLeftRight) &&
843
+ !swipingUpDown
844
+ ) {
783
845
  if (!swipingLeftRight) {
784
846
  this.setState({ swipingLeftRight: true });
785
847
  }
@@ -815,19 +877,21 @@ class ImageGallery extends React.Component {
815
877
  if (this.isThumbnailVertical()) {
816
878
  const slideY = dir === DOWN ? absY : -absY;
817
879
  thumbsTranslate = thumbsSwipedTranslate + slideY;
818
- totalSwipeableLength = thumbsElement.scrollHeight
819
- - thumbnailsWrapperHeight + emptySpaceMargin;
880
+ totalSwipeableLength =
881
+ thumbsElement.scrollHeight - thumbnailsWrapperHeight + emptySpaceMargin;
820
882
  hasSwipedPassedEnd = Math.abs(thumbsTranslate) > totalSwipeableLength;
821
883
  hasSwipedPassedStart = thumbsTranslate > emptySpaceMargin;
822
- isThumbnailBarSmallerThanContainer = thumbsElement.scrollHeight <= thumbnailsWrapperHeight;
884
+ isThumbnailBarSmallerThanContainer =
885
+ thumbsElement.scrollHeight <= thumbnailsWrapperHeight;
823
886
  } else {
824
887
  const slideX = dir === RIGHT ? absX : -absX;
825
888
  thumbsTranslate = thumbsSwipedTranslate + slideX;
826
- totalSwipeableLength = thumbsElement.scrollWidth
827
- - thumbnailsWrapperWidth + emptySpaceMargin;
889
+ totalSwipeableLength =
890
+ thumbsElement.scrollWidth - thumbnailsWrapperWidth + emptySpaceMargin;
828
891
  hasSwipedPassedEnd = Math.abs(thumbsTranslate) > totalSwipeableLength;
829
892
  hasSwipedPassedStart = thumbsTranslate > emptySpaceMargin;
830
- isThumbnailBarSmallerThanContainer = thumbsElement.scrollWidth <= thumbnailsWrapperWidth;
893
+ isThumbnailBarSmallerThanContainer =
894
+ thumbsElement.scrollWidth <= thumbnailsWrapperWidth;
831
895
  }
832
896
 
833
897
  if (isThumbnailBarSmallerThanContainer) {
@@ -899,7 +963,7 @@ class ImageGallery extends React.Component {
899
963
  // if it is RTL the direction is reversed
900
964
  const swipeDirection = (dir === LEFT ? 1 : -1) * (isRTL ? -1 : 1);
901
965
  const isSwipeUpOrDown = dir === UP || dir === DOWN;
902
- const isLeftRightFlick = (velocity > flickThreshold) && !isSwipeUpOrDown;
966
+ const isLeftRightFlick = velocity > flickThreshold && !isSwipeUpOrDown;
903
967
  this.handleOnSwipedTo(swipeDirection, isLeftRightFlick);
904
968
  }
905
969
 
@@ -913,8 +977,10 @@ class ImageGallery extends React.Component {
913
977
  }
914
978
 
915
979
  // If we can't swipe left or right, stay in the current index (noop)
916
- if ((swipeDirection === -1 && !this.canSlideLeft())
917
- || (swipeDirection === 1 && !this.canSlideRight())) {
980
+ if (
981
+ (swipeDirection === -1 && !this.canSlideLeft()) ||
982
+ (swipeDirection === 1 && !this.canSlideRight())
983
+ ) {
918
984
  slideTo = currentIndex;
919
985
  }
920
986
 
@@ -931,14 +997,14 @@ class ImageGallery extends React.Component {
931
997
 
932
998
  handleMouseDown() {
933
999
  // keep track of mouse vs keyboard usage for a11y
934
- this.imageGallery.current.classList.add('image-gallery-using-mouse');
1000
+ this.imageGallery.current.classList.add("image-gallery-using-mouse");
935
1001
  }
936
1002
 
937
1003
  handleKeyDown(event) {
938
1004
  const { disableKeyDown, useBrowserFullscreen } = this.props;
939
1005
  const { isFullscreen } = this.state;
940
1006
  // keep track of mouse vs keyboard usage for a11y
941
- this.imageGallery.current.classList.remove('image-gallery-using-mouse');
1007
+ this.imageGallery.current.classList.remove("image-gallery-using-mouse");
942
1008
 
943
1009
  if (disableKeyDown) return;
944
1010
  const LEFT_ARROW = 37;
@@ -977,17 +1043,27 @@ class ImageGallery extends React.Component {
977
1043
  }
978
1044
 
979
1045
  removeThumbnailsResizeObserver() {
980
- if (this.resizeThumbnailWrapperObserver
981
- && this.thumbnailsWrapper && this.thumbnailsWrapper.current) {
982
- this.resizeThumbnailWrapperObserver.unobserve(this.thumbnailsWrapper.current);
1046
+ if (
1047
+ this.resizeThumbnailWrapperObserver &&
1048
+ this.thumbnailsWrapper &&
1049
+ this.thumbnailsWrapper.current
1050
+ ) {
1051
+ this.resizeThumbnailWrapperObserver.unobserve(
1052
+ this.thumbnailsWrapper.current
1053
+ );
983
1054
  this.resizeThumbnailWrapperObserver = null;
984
1055
  }
985
1056
  }
986
1057
 
987
1058
  removeResizeObserver() {
988
- if (this.resizeSlideWrapperObserver
989
- && this.imageGallerySlideWrapper && this.imageGallerySlideWrapper.current) {
990
- this.resizeSlideWrapperObserver.unobserve(this.imageGallerySlideWrapper.current);
1059
+ if (
1060
+ this.resizeSlideWrapperObserver &&
1061
+ this.imageGallerySlideWrapper &&
1062
+ this.imageGallerySlideWrapper.current
1063
+ ) {
1064
+ this.resizeSlideWrapperObserver.unobserve(
1065
+ this.imageGallerySlideWrapper.current
1066
+ );
991
1067
  this.resizeSlideWrapperObserver = null;
992
1068
  }
993
1069
  this.removeThumbnailsResizeObserver();
@@ -1005,9 +1081,13 @@ class ImageGallery extends React.Component {
1005
1081
  this.setState({ galleryWidth: this.imageGallery.current.offsetWidth });
1006
1082
  }
1007
1083
 
1008
- if (this.imageGallerySlideWrapper && this.imageGallerySlideWrapper.current) {
1084
+ if (
1085
+ this.imageGallerySlideWrapper &&
1086
+ this.imageGallerySlideWrapper.current
1087
+ ) {
1009
1088
  this.setState({
1010
- gallerySlideWrapperHeight: this.imageGallerySlideWrapper.current.offsetHeight,
1089
+ gallerySlideWrapperHeight:
1090
+ this.imageGallerySlideWrapper.current.offsetHeight,
1011
1091
  });
1012
1092
  }
1013
1093
 
@@ -1018,23 +1098,33 @@ class ImageGallery extends React.Component {
1018
1098
  initSlideWrapperResizeObserver(element) {
1019
1099
  if (element && !element.current) return;
1020
1100
  // keeps track of gallery height changes for vertical thumbnail height
1021
- this.resizeSlideWrapperObserver = new ResizeObserver(debounce((entries) => {
1022
- if (!entries) return;
1023
- entries.forEach((entry) => {
1024
- this.setState({ thumbnailsWrapperWidth: entry.contentRect.width }, this.handleResize);
1025
- });
1026
- }, 50));
1101
+ this.resizeSlideWrapperObserver = new ResizeObserver(
1102
+ debounce((entries) => {
1103
+ if (!entries) return;
1104
+ entries.forEach((entry) => {
1105
+ this.setState(
1106
+ { thumbnailsWrapperWidth: entry.contentRect.width },
1107
+ this.handleResize
1108
+ );
1109
+ });
1110
+ }, 50)
1111
+ );
1027
1112
  this.resizeSlideWrapperObserver.observe(element.current);
1028
1113
  }
1029
1114
 
1030
1115
  initThumbnailWrapperResizeObserver(element) {
1031
1116
  if (element && !element.current) return; // thumbnails are not always available
1032
- this.resizeThumbnailWrapperObserver = new ResizeObserver(debounce((entries) => {
1033
- if (!entries) return;
1034
- entries.forEach((entry) => {
1035
- this.setState({ thumbnailsWrapperHeight: entry.contentRect.height }, this.handleResize);
1036
- });
1037
- }, 50));
1117
+ this.resizeThumbnailWrapperObserver = new ResizeObserver(
1118
+ debounce((entries) => {
1119
+ if (!entries) return;
1120
+ entries.forEach((entry) => {
1121
+ this.setState(
1122
+ { thumbnailsWrapperHeight: entry.contentRect.height },
1123
+ this.handleResize
1124
+ );
1125
+ });
1126
+ }, 50)
1127
+ );
1038
1128
  this.resizeThumbnailWrapperObserver.observe(element.current);
1039
1129
  }
1040
1130
 
@@ -1055,16 +1145,16 @@ class ImageGallery extends React.Component {
1055
1145
  }
1056
1146
  }
1057
1147
 
1058
-
1059
1148
  handleScreenChange() {
1060
1149
  /*
1061
1150
  handles screen change events that the browser triggers e.g. esc key
1062
1151
  */
1063
1152
  const { onScreenChange, useBrowserFullscreen } = this.props;
1064
- const fullScreenElement = document.fullscreenElement
1065
- || document.msFullscreenElement
1066
- || document.mozFullScreenElement
1067
- || document.webkitFullscreenElement;
1153
+ const fullScreenElement =
1154
+ document.fullscreenElement ||
1155
+ document.msFullscreenElement ||
1156
+ document.mozFullScreenElement ||
1157
+ document.webkitFullscreenElement;
1068
1158
 
1069
1159
  // check if screenchange element is the gallery
1070
1160
  const isFullscreen = this.imageGallery.current === fullScreenElement;
@@ -1097,51 +1187,63 @@ class ImageGallery extends React.Component {
1097
1187
  onBeforeSlide(nextIndex);
1098
1188
  }
1099
1189
 
1100
- this.setState({
1101
- previousIndex: currentIndex,
1102
- currentIndex: nextIndex,
1103
- isTransitioning: nextIndex !== currentIndex,
1104
- currentSlideOffset: 0,
1105
- slideStyle: { transition: `all ${slideDuration}ms ease-out` },
1106
- }, this.onSliding);
1190
+ this.setState(
1191
+ {
1192
+ previousIndex: currentIndex,
1193
+ currentIndex: nextIndex,
1194
+ isTransitioning: nextIndex !== currentIndex,
1195
+ currentSlideOffset: 0,
1196
+ slideStyle: { transition: `all ${slideDuration}ms ease-out` },
1197
+ },
1198
+ this.onSliding
1199
+ );
1107
1200
  }
1108
1201
  }
1109
1202
 
1110
1203
  slideLeft(event) {
1111
1204
  const { isRTL } = this.props;
1112
- this.slideTo(event, isRTL ? 'right' : 'left')
1205
+ this.slideTo(event, isRTL ? "right" : "left");
1113
1206
  }
1114
1207
 
1115
1208
  slideRight(event) {
1116
1209
  const { isRTL } = this.props;
1117
- this.slideTo(event, isRTL ? 'left' : 'right')
1210
+ this.slideTo(event, isRTL ? "left" : "right");
1118
1211
  }
1119
1212
 
1120
1213
  slideTo(event, direction) {
1121
- const { currentIndex, currentSlideOffset, isTransitioning } = this.state;
1214
+ const { currentIndex, isTransitioning } = this.state;
1122
1215
  const { items } = this.props;
1123
- const nextIndex = currentIndex + (direction === 'left' ? -1 : 1)
1216
+ const nextIndex = currentIndex + (direction === "left" ? -1 : 1);
1124
1217
 
1125
1218
  if (isTransitioning) return;
1126
1219
 
1127
1220
  if (items.length === 2) {
1128
- /*
1129
- When there are only 2 slides fake a tiny swipe to get the slides
1130
- on the correct side for transitioning
1131
- */
1132
- this.setState({
1133
- // this will reset once index changes
1134
- currentSlideOffset: currentSlideOffset + (direction === 'left' ? 0.001 : -0.001),
1135
- slideStyle: { transition: 'none' }, // move the slide over instantly
1136
- }, () => {
1137
- // add 25ms timeout to avoid delay in moving slides over
1138
- window.setTimeout(() => this.slideToIndex(nextIndex, event), 25);
1139
- });
1221
+ this.slideToIndexWithStyleReset(nextIndex, event);
1140
1222
  } else {
1141
1223
  this.slideToIndex(nextIndex, event);
1142
1224
  }
1143
1225
  }
1144
1226
 
1227
+ slideToIndexWithStyleReset(nextIndex, event) {
1228
+ /*
1229
+ When there are only 2 slides fake a tiny swipe to get the slides
1230
+ on the correct side for transitioning
1231
+ */
1232
+ const { currentIndex, currentSlideOffset } = this.state;
1233
+ this.setState(
1234
+ {
1235
+ // this will reset once index changes
1236
+ currentSlideOffset:
1237
+ currentSlideOffset + (currentIndex > nextIndex ? 0.001 : -0.001),
1238
+ slideStyle: { transition: "none" }, // move the slide over instantly
1239
+ },
1240
+ () => {
1241
+ // add 25ms timeout to avoid delay in moving slides over
1242
+ window.setTimeout(() => this.slideToIndex(nextIndex, event), 25);
1243
+ }
1244
+ );
1245
+ }
1246
+
1145
1247
  handleThumbnailMouseOver(event, index) {
1146
1248
  const { slideOnThumbnailOver } = this.props;
1147
1249
  if (slideOnThumbnailOver) this.onThumbnailMouseOver(event, index);
@@ -1162,7 +1264,7 @@ class ImageGallery extends React.Component {
1162
1264
 
1163
1265
  isThumbnailVertical() {
1164
1266
  const { thumbnailPosition } = this.props;
1165
- return thumbnailPosition === 'left' || thumbnailPosition === 'right';
1267
+ return thumbnailPosition === "left" || thumbnailPosition === "right";
1166
1268
  }
1167
1269
 
1168
1270
  addScreenChangeEvent() {
@@ -1234,17 +1336,13 @@ class ImageGallery extends React.Component {
1234
1336
  }
1235
1337
 
1236
1338
  play(shouldCallOnPlay = true) {
1237
- const {
1238
- onPlay,
1239
- slideInterval,
1240
- slideDuration,
1241
- } = this.props;
1339
+ const { onPlay, slideInterval, slideDuration } = this.props;
1242
1340
  const { currentIndex } = this.state;
1243
1341
  if (!this.playPauseIntervalId) {
1244
1342
  this.setState({ isPlaying: true });
1245
1343
  this.playPauseIntervalId = window.setInterval(
1246
1344
  this.pauseOrPlay,
1247
- Math.max(slideInterval, slideDuration),
1345
+ Math.max(slideInterval, slideDuration)
1248
1346
  );
1249
1347
  if (onPlay && shouldCallOnPlay) {
1250
1348
  onPlay(currentIndex);
@@ -1329,24 +1427,18 @@ class ImageGallery extends React.Component {
1329
1427
  loading={item.thumbnailLoading}
1330
1428
  onError={handleThumbnailError}
1331
1429
  />
1332
- {
1333
- item.thumbnailLabel && (
1334
- <div className="image-gallery-thumbnail-label">
1335
- {item.thumbnailLabel}
1336
- </div>
1337
- )
1338
- }
1430
+ {item.thumbnailLabel && (
1431
+ <div className="image-gallery-thumbnail-label">
1432
+ {item.thumbnailLabel}
1433
+ </div>
1434
+ )}
1339
1435
  </span>
1340
1436
  );
1341
1437
  }
1342
1438
 
1343
1439
  render() {
1344
- const {
1345
- currentIndex,
1346
- isFullscreen,
1347
- modalFullscreen,
1348
- isPlaying,
1349
- } = this.state;
1440
+ const { currentIndex, isFullscreen, modalFullscreen, isPlaying } =
1441
+ this.state;
1350
1442
 
1351
1443
  const {
1352
1444
  additionalClass,
@@ -1371,120 +1463,114 @@ class ImageGallery extends React.Component {
1371
1463
  const thumbnailStyle = this.getThumbnailStyle();
1372
1464
  const { slides, thumbnails, bullets } = this.getSlideItems();
1373
1465
  const slideWrapperClass = clsx(
1374
- 'image-gallery-slide-wrapper',
1375
- thumbnailPosition,
1376
- { 'image-gallery-rtl': isRTL },
1466
+ "image-gallery-slide-wrapper",
1467
+ this.getThumbnailPositionClassName(thumbnailPosition),
1468
+ { "image-gallery-rtl": isRTL }
1377
1469
  );
1378
1470
 
1379
1471
  const slideWrapper = (
1380
1472
  <div ref={this.imageGallerySlideWrapper} className={slideWrapperClass}>
1381
1473
  {renderCustomControls && renderCustomControls()}
1382
- {
1383
- this.canSlide() ? (
1384
- <React.Fragment>
1385
- {
1386
- showNav && (
1387
- <React.Fragment>
1388
- {renderLeftNav(this.slideLeft, !this.canSlideLeft())}
1389
- {renderRightNav(this.slideRight, !this.canSlideRight())}
1390
- </React.Fragment>
1391
- )
1392
- }
1393
- <SwipeWrapper
1394
- className="image-gallery-swipe"
1395
- delta={0}
1396
- onSwiping={this.handleSwiping}
1397
- onSwiped={this.handleOnSwiped}
1398
- >
1399
- <div className="image-gallery-slides">
1400
- {slides}
1401
- </div>
1402
- </SwipeWrapper>
1403
- </React.Fragment>
1404
- ) : (
1405
- <div className="image-gallery-slides">
1406
- {slides}
1407
- </div>
1408
- )
1409
- }
1474
+ {this.canSlide() ? (
1475
+ <React.Fragment>
1476
+ {showNav && (
1477
+ <React.Fragment>
1478
+ {renderLeftNav(this.slideLeft, !this.canSlideLeft())}
1479
+ {renderRightNav(this.slideRight, !this.canSlideRight())}
1480
+ </React.Fragment>
1481
+ )}
1482
+ <SwipeWrapper
1483
+ className="image-gallery-swipe"
1484
+ delta={0}
1485
+ onSwiping={this.handleSwiping}
1486
+ onSwiped={this.handleOnSwiped}
1487
+ >
1488
+ <div className="image-gallery-slides">{slides}</div>
1489
+ </SwipeWrapper>
1490
+ </React.Fragment>
1491
+ ) : (
1492
+ <div className="image-gallery-slides">{slides}</div>
1493
+ )}
1410
1494
  {showPlayButton && renderPlayPauseButton(this.togglePlay, isPlaying)}
1411
- {
1412
- showBullets && (
1413
- <div className="image-gallery-bullets">
1414
- <div
1415
- className="image-gallery-bullets-container"
1416
- role="navigation"
1417
- aria-label="Bullet Navigation"
1418
- >
1419
- {bullets}
1420
- </div>
1421
- </div>
1422
- )
1423
- }
1424
- {showFullscreenButton && renderFullscreenButton(this.toggleFullScreen, isFullscreen)}
1425
- {
1426
- showIndex && (
1427
- <div className="image-gallery-index">
1428
- <span className="image-gallery-index-current">
1429
- {currentIndex + 1}
1430
- </span>
1431
- <span className="image-gallery-index-separator">
1432
- {indexSeparator}
1433
- </span>
1434
- <span className="image-gallery-index-total">
1435
- {items.length}
1436
- </span>
1495
+ {showBullets && (
1496
+ <div className="image-gallery-bullets">
1497
+ <div
1498
+ className="image-gallery-bullets-container"
1499
+ role="navigation"
1500
+ aria-label="Bullet Navigation"
1501
+ >
1502
+ {bullets}
1437
1503
  </div>
1438
- )
1439
- }
1504
+ </div>
1505
+ )}
1506
+ {showFullscreenButton &&
1507
+ renderFullscreenButton(this.toggleFullScreen, isFullscreen)}
1508
+ {showIndex && (
1509
+ <div className="image-gallery-index">
1510
+ <span className="image-gallery-index-current">
1511
+ {currentIndex + 1}
1512
+ </span>
1513
+ <span className="image-gallery-index-separator">
1514
+ {indexSeparator}
1515
+ </span>
1516
+ <span className="image-gallery-index-total">{items.length}</span>
1517
+ </div>
1518
+ )}
1440
1519
  </div>
1441
1520
  );
1442
1521
 
1443
- const igClass = clsx('image-gallery', additionalClass, { 'fullscreen-modal': modalFullscreen });
1444
- const igContentClass = clsx('image-gallery-content', thumbnailPosition, { fullscreen: isFullscreen });
1522
+ const igClass = clsx("image-gallery", additionalClass, {
1523
+ "fullscreen-modal": modalFullscreen,
1524
+ });
1525
+ const igContentClass = clsx(
1526
+ "image-gallery-content",
1527
+ this.getThumbnailPositionClassName(thumbnailPosition),
1528
+ { fullscreen: isFullscreen }
1529
+ );
1445
1530
  const thumbnailWrapperClass = clsx(
1446
- 'image-gallery-thumbnails-wrapper',
1447
- thumbnailPosition,
1448
- { 'thumbnails-wrapper-rtl': !this.isThumbnailVertical() && isRTL },
1449
- { 'thumbnails-swipe-horizontal': !this.isThumbnailVertical() && !disableThumbnailSwipe },
1450
- { 'thumbnails-swipe-vertical': this.isThumbnailVertical() && !disableThumbnailSwipe },
1531
+ "image-gallery-thumbnails-wrapper",
1532
+ this.getThumbnailPositionClassName(thumbnailPosition),
1533
+ { "thumbnails-wrapper-rtl": !this.isThumbnailVertical() && isRTL },
1534
+ {
1535
+ "thumbnails-swipe-horizontal":
1536
+ !this.isThumbnailVertical() && !disableThumbnailSwipe,
1537
+ },
1538
+ {
1539
+ "thumbnails-swipe-vertical":
1540
+ this.isThumbnailVertical() && !disableThumbnailSwipe,
1541
+ }
1451
1542
  );
1452
1543
  return (
1453
- <div
1454
- ref={this.imageGallery}
1455
- className={igClass}
1456
- aria-live="polite"
1457
- >
1544
+ <div ref={this.imageGallery} className={igClass} aria-live="polite">
1458
1545
  <div className={igContentClass}>
1459
- {(thumbnailPosition === 'bottom' || thumbnailPosition === 'right') && slideWrapper}
1460
- {
1461
- showThumbnails && thumbnails.length > 0 ? (
1462
- <SwipeWrapper
1463
- className={thumbnailWrapperClass}
1464
- delta={0}
1465
- onSwiping={!disableThumbnailSwipe && this.handleThumbnailSwiping}
1466
- onSwiped={!disableThumbnailSwipe && this.handleOnThumbnailSwiped}
1546
+ {(thumbnailPosition === "bottom" || thumbnailPosition === "right") &&
1547
+ slideWrapper}
1548
+ {showThumbnails && thumbnails.length > 0 ? (
1549
+ <SwipeWrapper
1550
+ className={thumbnailWrapperClass}
1551
+ delta={0}
1552
+ onSwiping={!disableThumbnailSwipe && this.handleThumbnailSwiping}
1553
+ onSwiped={!disableThumbnailSwipe && this.handleOnThumbnailSwiped}
1554
+ >
1555
+ <div
1556
+ className="image-gallery-thumbnails"
1557
+ ref={this.thumbnailsWrapper}
1558
+ style={this.getThumbnailBarHeight()}
1467
1559
  >
1468
- <div
1469
- className="image-gallery-thumbnails"
1470
- ref={this.thumbnailsWrapper}
1471
- style={this.getThumbnailBarHeight()}
1560
+ <nav
1561
+ ref={this.thumbnails}
1562
+ className="image-gallery-thumbnails-container"
1563
+ style={thumbnailStyle}
1564
+ aria-label="Thumbnail Navigation"
1472
1565
  >
1473
- <nav
1474
- ref={this.thumbnails}
1475
- className="image-gallery-thumbnails-container"
1476
- style={thumbnailStyle}
1477
- aria-label="Thumbnail Navigation"
1478
- >
1479
- {thumbnails}
1480
- </nav>
1481
- </div>
1482
- </SwipeWrapper>
1483
- ) : null
1484
- }
1485
- {(thumbnailPosition === 'top' || thumbnailPosition === 'left') && slideWrapper}
1566
+ {thumbnails}
1567
+ </nav>
1568
+ </div>
1569
+ </SwipeWrapper>
1570
+ ) : null}
1571
+ {(thumbnailPosition === "top" || thumbnailPosition === "left") &&
1572
+ slideWrapper}
1486
1573
  </div>
1487
-
1488
1574
  </div>
1489
1575
  );
1490
1576
  }
@@ -1492,32 +1578,34 @@ class ImageGallery extends React.Component {
1492
1578
 
1493
1579
  ImageGallery.propTypes = {
1494
1580
  flickThreshold: number,
1495
- items: arrayOf(shape({
1496
- bulletClass: string,
1497
- bulletOnClick: func,
1498
- description: string,
1499
- original: string,
1500
- originalHeight: number,
1501
- originalWidth: number,
1502
- loading: string,
1503
- thumbnailHeight: number,
1504
- thumbnailWidth: number,
1505
- thumbnailLoading: string,
1506
- fullscreen: string,
1507
- originalAlt: string,
1508
- originalTitle: string,
1509
- thumbnail: string,
1510
- thumbnailAlt: string,
1511
- thumbnailLabel: string,
1512
- thumbnailTitle: string,
1513
- originalClass: string,
1514
- thumbnailClass: string,
1515
- renderItem: func,
1516
- renderThumbInner: func,
1517
- imageSet: imageSetType,
1518
- srcSet: string,
1519
- sizes: string,
1520
- })).isRequired,
1581
+ items: arrayOf(
1582
+ shape({
1583
+ bulletClass: string,
1584
+ bulletOnClick: func,
1585
+ description: string,
1586
+ original: string,
1587
+ originalHeight: number,
1588
+ originalWidth: number,
1589
+ loading: string,
1590
+ thumbnailHeight: number,
1591
+ thumbnailWidth: number,
1592
+ thumbnailLoading: string,
1593
+ fullscreen: string,
1594
+ originalAlt: string,
1595
+ originalTitle: string,
1596
+ thumbnail: string,
1597
+ thumbnailAlt: string,
1598
+ thumbnailLabel: string,
1599
+ thumbnailTitle: string,
1600
+ originalClass: string,
1601
+ thumbnailClass: string,
1602
+ renderItem: func,
1603
+ renderThumbInner: func,
1604
+ imageSet: imageSetType,
1605
+ srcSet: string,
1606
+ sizes: string,
1607
+ })
1608
+ ).isRequired,
1521
1609
  showNav: bool,
1522
1610
  autoPlay: bool,
1523
1611
  lazyLoad: bool,
@@ -1534,7 +1622,7 @@ ImageGallery.propTypes = {
1534
1622
  useBrowserFullscreen: bool,
1535
1623
  onErrorImageURL: string,
1536
1624
  indexSeparator: string,
1537
- thumbnailPosition: oneOf(['top', 'bottom', 'left', 'right']),
1625
+ thumbnailPosition: oneOf(["top", "bottom", "left", "right"]),
1538
1626
  startIndex: number,
1539
1627
  slideDuration: number,
1540
1628
  slideInterval: number,
@@ -1555,6 +1643,7 @@ ImageGallery.propTypes = {
1555
1643
  onTouchStart: func,
1556
1644
  onMouseOver: func,
1557
1645
  onMouseLeave: func,
1646
+ onBulletClick: func,
1558
1647
  onThumbnailError: func,
1559
1648
  onThumbnailClick: func,
1560
1649
  renderCustomControls: func,
@@ -1572,8 +1661,8 @@ ImageGallery.propTypes = {
1572
1661
  };
1573
1662
 
1574
1663
  ImageGallery.defaultProps = {
1575
- onErrorImageURL: '',
1576
- additionalClass: '',
1664
+ onErrorImageURL: "",
1665
+ additionalClass: "",
1577
1666
  showNav: true,
1578
1667
  autoPlay: false,
1579
1668
  lazyLoad: false,
@@ -1592,8 +1681,8 @@ ImageGallery.defaultProps = {
1592
1681
  useBrowserFullscreen: true,
1593
1682
  flickThreshold: 0.4,
1594
1683
  stopPropagation: false,
1595
- indexSeparator: ' / ',
1596
- thumbnailPosition: 'bottom',
1684
+ indexSeparator: " / ",
1685
+ thumbnailPosition: "bottom",
1597
1686
  startIndex: 0,
1598
1687
  slideDuration: 450,
1599
1688
  swipingTransitionDuration: 0,
@@ -1611,6 +1700,7 @@ ImageGallery.defaultProps = {
1611
1700
  onTouchStart: null,
1612
1701
  onMouseOver: null,
1613
1702
  onMouseLeave: null,
1703
+ onBulletClick: null,
1614
1704
  onThumbnailError: null,
1615
1705
  onThumbnailClick: null,
1616
1706
  renderCustomControls: null,