react-editable-photo-grid 1.0.0 → 2.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.
- package/README.md +195 -1
- package/dist/index.js +1 -1
- package/package.json +12 -7
- package/src/PhotoGrid.tsx +130 -54
- package/src/components/Checkbox.tsx +27 -0
- package/src/components/NonScrollGallery.tsx +188 -0
- package/src/components/PhotoControls.tsx +29 -33
- package/src/components/RowControls.tsx +6 -8
- package/src/components/ScrollGallery.tsx +190 -0
- package/src/index.js +4 -1
- package/src/styles.css +328 -1
- package/src/types.ts +34 -4
- package/src/utils.tsx +120 -24
- package/.babelrc +0 -3
- package/tsconfig.json +0 -18
- package/webpack.config.js +0 -39
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import React, { useEffect, useState, TouchEvent } from 'react'
|
|
2
|
+
import { imgSrcProperty, GalleryButtonArrows, PhotoItem } from '../types';
|
|
3
|
+
import { getImageSrcProperty, photoHasDetails } from "../utils";
|
|
4
|
+
|
|
5
|
+
type GalleryProps = {
|
|
6
|
+
photos: PhotoItem[],
|
|
7
|
+
activeKey: number,
|
|
8
|
+
setActiveKey: (key: number) => void,
|
|
9
|
+
imageSrcPrefix: string;
|
|
10
|
+
imageSrcProperty: imgSrcProperty;
|
|
11
|
+
buttonArrows?: GalleryButtonArrows;
|
|
12
|
+
onGallerySwipe?: (photo: PhotoItem) => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const NonScrollGallery = (props: GalleryProps) => {
|
|
16
|
+
const [touchPosition, setTouchPosition] = useState<number | null>(null),
|
|
17
|
+
[visible, setVisible] = useState<boolean>(false);
|
|
18
|
+
|
|
19
|
+
const getSrcProperty = (photo: PhotoItem): string => {
|
|
20
|
+
const property = props.imageSrcProperty as string;
|
|
21
|
+
return getImageSrcProperty(photo, property);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const showGallery = () => {
|
|
25
|
+
setVisible(true);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const handleSwipe = () => {
|
|
29
|
+
if (props.onGallerySwipe) {
|
|
30
|
+
const photoKey = props.activeKey,
|
|
31
|
+
photo: PhotoItem = props.photos[photoKey];
|
|
32
|
+
|
|
33
|
+
if (photo) {
|
|
34
|
+
props.onGallerySwipe(photo);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const shouldRenderImage = (index: number) => {
|
|
40
|
+
const key = props.activeKey;
|
|
41
|
+
let validIndexes = [key];
|
|
42
|
+
|
|
43
|
+
if (key > 0) {
|
|
44
|
+
validIndexes.push(key - 1);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (key < props.photos.length - 1) {
|
|
48
|
+
validIndexes.push(key + 1);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return validIndexes.includes(index);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const prevItem = (e: React.MouseEvent<HTMLButtonElement>) => {
|
|
55
|
+
e.preventDefault()
|
|
56
|
+
if (props.activeKey > 0) {
|
|
57
|
+
props.setActiveKey(props.activeKey - 1);
|
|
58
|
+
handleSwipe();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const nextItem = (e: React.MouseEvent<HTMLButtonElement>) => {
|
|
63
|
+
e.preventDefault()
|
|
64
|
+
if (props.activeKey < props.photos.length - 1) {
|
|
65
|
+
props.setActiveKey(props.activeKey + 1);
|
|
66
|
+
handleSwipe();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const keydownHandler = (e: KeyboardEvent) => {
|
|
71
|
+
if (e.keyCode === 39) {
|
|
72
|
+
if (props.activeKey < props.photos.length - 1) {
|
|
73
|
+
props.setActiveKey(props.activeKey + 1);
|
|
74
|
+
}
|
|
75
|
+
} else if (e.keyCode === 37) {
|
|
76
|
+
if (props.activeKey > 0) {
|
|
77
|
+
props.setActiveKey(props.activeKey - 1);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
handleSwipe();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const hideGallery = () => {
|
|
84
|
+
setVisible(false);
|
|
85
|
+
props.setActiveKey(-1);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const disableRightClick = () => {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const handleTouchStart = (e: TouchEvent<HTMLDivElement>) => {
|
|
93
|
+
const touchDown = e.touches[0].clientX;
|
|
94
|
+
setTouchPosition(touchDown);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const handleTouchMove = (e: TouchEvent<HTMLDivElement>) => {
|
|
98
|
+
if (touchPosition === null) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const currentTouch = e.touches[0].clientX,
|
|
103
|
+
diff = touchPosition - currentTouch;
|
|
104
|
+
|
|
105
|
+
if (diff > 5) {
|
|
106
|
+
if (props.activeKey < props.photos.length - 1) {
|
|
107
|
+
props.setActiveKey(props.activeKey + 1);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (diff < -5) {
|
|
112
|
+
if (props.activeKey > 0) {
|
|
113
|
+
props.setActiveKey(props.activeKey - 1);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
handleSwipe();
|
|
118
|
+
setTouchPosition(null);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
if (props.activeKey > -1) {
|
|
123
|
+
if (visible === false) {
|
|
124
|
+
showGallery()
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
document.addEventListener('keydown', keydownHandler);
|
|
129
|
+
|
|
130
|
+
return function cleanup() {
|
|
131
|
+
document.removeEventListener('keydown', keydownHandler);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
}, [props.activeKey])
|
|
135
|
+
|
|
136
|
+
return (
|
|
137
|
+
<div
|
|
138
|
+
className="custom__gallery"
|
|
139
|
+
style={{ display: visible === true ? 'block' : 'none' }}
|
|
140
|
+
onTouchStart={handleTouchStart}
|
|
141
|
+
onTouchMove={handleTouchMove}
|
|
142
|
+
>
|
|
143
|
+
<div className="clearfix">
|
|
144
|
+
<button className="close__gallery" onClick={hideGallery} type="button">×</button>
|
|
145
|
+
</div>
|
|
146
|
+
<div className="custom__gallery__container">
|
|
147
|
+
{props.activeKey > 0 &&
|
|
148
|
+
<button
|
|
149
|
+
onClick={prevItem}
|
|
150
|
+
className="previous__item"
|
|
151
|
+
dangerouslySetInnerHTML={{ __html: props.buttonArrows ? props.buttonArrows.prev : '←' }}
|
|
152
|
+
/>
|
|
153
|
+
}
|
|
154
|
+
<div className="custom__gallery__images">
|
|
155
|
+
{props.photos.length &&
|
|
156
|
+
props.photos.map((photo, i) =>
|
|
157
|
+
<div key={`${i}`} className={props.activeKey == i ? "custom__gallery__item active" : "custom__gallery__item"}>
|
|
158
|
+
<img
|
|
159
|
+
src={shouldRenderImage(i) ? `${props.imageSrcPrefix}${getSrcProperty(photo)}` : ''}
|
|
160
|
+
alt="gallery item"
|
|
161
|
+
onContextMenu={disableRightClick}
|
|
162
|
+
/>
|
|
163
|
+
{photoHasDetails(photo) === true && (
|
|
164
|
+
<div className="custom__gallery__photo__overlay">
|
|
165
|
+
{photo.name != undefined && photo.name !== '' && (
|
|
166
|
+
<h4>{photo.name}</h4>
|
|
167
|
+
)}
|
|
168
|
+
{photo.description != undefined && photo.description !== '' && (
|
|
169
|
+
<p>{photo.description}</p>
|
|
170
|
+
)}
|
|
171
|
+
</div>
|
|
172
|
+
)}
|
|
173
|
+
</div>
|
|
174
|
+
)}
|
|
175
|
+
</div>
|
|
176
|
+
{props.activeKey < props.photos.length - 1 &&
|
|
177
|
+
<button
|
|
178
|
+
onClick={nextItem}
|
|
179
|
+
className="next__item"
|
|
180
|
+
dangerouslySetInnerHTML={{ __html: props.buttonArrows ? props.buttonArrows.next : '→' }}
|
|
181
|
+
/>
|
|
182
|
+
}
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export default NonScrollGallery;
|
|
@@ -1,61 +1,57 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { PhotoControlsProps } from '../types';
|
|
3
3
|
import { castRowKey } from '../utils';
|
|
4
|
-
import'../styles.css';
|
|
4
|
+
import '../styles.css';
|
|
5
5
|
|
|
6
6
|
const PhotoControls = (props: PhotoControlsProps) => {
|
|
7
7
|
return (
|
|
8
8
|
<ul className="photogrid--photo__controls">
|
|
9
9
|
{props.photo.column > 1 &&
|
|
10
10
|
<li>
|
|
11
|
-
<button
|
|
12
|
-
type="button"
|
|
13
|
-
className="photo__control"
|
|
14
|
-
onClick={props.movePhotoLeft}
|
|
15
|
-
data-id={props.photo.id}
|
|
11
|
+
<button
|
|
12
|
+
type="button"
|
|
13
|
+
className="photo__control move__photo__left"
|
|
14
|
+
onClick={props.movePhotoLeft}
|
|
15
|
+
data-id={props.photo.id}
|
|
16
16
|
data-row={props.rowKey}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
</button>
|
|
17
|
+
dangerouslySetInnerHTML={{ __html: props.buttonArrows ? props.buttonArrows.left : '←' }}
|
|
18
|
+
/>
|
|
20
19
|
</li>
|
|
21
20
|
}
|
|
22
21
|
{castRowKey(props.rowKey) > 1 &&
|
|
23
22
|
<li>
|
|
24
|
-
<button
|
|
25
|
-
type="button"
|
|
26
|
-
className="photo__control"
|
|
27
|
-
onClick={props.movePhotoUp}
|
|
28
|
-
data-id={props.photo.id}
|
|
23
|
+
<button
|
|
24
|
+
type="button"
|
|
25
|
+
className="photo__control move__photo__up"
|
|
26
|
+
onClick={props.movePhotoUp}
|
|
27
|
+
data-id={props.photo.id}
|
|
29
28
|
data-row={props.rowKey}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
</button>
|
|
29
|
+
dangerouslySetInnerHTML={{ __html: props.buttonArrows ? props.buttonArrows.up : '↑' }}
|
|
30
|
+
/>
|
|
33
31
|
</li>
|
|
34
32
|
}
|
|
35
33
|
{castRowKey(props.rowKey) < props.rowCount || castRowKey(props.rowKey) === props.rowCount && props.photoCount > 1 ?
|
|
36
34
|
<li>
|
|
37
|
-
<button
|
|
38
|
-
type="button"
|
|
39
|
-
className="photo__control"
|
|
40
|
-
onClick={props.movePhotoDown}
|
|
41
|
-
data-id={props.photo.id}
|
|
35
|
+
<button
|
|
36
|
+
type="button"
|
|
37
|
+
className="photo__control move__photo__down"
|
|
38
|
+
onClick={props.movePhotoDown}
|
|
39
|
+
data-id={props.photo.id}
|
|
42
40
|
data-row={props.rowKey}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
</button>
|
|
41
|
+
dangerouslySetInnerHTML={{ __html: props.buttonArrows ? props.buttonArrows.down : '↓' }}
|
|
42
|
+
/>
|
|
46
43
|
</li> : null
|
|
47
44
|
}
|
|
48
45
|
{props.photo.column < props.photoCount &&
|
|
49
46
|
<li>
|
|
50
|
-
<button
|
|
51
|
-
type="button"
|
|
52
|
-
className="photo__control"
|
|
53
|
-
onClick={props.movePhotoRight}
|
|
54
|
-
data-id={props.photo.id}
|
|
47
|
+
<button
|
|
48
|
+
type="button"
|
|
49
|
+
className="photo__control move__photo__right"
|
|
50
|
+
onClick={props.movePhotoRight}
|
|
51
|
+
data-id={props.photo.id}
|
|
55
52
|
data-row={props.rowKey}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
</button>
|
|
53
|
+
dangerouslySetInnerHTML={{ __html: props.buttonArrows ? props.buttonArrows.right : '→' }}
|
|
54
|
+
/>
|
|
59
55
|
</li>
|
|
60
56
|
}
|
|
61
57
|
</ul>
|
|
@@ -9,23 +9,21 @@ const RowControls = (props: RowControlsProps) => {
|
|
|
9
9
|
{castRowKey(props.rowKey) > 1 &&
|
|
10
10
|
<li>
|
|
11
11
|
<button
|
|
12
|
-
className="row__control"
|
|
12
|
+
className="row__control move__row__up"
|
|
13
13
|
onClick={props.moveRowUp}
|
|
14
14
|
data-row={props.rowKey}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
</button>
|
|
15
|
+
dangerouslySetInnerHTML={{ __html: props.buttonArrows ? props.buttonArrows.up : '↑' }}
|
|
16
|
+
/>
|
|
18
17
|
</li>
|
|
19
18
|
}
|
|
20
19
|
{castRowKey(props.rowKey) < props.rowCount &&
|
|
21
20
|
<li>
|
|
22
21
|
<button
|
|
23
|
-
className="row__control"
|
|
22
|
+
className="row__control move__row__down"
|
|
24
23
|
onClick={props.moveRowDown}
|
|
25
24
|
data-row={props.rowKey}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
</button>
|
|
25
|
+
dangerouslySetInnerHTML={{ __html: props.buttonArrows ? props.buttonArrows.down : '↓' }}
|
|
26
|
+
/>
|
|
29
27
|
</li>
|
|
30
28
|
}
|
|
31
29
|
</ul>
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
|
2
|
+
import { imgSrcProperty, GalleryButtonArrows, PhotoItem } from '../types';
|
|
3
|
+
import { photoHasDetails } from "../utils";
|
|
4
|
+
import debounce from 'lodash.debounce';
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
photos: PhotoItem[],
|
|
8
|
+
activeKey: number,
|
|
9
|
+
setActiveKey: (key: number) => void,
|
|
10
|
+
imageSrcPrefix: string;
|
|
11
|
+
imageSrcProperty: imgSrcProperty;
|
|
12
|
+
onGallerySwipe?: (photo: PhotoItem) => void;
|
|
13
|
+
buttonArrows?: GalleryButtonArrows;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const ScrollGallery: React.FC<Props> = ({ photos, imageSrcPrefix, imageSrcProperty, onGallerySwipe, activeKey, setActiveKey, buttonArrows }) => {
|
|
17
|
+
const [visible, setVisible] = useState<boolean>(false),
|
|
18
|
+
scrollContainer = useRef<HTMLDivElement | null>(null),
|
|
19
|
+
imgRefs = useRef<(HTMLImageElement | null)[]>([]),
|
|
20
|
+
[swipeEnabled, setSwipeEnabled] = useState(false);
|
|
21
|
+
|
|
22
|
+
const getImageSrcProperty = (photo: PhotoItem, property: string): string => {
|
|
23
|
+
switch (property) {
|
|
24
|
+
case 'id':
|
|
25
|
+
return photo.id;
|
|
26
|
+
case 'thumbnail_path':
|
|
27
|
+
return photo.thumbnail_path;
|
|
28
|
+
case 'image_path':
|
|
29
|
+
return photo.image_path;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return photo.image_path;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const handleSwipe = (index: number) => {
|
|
36
|
+
if (onGallerySwipe && swipeEnabled) {
|
|
37
|
+
const photo: PhotoItem = photos[index];
|
|
38
|
+
|
|
39
|
+
if (photo) {
|
|
40
|
+
onGallerySwipe(photo);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const hideGallery = () => {
|
|
46
|
+
setVisible(false);
|
|
47
|
+
setActiveKey(-1);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const jumpToImage = useCallback(
|
|
51
|
+
debounce((index: number) => {
|
|
52
|
+
setSwipeEnabled(false);
|
|
53
|
+
|
|
54
|
+
const imgElement = imgRefs.current[index];
|
|
55
|
+
const containerElement = scrollContainer.current;
|
|
56
|
+
|
|
57
|
+
if (imgElement && containerElement) {
|
|
58
|
+
const imgRect = imgElement.getBoundingClientRect();
|
|
59
|
+
const containerRect = containerElement.getBoundingClientRect();
|
|
60
|
+
|
|
61
|
+
const scrollLeft = imgRect.left - containerRect.left + containerElement.scrollLeft;
|
|
62
|
+
|
|
63
|
+
containerElement.scrollTo({
|
|
64
|
+
left: scrollLeft,
|
|
65
|
+
behavior: 'smooth'
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
setSwipeEnabled(true);
|
|
70
|
+
}, 100),
|
|
71
|
+
[]
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const disableRightClick = (e: React.MouseEvent<HTMLImageElement>) => {
|
|
75
|
+
e.preventDefault();
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const scrollLeft = (e: React.MouseEvent<HTMLButtonElement>) => {
|
|
80
|
+
e.preventDefault();
|
|
81
|
+
if (scrollContainer.current != undefined) {
|
|
82
|
+
scrollContainer.current.scrollBy({
|
|
83
|
+
top: 0,
|
|
84
|
+
left: -1,
|
|
85
|
+
behavior: 'smooth'
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const scrollRight = (e: React.MouseEvent<HTMLButtonElement>) => {
|
|
91
|
+
e.preventDefault();
|
|
92
|
+
if (scrollContainer.current != undefined) {
|
|
93
|
+
scrollContainer.current.scrollBy({
|
|
94
|
+
top: 0,
|
|
95
|
+
left: 800,
|
|
96
|
+
behavior: 'smooth'
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const loadImagesSrc = () => {
|
|
102
|
+
imgRefs.current.forEach((img, index) => {
|
|
103
|
+
if (img) {
|
|
104
|
+
const src = img.getAttribute('data-src');
|
|
105
|
+
if (src) {
|
|
106
|
+
img.src = src;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
})
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {
|
|
113
|
+
return;
|
|
114
|
+
const target = e.currentTarget as HTMLDivElement;
|
|
115
|
+
const { scrollLeft } = target;
|
|
116
|
+
const itemWidth = target.clientWidth;
|
|
117
|
+
const index = Math.round(scrollLeft / itemWidth);
|
|
118
|
+
setActiveKey(index);
|
|
119
|
+
handleSwipe(index);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
useEffect(() => {
|
|
123
|
+
if (activeKey > -1 && visible === false) {
|
|
124
|
+
setVisible(true);
|
|
125
|
+
jumpToImage(activeKey);
|
|
126
|
+
}
|
|
127
|
+
}, [activeKey]);
|
|
128
|
+
|
|
129
|
+
useEffect(() => {
|
|
130
|
+
loadImagesSrc();
|
|
131
|
+
}, [photos]);
|
|
132
|
+
|
|
133
|
+
return (
|
|
134
|
+
<div
|
|
135
|
+
className={`${visible ? 'block' : 'hidden'} photogrid__gallery`}
|
|
136
|
+
>
|
|
137
|
+
<div className="photogrid__gallery__hide">
|
|
138
|
+
<button onClick={hideGallery} type="button">×</button>
|
|
139
|
+
</div>
|
|
140
|
+
<div
|
|
141
|
+
className="photogrid__prev"
|
|
142
|
+
>
|
|
143
|
+
<button
|
|
144
|
+
type="button"
|
|
145
|
+
onClick={scrollLeft}
|
|
146
|
+
dangerouslySetInnerHTML={{ __html: buttonArrows ? buttonArrows.prev : '←' }}
|
|
147
|
+
/>
|
|
148
|
+
</div>
|
|
149
|
+
<div
|
|
150
|
+
ref={scrollContainer}
|
|
151
|
+
className="photogrid__gallery_scrollcontainer"
|
|
152
|
+
onScroll={handleScroll}
|
|
153
|
+
>
|
|
154
|
+
{photos.length &&
|
|
155
|
+
photos.map((photo, i) =>
|
|
156
|
+
<div key={`${i}`} className="photogrid__gallery_item">
|
|
157
|
+
<img
|
|
158
|
+
ref={el => imgRefs.current[i] = el}
|
|
159
|
+
data-index={i}
|
|
160
|
+
data-src={`${imageSrcPrefix}${getImageSrcProperty(photo, imageSrcProperty)}`}
|
|
161
|
+
alt="gallery item"
|
|
162
|
+
onContextMenu={disableRightClick}
|
|
163
|
+
/>
|
|
164
|
+
{photoHasDetails(photo) === true && (
|
|
165
|
+
<div className="photogrid__gallery_item__overlay">
|
|
166
|
+
{photo.name != undefined && photo.name !== '' && (
|
|
167
|
+
<h4>{photo.name}</h4>
|
|
168
|
+
)}
|
|
169
|
+
{photo.description != undefined && photo.description !== '' && (
|
|
170
|
+
<p>{photo.description}</p>
|
|
171
|
+
)}
|
|
172
|
+
</div>
|
|
173
|
+
)}
|
|
174
|
+
</div>
|
|
175
|
+
)}
|
|
176
|
+
</div>
|
|
177
|
+
<div
|
|
178
|
+
className="photogrid__next"
|
|
179
|
+
>
|
|
180
|
+
<button
|
|
181
|
+
type="button"
|
|
182
|
+
onClick={scrollRight}
|
|
183
|
+
dangerouslySetInnerHTML={{ __html: buttonArrows ? buttonArrows.next : '→' }}
|
|
184
|
+
/>
|
|
185
|
+
</div>
|
|
186
|
+
</div>
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export default ScrollGallery;
|
package/src/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import PhotoGrid from './PhotoGrid';
|
|
2
|
+
import Checkbox from './components/Checkbox';
|
|
3
|
+
import { PhotoRows, PhotoItem, imgSrcProperty } from './types';
|
|
4
|
+
import { sortPhotosIntoRows } from './utils';
|
|
2
5
|
|
|
3
|
-
export { PhotoGrid };
|
|
6
|
+
export { PhotoGrid, PhotoRows, PhotoItem, imgSrcProperty, sortPhotosIntoRows, Checkbox };
|