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.
@@ -0,0 +1,22 @@
1
+ import React from "react";
2
+ import { render, screen } from "@testing-library/react";
3
+
4
+ import ImageGallery from "./ImageGallery";
5
+
6
+ describe("<ImageGallery />", () => {
7
+ const defaultProps = {
8
+ items: [
9
+ {
10
+ original: "test.png",
11
+ thumbnail: "test_thumb.png",
12
+ },
13
+ ],
14
+ };
15
+
16
+ it("renders slides", () => {
17
+ render(<ImageGallery {...defaultProps} />);
18
+ const elements = screen.getAllByLabelText("Go to Slide 1");
19
+ // expect a thumbnail and slide label
20
+ expect(elements.length).toBe(2);
21
+ });
22
+ });
@@ -0,0 +1,75 @@
1
+ import React from "react";
2
+ import { bool, func, string } from "prop-types";
3
+
4
+ const defaultProps = {
5
+ description: "",
6
+ fullscreen: "",
7
+ isFullscreen: false,
8
+ originalAlt: "",
9
+ originalHeight: "",
10
+ originalWidth: "",
11
+ originalTitle: "",
12
+ sizes: "",
13
+ srcSet: "",
14
+ loading: "eager",
15
+ };
16
+
17
+ const Item = React.memo((props) => {
18
+ const {
19
+ description,
20
+ fullscreen, // fullscreen version of img
21
+ handleImageLoaded,
22
+ isFullscreen,
23
+ onImageError,
24
+ original,
25
+ originalAlt,
26
+ originalHeight,
27
+ originalWidth,
28
+ originalTitle,
29
+ sizes,
30
+ srcSet,
31
+ loading,
32
+ } = { ...defaultProps, ...props };
33
+ const itemSrc = isFullscreen ? fullscreen || original : original;
34
+
35
+ return (
36
+ <React.Fragment>
37
+ <img
38
+ className="image-gallery-image"
39
+ src={itemSrc}
40
+ alt={originalAlt}
41
+ srcSet={srcSet}
42
+ height={originalHeight}
43
+ width={originalWidth}
44
+ sizes={sizes}
45
+ title={originalTitle}
46
+ onLoad={(event) => handleImageLoaded(event, original)}
47
+ onError={onImageError}
48
+ loading={loading}
49
+ />
50
+ {description && (
51
+ <span className="image-gallery-description">{description}</span>
52
+ )}
53
+ </React.Fragment>
54
+ );
55
+ });
56
+
57
+ Item.displayName = "Item";
58
+
59
+ Item.propTypes = {
60
+ description: string,
61
+ fullscreen: string, // fullscreen version of img
62
+ handleImageLoaded: func.isRequired,
63
+ isFullscreen: bool,
64
+ onImageError: func.isRequired,
65
+ original: string.isRequired,
66
+ originalAlt: string,
67
+ originalHeight: string,
68
+ originalWidth: string,
69
+ originalTitle: string,
70
+ sizes: string,
71
+ srcSet: string,
72
+ loading: string,
73
+ };
74
+
75
+ export default Item;
@@ -1,10 +1,14 @@
1
- import React from 'react';
2
- import { number, oneOf, string } from 'prop-types';
1
+ import React from "react";
2
+ import { number, oneOf, string } from "prop-types";
3
3
 
4
4
  const left = <polyline points="15 18 9 12 15 6" />;
5
5
  const right = <polyline points="9 18 15 12 9 6" />;
6
- const maximize = <path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3" />;
7
- const minimize = <path d="M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3" />;
6
+ const maximize = (
7
+ <path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3" />
8
+ );
9
+ const minimize = (
10
+ <path d="M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3" />
11
+ );
8
12
  const play = <polygon points="5 3 19 12 5 21 5 3" />;
9
13
  const pause = (
10
14
  <React.Fragment>
@@ -22,12 +26,13 @@ const iconMapper = {
22
26
  pause,
23
27
  };
24
28
 
29
+ const defaultProps = {
30
+ strokeWidth: 1,
31
+ viewBox: "0 0 24 24",
32
+ };
33
+
25
34
  const SVG = (props) => {
26
- const {
27
- strokeWidth,
28
- viewBox,
29
- icon,
30
- } = props;
35
+ const { strokeWidth, viewBox, icon } = { ...defaultProps, ...props };
31
36
  return (
32
37
  <svg
33
38
  className="image-gallery-svg"
@@ -47,19 +52,8 @@ const SVG = (props) => {
47
52
  SVG.propTypes = {
48
53
  strokeWidth: number,
49
54
  viewBox: string,
50
- icon: oneOf([
51
- 'left',
52
- 'right',
53
- 'maximize',
54
- 'minimize',
55
- 'play',
56
- 'pause',
57
- ]).isRequired,
58
- };
59
-
60
- SVG.defaultProps = {
61
- strokeWidth: 1,
62
- viewBox: '0 0 24 24',
55
+ icon: oneOf(["left", "right", "maximize", "minimize", "play", "pause"])
56
+ .isRequired,
63
57
  };
64
58
 
65
59
  export default SVG;
@@ -1,19 +1,19 @@
1
- import React from 'react';
2
- import {
3
- string,
4
- node,
5
- number,
6
- func,
7
- } from 'prop-types';
8
- import { useSwipeable } from 'react-swipeable';
1
+ import React from "react";
2
+ import { string, node, number, func } from "prop-types";
3
+ import { useSwipeable } from "react-swipeable";
9
4
 
10
- const SwipeWrapper = ({
11
- children,
12
- className,
13
- delta,
14
- onSwiping,
15
- onSwiped,
16
- }) => {
5
+ const defaultProps = {
6
+ className: "",
7
+ delta: 0,
8
+ onSwiping: () => {},
9
+ onSwiped: () => {},
10
+ };
11
+
12
+ const SwipeWrapper = (props) => {
13
+ const { children, className, delta, onSwiping, onSwiped } = {
14
+ ...defaultProps,
15
+ ...props,
16
+ };
17
17
  const swipeHandlers = useSwipeable({
18
18
  delta,
19
19
  onSwiping,
@@ -34,11 +34,4 @@ SwipeWrapper.propTypes = {
34
34
  onSwiping: func,
35
35
  };
36
36
 
37
- SwipeWrapper.defaultProps = {
38
- className: '',
39
- delta: 0,
40
- onSwiping: () => {},
41
- onSwiped: () => {},
42
- };
43
-
44
37
  export default SwipeWrapper;
@@ -1,11 +1,8 @@
1
- import React from 'react';
2
- import { bool, func } from 'prop-types';
3
- import SVG from 'src/SVG';
1
+ import React from "react";
2
+ import { bool, func } from "prop-types";
3
+ import SVG from "src/components/SVG";
4
4
 
5
- const Fullscreen = React.memo(({
6
- isFullscreen,
7
- onClick,
8
- }) => {
5
+ const Fullscreen = React.memo(({ isFullscreen, onClick }) => {
9
6
  return (
10
7
  <button
11
8
  type="button"
@@ -13,17 +10,16 @@ const Fullscreen = React.memo(({
13
10
  onClick={onClick}
14
11
  aria-label="Open Fullscreen"
15
12
  >
16
- <SVG strokeWidth={2} icon={isFullscreen ? 'minimize' : 'maximize'} />
13
+ <SVG strokeWidth={2} icon={isFullscreen ? "minimize" : "maximize"} />
17
14
  </button>
18
15
  );
19
16
  });
20
17
 
21
- Fullscreen.displayName = 'Fullscreen';
18
+ Fullscreen.displayName = "Fullscreen";
22
19
 
23
20
  Fullscreen.propTypes = {
24
21
  isFullscreen: bool.isRequired,
25
22
  onClick: func.isRequired,
26
23
  };
27
24
 
28
-
29
25
  export default Fullscreen;
@@ -1,11 +1,8 @@
1
- import React from 'react';
2
- import { bool, func } from 'prop-types';
3
- import SVG from 'src/SVG';
1
+ import React from "react";
2
+ import { bool, func } from "prop-types";
3
+ import SVG from "src/components/SVG";
4
4
 
5
- const LeftNav = React.memo(({
6
- disabled,
7
- onClick,
8
- }) => {
5
+ const LeftNav = React.memo(({ disabled, onClick }) => {
9
6
  return (
10
7
  <button
11
8
  type="button"
@@ -19,12 +16,11 @@ const LeftNav = React.memo(({
19
16
  );
20
17
  });
21
18
 
22
- LeftNav.displayName = 'LeftNav';
19
+ LeftNav.displayName = "LeftNav";
23
20
 
24
21
  LeftNav.propTypes = {
25
22
  disabled: bool.isRequired,
26
23
  onClick: func.isRequired,
27
24
  };
28
25
 
29
-
30
26
  export default LeftNav;
@@ -1,11 +1,8 @@
1
- import React from 'react';
2
- import { bool, func } from 'prop-types';
3
- import SVG from 'src/SVG';
1
+ import React from "react";
2
+ import { bool, func } from "prop-types";
3
+ import SVG from "src/components/SVG";
4
4
 
5
- const PlayPause = React.memo(({
6
- isPlaying,
7
- onClick,
8
- }) => {
5
+ const PlayPause = React.memo(({ isPlaying, onClick }) => {
9
6
  return (
10
7
  <button
11
8
  type="button"
@@ -13,17 +10,16 @@ const PlayPause = React.memo(({
13
10
  onClick={onClick}
14
11
  aria-label="Play or Pause Slideshow"
15
12
  >
16
- <SVG strokeWidth={2} icon={isPlaying ? 'pause' : 'play'} />
13
+ <SVG strokeWidth={2} icon={isPlaying ? "pause" : "play"} />
17
14
  </button>
18
15
  );
19
16
  });
20
17
 
21
- PlayPause.displayName = 'PlayPause';
18
+ PlayPause.displayName = "PlayPause";
22
19
 
23
20
  PlayPause.propTypes = {
24
21
  isPlaying: bool.isRequired,
25
22
  onClick: func.isRequired,
26
23
  };
27
24
 
28
-
29
25
  export default PlayPause;
@@ -1,11 +1,8 @@
1
- import React from 'react';
2
- import { bool, func } from 'prop-types';
3
- import SVG from 'src/SVG';
1
+ import React from "react";
2
+ import { bool, func } from "prop-types";
3
+ import SVG from "src/components/SVG";
4
4
 
5
- const RightNav = React.memo(({
6
- disabled,
7
- onClick,
8
- }) => {
5
+ const RightNav = React.memo(({ disabled, onClick }) => {
9
6
  return (
10
7
  <button
11
8
  type="button"
@@ -19,12 +16,11 @@ const RightNav = React.memo(({
19
16
  );
20
17
  });
21
18
 
22
- RightNav.displayName = 'RightNav';
19
+ RightNav.displayName = "RightNav";
23
20
 
24
21
  RightNav.propTypes = {
25
22
  disabled: bool.isRequired,
26
23
  onClick: func.isRequired,
27
24
  };
28
25
 
29
-
30
26
  export default RightNav;
@@ -1 +1 @@
1
- .image-gallery-icon{color:#fff;transition:all .3s ease-out;appearance:none;background-color:transparent;border:0;cursor:pointer;outline:none;position:absolute;z-index:4;filter:drop-shadow(0 2px 2px #1a1a1a)}@media(hover: hover)and (pointer: fine){.image-gallery-icon:hover{color:#337ab7}.image-gallery-icon:hover .image-gallery-svg{transform:scale(1.1)}}.image-gallery-icon:focus{outline:2px solid #337ab7}.image-gallery-using-mouse .image-gallery-icon:focus{outline:none}.image-gallery-fullscreen-button,.image-gallery-play-button{bottom:0;padding:20px}.image-gallery-fullscreen-button .image-gallery-svg,.image-gallery-play-button .image-gallery-svg{height:28px;width:28px}@media(max-width: 768px){.image-gallery-fullscreen-button,.image-gallery-play-button{padding:15px}.image-gallery-fullscreen-button .image-gallery-svg,.image-gallery-play-button .image-gallery-svg{height:24px;width:24px}}@media(max-width: 480px){.image-gallery-fullscreen-button,.image-gallery-play-button{padding:10px}.image-gallery-fullscreen-button .image-gallery-svg,.image-gallery-play-button .image-gallery-svg{height:16px;width:16px}}.image-gallery-fullscreen-button{right:0}.image-gallery-play-button{left:0}.image-gallery-left-nav,.image-gallery-right-nav{padding:50px 10px;top:50%;transform:translateY(-50%)}.image-gallery-left-nav .image-gallery-svg,.image-gallery-right-nav .image-gallery-svg{height:120px;width:60px}@media(max-width: 768px){.image-gallery-left-nav .image-gallery-svg,.image-gallery-right-nav .image-gallery-svg{height:72px;width:36px}}@media(max-width: 480px){.image-gallery-left-nav .image-gallery-svg,.image-gallery-right-nav .image-gallery-svg{height:48px;width:24px}}.image-gallery-left-nav[disabled],.image-gallery-right-nav[disabled]{cursor:disabled;opacity:.6;pointer-events:none}.image-gallery-left-nav{left:0}.image-gallery-right-nav{right:0}.image-gallery{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;-webkit-tap-highlight-color:rgba(0,0,0,0);position:relative}.image-gallery.fullscreen-modal{background:#000;bottom:0;height:100%;left:0;position:fixed;right:0;top:0;width:100%;z-index:5}.image-gallery.fullscreen-modal .image-gallery-content{top:50%;transform:translateY(-50%)}.image-gallery-content{position:relative;line-height:0;top:0}.image-gallery-content.fullscreen{background:#000}.image-gallery-content .image-gallery-slide .image-gallery-image{max-height:calc(100vh - 80px)}.image-gallery-content.left .image-gallery-slide .image-gallery-image,.image-gallery-content.right .image-gallery-slide .image-gallery-image{max-height:100vh}.image-gallery-slide-wrapper{position:relative}.image-gallery-slide-wrapper.left,.image-gallery-slide-wrapper.right{display:inline-block;width:calc(100% - 110px)}@media(max-width: 768px){.image-gallery-slide-wrapper.left,.image-gallery-slide-wrapper.right{width:calc(100% - 87px)}}.image-gallery-slide-wrapper.image-gallery-rtl{direction:rtl}.image-gallery-slides{line-height:0;overflow:hidden;position:relative;white-space:nowrap;text-align:center}.image-gallery-slide{left:0;position:absolute;top:0;width:100%}.image-gallery-slide.center{position:relative}.image-gallery-slide .image-gallery-image{width:100%;object-fit:contain}.image-gallery-slide .image-gallery-description{background:rgba(0,0,0,.4);bottom:70px;color:#fff;left:0;line-height:1;padding:10px 20px;position:absolute;white-space:normal}@media(max-width: 768px){.image-gallery-slide .image-gallery-description{bottom:45px;font-size:.8em;padding:8px 15px}}.image-gallery-bullets{bottom:20px;left:0;margin:0 auto;position:absolute;right:0;width:80%;z-index:4}.image-gallery-bullets .image-gallery-bullets-container{margin:0;padding:0;text-align:center}.image-gallery-bullets .image-gallery-bullet{appearance:none;background-color:transparent;border:1px solid #fff;border-radius:50%;box-shadow:0 2px 2px #1a1a1a;cursor:pointer;display:inline-block;margin:0 5px;outline:none;padding:5px;transition:all .2s ease-out}@media(max-width: 768px){.image-gallery-bullets .image-gallery-bullet{margin:0 3px;padding:3px}}@media(max-width: 480px){.image-gallery-bullets .image-gallery-bullet{padding:2.7px}}.image-gallery-bullets .image-gallery-bullet:focus{transform:scale(1.2);background:#337ab7;border:1px solid #337ab7}.image-gallery-bullets .image-gallery-bullet.active{transform:scale(1.2);border:1px solid #fff;background:#fff}@media(hover: hover)and (pointer: fine){.image-gallery-bullets .image-gallery-bullet:hover{background:#337ab7;border:1px solid #337ab7}.image-gallery-bullets .image-gallery-bullet.active:hover{background:#337ab7}}.image-gallery-thumbnails-wrapper{position:relative}.image-gallery-thumbnails-wrapper.thumbnails-swipe-horizontal{touch-action:pan-y}.image-gallery-thumbnails-wrapper.thumbnails-swipe-vertical{touch-action:pan-x}.image-gallery-thumbnails-wrapper.thumbnails-wrapper-rtl{direction:rtl}.image-gallery-thumbnails-wrapper.left,.image-gallery-thumbnails-wrapper.right{display:inline-block;vertical-align:top;width:100px}@media(max-width: 768px){.image-gallery-thumbnails-wrapper.left,.image-gallery-thumbnails-wrapper.right{width:81px}}.image-gallery-thumbnails-wrapper.left .image-gallery-thumbnails,.image-gallery-thumbnails-wrapper.right .image-gallery-thumbnails{height:100%;width:100%;left:0;padding:0;position:absolute;top:0}.image-gallery-thumbnails-wrapper.left .image-gallery-thumbnails .image-gallery-thumbnail,.image-gallery-thumbnails-wrapper.right .image-gallery-thumbnails .image-gallery-thumbnail{display:block;margin-right:0;padding:0}.image-gallery-thumbnails-wrapper.left .image-gallery-thumbnails .image-gallery-thumbnail+.image-gallery-thumbnail,.image-gallery-thumbnails-wrapper.right .image-gallery-thumbnails .image-gallery-thumbnail+.image-gallery-thumbnail{margin-left:0;margin-top:2px}.image-gallery-thumbnails-wrapper.left,.image-gallery-thumbnails-wrapper.right{margin:0 5px}@media(max-width: 768px){.image-gallery-thumbnails-wrapper.left,.image-gallery-thumbnails-wrapper.right{margin:0 3px}}.image-gallery-thumbnails{overflow:hidden;padding:5px 0}@media(max-width: 768px){.image-gallery-thumbnails{padding:3px 0}}.image-gallery-thumbnails .image-gallery-thumbnails-container{cursor:pointer;text-align:center;white-space:nowrap}.image-gallery-thumbnail{display:inline-block;border:4px solid transparent;transition:border .3s ease-out;width:100px;background:transparent;padding:0}@media(max-width: 768px){.image-gallery-thumbnail{border:3px solid transparent;width:81px}}.image-gallery-thumbnail+.image-gallery-thumbnail{margin-left:2px}.image-gallery-thumbnail .image-gallery-thumbnail-inner{display:block;position:relative}.image-gallery-thumbnail .image-gallery-thumbnail-image{vertical-align:middle;width:100%;line-height:0}.image-gallery-thumbnail.active,.image-gallery-thumbnail:focus{outline:none;border:4px solid #337ab7}@media(max-width: 768px){.image-gallery-thumbnail.active,.image-gallery-thumbnail:focus{border:3px solid #337ab7}}@media(hover: hover)and (pointer: fine){.image-gallery-thumbnail:hover{outline:none;border:4px solid #337ab7}}@media(hover: hover)and (pointer: fine)and (max-width: 768px){.image-gallery-thumbnail:hover{border:3px solid #337ab7}}.image-gallery-thumbnail-label{box-sizing:border-box;color:#fff;font-size:1em;left:0;line-height:1em;padding:5%;position:absolute;top:50%;text-shadow:0 2px 2px #1a1a1a;transform:translateY(-50%);white-space:normal;width:100%}@media(max-width: 768px){.image-gallery-thumbnail-label{font-size:.8em;line-height:.8em}}.image-gallery-index{background:rgba(0,0,0,.4);color:#fff;line-height:1;padding:10px 20px;position:absolute;right:0;top:0;z-index:4}@media(max-width: 768px){.image-gallery-index{font-size:.8em;padding:5px 10px}}
1
+ .image-gallery-icon{color:#fff;transition:all .3s ease-out;appearance:none;background-color:transparent;border:0;cursor:pointer;outline:none;position:absolute;z-index:4;filter:drop-shadow(0 2px 2px #1a1a1a)}@media(hover: hover)and (pointer: fine){.image-gallery-icon:hover{color:#337ab7}.image-gallery-icon:hover .image-gallery-svg{transform:scale(1.1)}}.image-gallery-icon:focus{outline:2px solid #337ab7}.image-gallery-using-mouse .image-gallery-icon:focus{outline:none}.image-gallery-fullscreen-button,.image-gallery-play-button{bottom:0;padding:20px}.image-gallery-fullscreen-button .image-gallery-svg,.image-gallery-play-button .image-gallery-svg{height:28px;width:28px}@media(max-width: 768px){.image-gallery-fullscreen-button,.image-gallery-play-button{padding:15px}.image-gallery-fullscreen-button .image-gallery-svg,.image-gallery-play-button .image-gallery-svg{height:24px;width:24px}}@media(max-width: 480px){.image-gallery-fullscreen-button,.image-gallery-play-button{padding:10px}.image-gallery-fullscreen-button .image-gallery-svg,.image-gallery-play-button .image-gallery-svg{height:16px;width:16px}}.image-gallery-fullscreen-button{right:0}.image-gallery-play-button{left:0}.image-gallery-left-nav,.image-gallery-right-nav{padding:50px 10px;top:50%;transform:translateY(-50%)}.image-gallery-left-nav .image-gallery-svg,.image-gallery-right-nav .image-gallery-svg{height:120px;width:60px}@media(max-width: 768px){.image-gallery-left-nav .image-gallery-svg,.image-gallery-right-nav .image-gallery-svg{height:72px;width:36px}}@media(max-width: 480px){.image-gallery-left-nav .image-gallery-svg,.image-gallery-right-nav .image-gallery-svg{height:48px;width:24px}}.image-gallery-left-nav[disabled],.image-gallery-right-nav[disabled]{cursor:disabled;opacity:.6;pointer-events:none}.image-gallery-left-nav{left:0}.image-gallery-right-nav{right:0}.image-gallery{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;-webkit-tap-highlight-color:rgba(0,0,0,0);position:relative}.image-gallery.fullscreen-modal{background:#000;bottom:0;height:100%;left:0;position:fixed;right:0;top:0;width:100%;z-index:5}.image-gallery.fullscreen-modal .image-gallery-content{top:50%;transform:translateY(-50%)}.image-gallery-content{position:relative;line-height:0;top:0}.image-gallery-content.fullscreen{background:#000}.image-gallery-content .image-gallery-slide .image-gallery-image{max-height:calc(100vh - 80px)}.image-gallery-content.image-gallery-thumbnails-left .image-gallery-slide .image-gallery-image,.image-gallery-content.image-gallery-thumbnails-right .image-gallery-slide .image-gallery-image{max-height:100vh}.image-gallery-slide-wrapper{position:relative}.image-gallery-slide-wrapper.image-gallery-thumbnails-left,.image-gallery-slide-wrapper.image-gallery-thumbnails-right{display:inline-block;width:calc(100% - 110px)}@media(max-width: 768px){.image-gallery-slide-wrapper.image-gallery-thumbnails-left,.image-gallery-slide-wrapper.image-gallery-thumbnails-right{width:calc(100% - 87px)}}.image-gallery-slide-wrapper.image-gallery-rtl{direction:rtl}.image-gallery-slides{line-height:0;overflow:hidden;position:relative;white-space:nowrap;text-align:center}.image-gallery-slide{left:0;position:absolute;top:0;width:100%}.image-gallery-slide.image-gallery-center{position:relative}.image-gallery-slide .image-gallery-image{width:100%;object-fit:contain}.image-gallery-slide .image-gallery-description{background:rgba(0,0,0,.4);bottom:70px;color:#fff;left:0;line-height:1;padding:10px 20px;position:absolute;white-space:normal}@media(max-width: 768px){.image-gallery-slide .image-gallery-description{bottom:45px;font-size:.8em;padding:8px 15px}}.image-gallery-bullets{bottom:20px;left:0;margin:0 auto;position:absolute;right:0;width:80%;z-index:4}.image-gallery-bullets .image-gallery-bullets-container{margin:0;padding:0;text-align:center}.image-gallery-bullets .image-gallery-bullet{appearance:none;background-color:transparent;border:1px solid #fff;border-radius:50%;box-shadow:0 2px 2px #1a1a1a;cursor:pointer;display:inline-block;margin:0 5px;outline:none;padding:5px;transition:all .2s ease-out}@media(max-width: 768px){.image-gallery-bullets .image-gallery-bullet{margin:0 3px;padding:3px}}@media(max-width: 480px){.image-gallery-bullets .image-gallery-bullet{padding:2.7px}}.image-gallery-bullets .image-gallery-bullet:focus{transform:scale(1.2);background:#337ab7;border:1px solid #337ab7}.image-gallery-bullets .image-gallery-bullet.active{transform:scale(1.2);border:1px solid #fff;background:#fff}@media(hover: hover)and (pointer: fine){.image-gallery-bullets .image-gallery-bullet:hover{background:#337ab7;border:1px solid #337ab7}.image-gallery-bullets .image-gallery-bullet.active:hover{background:#337ab7}}.image-gallery-thumbnails-wrapper{position:relative}.image-gallery-thumbnails-wrapper.thumbnails-swipe-horizontal{touch-action:pan-y}.image-gallery-thumbnails-wrapper.thumbnails-swipe-vertical{touch-action:pan-x}.image-gallery-thumbnails-wrapper.thumbnails-wrapper-rtl{direction:rtl}.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-left,.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-right{display:inline-block;vertical-align:top;width:100px}@media(max-width: 768px){.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-left,.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-right{width:81px}}.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-left .image-gallery-thumbnails,.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-right .image-gallery-thumbnails{height:100%;width:100%;left:0;padding:0;position:absolute;top:0}.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-left .image-gallery-thumbnails .image-gallery-thumbnail,.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-right .image-gallery-thumbnails .image-gallery-thumbnail{display:block;margin-right:0;padding:0}.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-left .image-gallery-thumbnails .image-gallery-thumbnail+.image-gallery-thumbnail,.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-right .image-gallery-thumbnails .image-gallery-thumbnail+.image-gallery-thumbnail{margin-left:0;margin-top:2px}.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-left,.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-right{margin:0 5px}@media(max-width: 768px){.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-left,.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-right{margin:0 3px}}.image-gallery-thumbnails{overflow:hidden;padding:5px 0}@media(max-width: 768px){.image-gallery-thumbnails{padding:3px 0}}.image-gallery-thumbnails .image-gallery-thumbnails-container{cursor:pointer;text-align:center;white-space:nowrap}.image-gallery-thumbnail{display:inline-block;border:4px solid transparent;transition:border .3s ease-out;width:100px;background:transparent;padding:0}@media(max-width: 768px){.image-gallery-thumbnail{border:3px solid transparent;width:81px}}.image-gallery-thumbnail+.image-gallery-thumbnail{margin-left:2px}.image-gallery-thumbnail .image-gallery-thumbnail-inner{display:block;position:relative}.image-gallery-thumbnail .image-gallery-thumbnail-image{vertical-align:middle;width:100%;line-height:0}.image-gallery-thumbnail.active,.image-gallery-thumbnail:focus{outline:none;border:4px solid #337ab7}@media(max-width: 768px){.image-gallery-thumbnail.active,.image-gallery-thumbnail:focus{border:3px solid #337ab7}}@media(hover: hover)and (pointer: fine){.image-gallery-thumbnail:hover{outline:none;border:4px solid #337ab7}}@media(hover: hover)and (pointer: fine)and (max-width: 768px){.image-gallery-thumbnail:hover{border:3px solid #337ab7}}.image-gallery-thumbnail-label{box-sizing:border-box;color:#fff;font-size:1em;left:0;line-height:1em;padding:5%;position:absolute;top:50%;text-shadow:0 2px 2px #1a1a1a;transform:translateY(-50%);white-space:normal;width:100%}@media(max-width: 768px){.image-gallery-thumbnail-label{font-size:.8em;line-height:.8em}}.image-gallery-index{background:rgba(0,0,0,.4);color:#fff;line-height:1;padding:10px 20px;position:absolute;right:0;top:0;z-index:4}@media(max-width: 768px){.image-gallery-index{font-size:.8em;padding:5px 10px}}
@@ -163,8 +163,8 @@ $ig-shadow: 0 2px 2px lighten($ig-black, 10%);
163
163
  max-height: calc(100vh - 80px); // 80 px for the thumbnail space
164
164
  }
165
165
 
166
- &.left,
167
- &.right {
166
+ &.image-gallery-thumbnails-left,
167
+ &.image-gallery-thumbnails-right {
168
168
  .image-gallery-slide .image-gallery-image {
169
169
  max-height: 100vh;
170
170
  }
@@ -174,8 +174,8 @@ $ig-shadow: 0 2px 2px lighten($ig-black, 10%);
174
174
  .image-gallery-slide-wrapper {
175
175
  position: relative;
176
176
 
177
- &.left,
178
- &.right {
177
+ &.image-gallery-thumbnails-left,
178
+ &.image-gallery-thumbnails-right {
179
179
  display: inline-block;
180
180
  width: calc(100% - 110px); // 100px + 10px for margin
181
181
 
@@ -202,7 +202,7 @@ $ig-shadow: 0 2px 2px lighten($ig-black, 10%);
202
202
  top: 0;
203
203
  width: 100%;
204
204
 
205
- &.center {
205
+ &.image-gallery-center {
206
206
  position: relative;
207
207
  }
208
208
 
@@ -306,8 +306,8 @@ $ig-shadow: 0 2px 2px lighten($ig-black, 10%);
306
306
  &.thumbnails-wrapper-rtl {
307
307
  direction: rtl;
308
308
  }
309
- &.left,
310
- &.right {
309
+ &.image-gallery-thumbnails-left,
310
+ &.image-gallery-thumbnails-right {
311
311
  display: inline-block;
312
312
  vertical-align: top;
313
313
  width: 100px;
@@ -339,8 +339,8 @@ $ig-shadow: 0 2px 2px lighten($ig-black, 10%);
339
339
  }
340
340
  }
341
341
 
342
- &.left,
343
- &.right {
342
+ &.image-gallery-thumbnails-left,
343
+ &.image-gallery-thumbnails-right {
344
344
  margin: 0 5px;
345
345
 
346
346
  @media (max-width: $ig-small-screen) {
@@ -450,4 +450,4 @@ $ig-shadow: 0 2px 2px lighten($ig-black, 10%);
450
450
  font-size: .8em;
451
451
  padding: 5px 10px;
452
452
  }
453
- }
453
+ }
package/webpack.build.js CHANGED
@@ -1,57 +1,56 @@
1
-
2
- const path = require('path');
3
- const MiniCssExtractPlugin = require('mini-css-extract-plugin');
4
- const RemovePlugin = require('remove-files-webpack-plugin');
1
+ const path = require("path");
2
+ const MiniCssExtractPlugin = require("mini-css-extract-plugin");
3
+ const RemovePlugin = require("remove-files-webpack-plugin");
5
4
 
6
5
  const config = {
7
- mode: 'production',
6
+ mode: "production",
8
7
  };
9
8
 
10
9
  const jsOutput = Object.assign({}, config, {
11
- entry: [ './src/ImageGallery.js', ],
10
+ entry: ["./src/components/ImageGallery.jsx"],
12
11
  output: {
13
- path: path.resolve(__dirname, 'build'),
14
- filename: 'image-gallery.js',
15
- library: 'ImageGallery',
16
- globalObject: 'this',
17
- libraryTarget: 'umd',
12
+ path: path.resolve(__dirname, "build"),
13
+ filename: "image-gallery.js",
14
+ library: "ImageGallery",
15
+ globalObject: "this",
16
+ libraryTarget: "umd",
18
17
  },
19
18
  resolve: {
20
19
  alias: {
21
- src: path.resolve(__dirname, 'src/'),
20
+ src: path.resolve(__dirname, "src/"),
22
21
  },
23
- extensions: ['.js']
22
+ extensions: [".js", ".jsx"],
24
23
  },
25
24
  module: {
26
25
  rules: [
27
26
  {
28
- test: /\.js$/,
27
+ test: /\.(js|jsx)$/,
29
28
  exclude: /node_modules/,
30
- loader: 'babel-loader',
31
- }
32
- ]
29
+ loader: "babel-loader",
30
+ },
31
+ ],
33
32
  },
34
33
  externals: {
35
34
  // Don't bundle react or react-dom
36
35
  react: {
37
- commonjs: 'react',
38
- commonjs2: 'react',
39
- amd: 'react',
40
- root: 'React',
36
+ commonjs: "react",
37
+ commonjs2: "react",
38
+ amd: "react",
39
+ root: "React",
41
40
  },
42
- 'react-dom': {
43
- commonjs: 'react-dom',
44
- commonjs2: 'react-dom',
45
- amd: 'react-dom',
46
- root: 'ReactDOM',
41
+ "react-dom": {
42
+ commonjs: "react-dom",
43
+ commonjs2: "react-dom",
44
+ amd: "react-dom",
45
+ root: "ReactDOM",
47
46
  },
48
47
  },
49
48
  });
50
49
 
51
50
  const cssOutput = Object.assign({}, config, {
52
- entry: './styles/scss/image-gallery.scss',
51
+ entry: "./styles/scss/image-gallery.scss",
53
52
  output: {
54
- path: path.resolve(__dirname, 'styles/css'),
53
+ path: path.resolve(__dirname, "styles/css"),
55
54
  },
56
55
  module: {
57
56
  rules: [
@@ -60,16 +59,16 @@ const cssOutput = Object.assign({}, config, {
60
59
  use: [
61
60
  MiniCssExtractPlugin.loader,
62
61
  // Translates CSS into CommonJS
63
- 'css-loader',
62
+ "css-loader",
64
63
  // Compiles Sass to CSS
65
- 'sass-loader',
64
+ "sass-loader",
66
65
  ],
67
- }
68
- ]
66
+ },
67
+ ],
69
68
  },
70
69
  plugins: [
71
70
  new MiniCssExtractPlugin({
72
- filename: 'image-gallery.css',
71
+ filename: "image-gallery.css",
73
72
  }),
74
73
  new RemovePlugin({
75
74
  /**
@@ -78,36 +77,36 @@ const cssOutput = Object.assign({}, config, {
78
77
  after: {
79
78
  test: [
80
79
  {
81
- folder: 'styles/css',
80
+ folder: "styles/css",
82
81
  method: (absoluteItemPath) => {
83
- return new RegExp(/\.js$/, 'm').test(absoluteItemPath);
82
+ return new RegExp(/\.js$/, "m").test(absoluteItemPath);
84
83
  },
85
- }
86
- ]
87
- }
84
+ },
85
+ ],
86
+ },
88
87
  }),
89
88
  ],
90
89
  });
91
90
 
92
91
  const jsDemoOutput = Object.assign({}, config, {
93
- entry: [ './example/app.js', ],
92
+ entry: ["./example/App.jsx"],
94
93
  output: {
95
- path: path.resolve(__dirname, 'demo'),
96
- filename: 'demo.mini.js',
94
+ path: path.resolve(__dirname, "demo"),
95
+ filename: "demo.mini.js",
97
96
  },
98
97
  resolve: {
99
98
  alias: {
100
- src: path.resolve(__dirname, 'src/'),
99
+ src: path.resolve(__dirname, "src/"),
101
100
  },
102
- extensions: ['.js']
101
+ extensions: [".js", ".jsx"],
103
102
  },
104
103
  module: {
105
104
  rules: [
106
105
  {
107
- test: /\.js$/,
108
- loader: 'babel-loader',
109
- }
110
- ]
106
+ test: /\.(js|jsx)$/,
107
+ loader: "babel-loader",
108
+ },
109
+ ],
111
110
  },
112
111
  plugins: [
113
112
  new RemovePlugin({
@@ -117,21 +116,21 @@ const jsDemoOutput = Object.assign({}, config, {
117
116
  after: {
118
117
  test: [
119
118
  {
120
- folder: 'demo',
119
+ folder: "demo",
121
120
  method: (absoluteItemPath) => {
122
121
  return new RegExp(/\.txt$/).test(absoluteItemPath);
123
122
  },
124
- }
125
- ]
126
- }
123
+ },
124
+ ],
125
+ },
127
126
  }),
128
127
  ],
129
128
  });
130
129
 
131
130
  const cssDemoOutput = Object.assign({}, config, {
132
- entry: ['./styles/scss/image-gallery.scss', './example/app.css'],
131
+ entry: ["./styles/scss/image-gallery.scss", "./example/App.css"],
133
132
  output: {
134
- path: path.resolve(__dirname, 'demo'),
133
+ path: path.resolve(__dirname, "demo"),
135
134
  },
136
135
  module: {
137
136
  rules: [
@@ -140,16 +139,16 @@ const cssDemoOutput = Object.assign({}, config, {
140
139
  use: [
141
140
  MiniCssExtractPlugin.loader,
142
141
  // Translates CSS into CommonJS
143
- 'css-loader',
142
+ "css-loader",
144
143
  // Compiles Sass to CSS
145
- 'sass-loader',
144
+ "sass-loader",
146
145
  ],
147
- }
148
- ]
146
+ },
147
+ ],
149
148
  },
150
149
  plugins: [
151
150
  new MiniCssExtractPlugin({
152
- filename: 'demo.mini.css',
151
+ filename: "demo.mini.css",
153
152
  }),
154
153
  new RemovePlugin({
155
154
  /**
@@ -158,13 +157,13 @@ const cssDemoOutput = Object.assign({}, config, {
158
157
  after: {
159
158
  test: [
160
159
  {
161
- folder: 'demo',
160
+ folder: "demo",
162
161
  method: (absoluteItemPath) => {
163
162
  return new RegExp(/\.js$/).test(absoluteItemPath);
164
163
  },
165
- }
166
- ]
167
- }
164
+ },
165
+ ],
166
+ },
168
167
  }),
169
168
  ],
170
169
  });