UNPKG

17.8 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _stringify = require('babel-runtime/core-js/json/stringify');
8
9var _stringify2 = _interopRequireDefault(_stringify);
10
11var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties');
12
13var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2);
14
15var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
16
17var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
18
19var _extends2 = require('babel-runtime/helpers/extends');
20
21var _extends3 = _interopRequireDefault(_extends2);
22
23var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
24
25var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
26
27var _regenerator = require('babel-runtime/regenerator');
28
29var _regenerator2 = _interopRequireDefault(_regenerator);
30
31var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
32
33var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
34
35var _from = require('babel-runtime/core-js/array/from');
36
37var _from2 = _interopRequireDefault(_from);
38
39var _react = require('react');
40
41var _react2 = _interopRequireDefault(_react);
42
43var _styledComponents = require('styled-components');
44
45var _styledComponents2 = _interopRequireDefault(_styledComponents);
46
47var _StyledImageViewer = require('./StyledImageViewer');
48
49var _StyledImageViewer2 = _interopRequireDefault(_StyledImageViewer);
50
51var _helperFunctions = require('./helperFunctions');
52
53var _SVGDir = require('./svg/SVGDir');
54
55var _SVGDir2 = _interopRequireDefault(_SVGDir);
56
57var _reactMediumImageZoom = require('react-medium-image-zoom');
58
59var _reactMediumImageZoom2 = _interopRequireDefault(_reactMediumImageZoom);
60
61var _OutsideClickListener = require('./OutsideClickListener');
62
63var _Accordion = require('./Accordion');
64
65var _Accordion2 = _interopRequireDefault(_Accordion);
66
67var _defaultStyles = require('./defaultStyles');
68
69var _reactSwipeable = require('react-swipeable');
70
71var _KBListener = require('./KBListener');
72
73function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
74
75var NEXT = 'NEXT';
76var PREV = 'PREV';
77var GOTO = 'GOTO';
78
79var initialState = { pos: 0, sliding: false, dir: NEXT };
80
81var CONTAINER = _StyledImageViewer2.default.CONTAINER,
82 MAIN_FRAME = _StyledImageViewer2.default.MAIN_FRAME,
83 PREVIEW_BUTTON = _StyledImageViewer2.default.PREVIEW_BUTTON,
84 PREVIEW_FRAME = _StyledImageViewer2.default.PREVIEW_FRAME,
85 PREVIEW_ACCORDION = _StyledImageViewer2.default.PREVIEW_ACCORDION,
86 MAIN_IMAGE_FRAME = _StyledImageViewer2.default.MAIN_IMAGE_FRAME,
87 MAIN_IMAGE = _StyledImageViewer2.default.MAIN_IMAGE,
88 SMALL_NAV_BUTTON = _StyledImageViewer2.default.SMALL_NAV_BUTTON,
89 LARGE_NAV_BUTTON = _StyledImageViewer2.default.LARGE_NAV_BUTTON;
90
91
92var ImageViewer = function ImageViewer(_ref) {
93 var _ref$debug = _ref.debug,
94 debug = _ref$debug === undefined ? false : _ref$debug,
95 _ref$imageMargin = _ref.imageMargin,
96 imageMargin = _ref$imageMargin === undefined ? 30 : _ref$imageMargin,
97 _ref$srcs = _ref.srcs,
98 srcs = _ref$srcs === undefined ? (0, _from2.default)({ length: 8 }, function (_, i) {
99 return 'https://loremflickr.com/210/300?random=' + i;
100 }) : _ref$srcs,
101 disableDiscreteNavButtons = _ref.disableDiscreteNavButtons,
102 accordionProps = _ref.accordionProps,
103 layout = _ref.layout,
104 className = _ref.className,
105 style = _ref.style,
106 onClick = _ref.onClick,
107 renderMidArea = _ref.renderMidArea,
108 renderOption = _ref.renderOption,
109 renderOptions = _ref.renderOptions,
110 _ref$zoomedInImagePro = _ref.zoomedInImageProps,
111 zoomedInImageProps = _ref$zoomedInImagePro === undefined ? {} : _ref$zoomedInImagePro,
112 _ref$unzoomedImagePro = _ref.unzoomedImageProps,
113 unzoomedImageProps = _ref$unzoomedImagePro === undefined ? {
114 style: {
115 width: '30rem',
116 overflowX: 'hidden',
117 overflowY: 'hidden'
118 }
119 } : _ref$unzoomedImagePro,
120 _ref$cssImageUnzoomed = _ref.cssImageUnzoomedClass,
121 cssImageUnzoomedClass = _ref$cssImageUnzoomed === undefined ? 'imageviewer__image--unzoomed' : _ref$cssImageUnzoomed,
122 _ref$cssImageZoomedIn = _ref.cssImageZoomedInClass,
123 cssImageZoomedInClass = _ref$cssImageZoomedIn === undefined ? 'imageviewer__image--zoomed-in' : _ref$cssImageZoomedIn;
124
125 var slide = function () {
126 var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(dir) {
127 return _regenerator2.default.wrap(function _callee$(_context) {
128 while (1) {
129 switch (_context.prev = _context.next) {
130 case 0:
131 dispatch({ type: dir, numItems: numItems });
132 _context.next = 3;
133 return setTimeout(function () {
134 dispatch({ type: 'stopSliding' });
135 }, 1000);
136
137 case 3:
138 case 'end':
139 return _context.stop();
140 }
141 }
142 }, _callee, undefined);
143 }));
144
145 return function slide(_x) {
146 return _ref2.apply(this, arguments);
147 };
148 }();
149
150 var _useState = (0, _react.useState)(false),
151 _useState2 = (0, _slicedToArray3.default)(_useState, 2),
152 isComponentActive = _useState2[0],
153 setIsComponentActive = _useState2[1];
154
155 var reducer = function reducer(state, _ref3) {
156 var type = _ref3.type,
157 numItems = _ref3.numItems,
158 pos = _ref3.pos;
159
160 switch (type) {
161 case 'reset':
162 return initialState;
163 case PREV:
164 return (0, _extends3.default)({}, state, {
165 dir: PREV,
166 sliding: true,
167 pos: state.pos === 0 ? numItems - 1 : state.pos - 1
168 });
169 case NEXT:
170 return (0, _extends3.default)({}, state, {
171 dir: NEXT,
172 sliding: true,
173 pos: state.pos === numItems - 1 ? 0 : state.pos + 1
174 });
175 case GOTO:
176 return (0, _extends3.default)({}, state, {
177 pos: pos
178 });
179 case 'stopSliding':
180 return (0, _extends3.default)({}, state, {
181 sliding: false
182 });
183 default:
184 return state;
185 }
186 };
187
188 var goTo = function goTo(dir) {
189 console.log(dir);
190 slide(dir);
191 };
192
193 var _useReducer = (0, _react.useReducer)(reducer, initialState),
194 _useReducer2 = (0, _slicedToArray3.default)(_useReducer, 2),
195 state = _useReducer2[0],
196 dispatch = _useReducer2[1];
197
198 var dir = state.dir,
199 sliding = state.sliding,
200 pos = state.pos;
201
202 var _useState3 = (0, _react.useState)(false),
203 _useState4 = (0, _slicedToArray3.default)(_useState3, 2),
204 isSwiping = _useState4[0],
205 setIsSwipingTo = _useState4[1];
206
207 var handlers = (0, _reactSwipeable.useSwipeable)({
208 onSwiping: function onSwiping(e) {
209 setIsSwipingTo(true);
210 },
211 onSwiped: function onSwiped() {
212 setTimeout(function () {
213 setIsSwipingTo(false);
214 }, 150);
215 },
216 onSwipedLeft: function onSwipedLeft() {
217 goTo(NEXT);
218 },
219 onSwipedRight: function onSwipedRight() {
220 goTo(PREV);
221 },
222 trackMouse: true
223 //preventDefaultTouchmoveEvent: true,
224 });
225
226 var numItems = srcs.length;
227
228 var arrayOfSecondaryRefs = (0, _from2.default)({ length: srcs.length }, function () {
229 return (0, _react.useRef)(null);
230 });
231 var arrayOfPrimaryRefs = (0, _from2.default)({ length: srcs.length }, function () {
232 return (0, _react.useRef)(null);
233 });
234
235 var externalSwipeableRef = (0, _react.useRef)(null);
236 var mainImageRef = (0, _react.useRef)(null);
237
238 var _useState5 = (0, _react.useState)(0),
239 _useState6 = (0, _slicedToArray3.default)(_useState5, 2),
240 previewImageWidth = _useState6[0],
241 setPreviewImageWidthTo = _useState6[1];
242
243 var _useState7 = (0, _react.useState)(0),
244 _useState8 = (0, _slicedToArray3.default)(_useState7, 2),
245 previewImageHeight = _useState8[0],
246 setPreviewImageHeightTo = _useState8[1];
247
248 var _useState9 = (0, _react.useState)(0),
249 _useState10 = (0, _slicedToArray3.default)(_useState9, 2),
250 previewImageFrameWidth = _useState10[0],
251 setPreviewImageFrameWidthTo = _useState10[1];
252
253 var _useState11 = (0, _react.useState)(0),
254 _useState12 = (0, _slicedToArray3.default)(_useState11, 2),
255 previewImageFrameHeight = _useState12[0],
256 setPreviewImageFrameHeightTo = _useState12[1];
257
258 var _useState13 = (0, _react.useState)(0),
259 _useState14 = (0, _slicedToArray3.default)(_useState13, 2),
260 mainImageWidth = _useState14[0],
261 setMainImageWidthTo = _useState14[1];
262
263 var _useState15 = (0, _react.useState)(0),
264 _useState16 = (0, _slicedToArray3.default)(_useState15, 2),
265 mainImageMaxHeight = _useState16[0],
266 setMainImageMaxHeightTo = _useState16[1];
267
268 (0, _react.useEffect)(function () {
269 var previewImageElement = arrayOfSecondaryRefs[pos] && arrayOfSecondaryRefs[pos].current;
270
271 if (previewImageElement) {
272 var previewImageBCR = previewImageElement.getBoundingClientRect();
273 setPreviewImageWidthTo(previewImageBCR.width);
274 setPreviewImageHeightTo(previewImageBCR.height);
275
276 if (externalSwipeableRef) {
277 var previewFrameBCR = externalSwipeableRef.current.getBoundingClientRect();
278 setPreviewImageFrameWidthTo(previewFrameBCR.width);
279 setPreviewImageFrameHeightTo(previewFrameBCR.height);
280 }
281
282 externalSwipeableRef.current.scrollTo({
283 left: previewImageWidth * (pos + 0.5) - previewImageFrameWidth / 2,
284 top: previewImageHeight * (pos + 0.5) - previewImageFrameHeight / 2,
285 behavior: 'smooth'
286 });
287 }
288 }, [pos]);
289
290 var _useState17 = (0, _react.useState)(0),
291 _useState18 = (0, _slicedToArray3.default)(_useState17, 2),
292 forced = _useState18[0],
293 forceUpdate = _useState18[1];
294
295 (0, _react.useEffect)(function () {
296 setTimeout(function () {
297 return forceUpdate(1);
298 }, 200);
299 }, []);
300
301 (0, _react.useEffect)(function () {
302 debug && console.log(arrayOfPrimaryRefs[0].current && arrayOfPrimaryRefs[0].current.offsetHeight);
303 var mainImageElement = arrayOfPrimaryRefs[pos] && arrayOfPrimaryRefs[pos].current;
304 if (mainImageElement) {
305 setMainImageWidthTo(mainImageElement.getBoundingClientRect().width);
306 setMainImageMaxHeightTo(Math.max.apply(Math, (0, _toConsumableArray3.default)(arrayOfPrimaryRefs.map(function (primaryRef) {
307 return primaryRef.current.getBoundingClientRect().height;
308 }))));
309
310 if (sliding) {
311 var by = (mainImageWidth + imageMargin) * pos;
312
313 mainImageRef.current.scrollTo({
314 left: by,
315 behavior: 'smooth'
316 });
317 } else {
318 var _by = (mainImageWidth + imageMargin) * pos;
319
320 mainImageRef.current.scrollTo({
321 left: _by
322 });
323 }
324 }
325 }, [pos, forced]);
326
327 var getOptionProps = function getOptionProps(src, i) {
328 return function () {
329 var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
330
331 var className = _ref4.className,
332 style = _ref4.style,
333 _onClick = _ref4.onClick,
334 props = (0, _objectWithoutProperties3.default)(_ref4, ['className', 'style', 'onClick']);
335
336 return (0, _extends3.default)({
337 style: (0, _extends3.default)({
338 backgroundImage: 'url(\'' + src + '\')'
339 }, style),
340 key: i,
341 onClick: function onClick(e) {
342 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
343 args[_key - 1] = arguments[_key];
344 }
345
346 _onClick && _onClick.apply(undefined, [e].concat(args));
347 dispatch({ type: GOTO, pos: i });
348 },
349
350 id: 'imageviewer__preview__item-' + i,
351 className: className ? (0, _helperFunctions.flippyClass)(pos === i, 'imageviewer__preview__item', 'active', 'inactive') + ' ' + (0, _helperFunctions.flippyClass)(pos === i, className, 'active', 'inactive') : (0, _helperFunctions.flippyClass)(pos === i, 'imageviewer__preview__item', 'active', 'inactive')
352 }, props);
353 };
354 };
355 var renderDebugArea = function renderDebugArea() {
356 return _react2.default.createElement(
357 'div',
358 { style: { background: '#fff' } },
359 (0, _stringify2.default)(state),
360 ' isComponentActive: ',
361 (0, _stringify2.default)(isComponentActive)
362 );
363 };
364
365 var _useOutsideClickListe = (0, _OutsideClickListener.useOutsideClickListener)({
366 outsideHandler: function outsideHandler() {
367 return setIsComponentActive(false);
368 },
369 insideHandler: function insideHandler() {
370 return setIsComponentActive(true);
371 }
372 }),
373 elClickListenerRef = _useOutsideClickListe.elClickListenerRef;
374
375 (0, _KBListener.useKBListener)({
376 keyCodes: [[37, function () {
377 if (isComponentActive) {
378 slide(PREV);
379 }
380 }], [39, function () {
381 if (isComponentActive) {
382 slide(NEXT);
383 }
384 }]]
385 });
386
387 var sharedButtonProps = {
388 layout: layout,
389 disableDiscreteNavButtons: disableDiscreteNavButtons,
390 previewImageHeight: previewImageHeight,
391 mainImageMaxHeight: mainImageMaxHeight,
392 previewImageWidth: previewImageWidth,
393 mainImageWidth: mainImageWidth,
394 srcsLength: srcs.length
395 };
396
397 var renderImageZoom = function renderImageZoom(src) {
398 return _react2.default.createElement(_reactMediumImageZoom2.default, {
399 shouldHandleZoom: function shouldHandleZoom(e) {
400 return !isSwiping;
401 },
402 image: (0, _extends3.default)({
403 src: src,
404 className: cssImageUnzoomedClass
405 }, unzoomedImageProps),
406 zoomImage: (0, _extends3.default)({
407 src: src,
408 className: cssImageZoomedInClass
409 }, zoomedInImageProps)
410 });
411 };
412
413 var renderLargeNavButton = function renderLargeNavButton(dir) {
414 var cardinalDir = dir === NEXT ? 'Right' : 'Left';
415 return _react2.default.createElement(
416 LARGE_NAV_BUTTON,
417 (0, _extends3.default)({}, sharedButtonProps, {
418 dir: dir,
419 onClick: function onClick() {
420 return goTo(dir);
421 },
422 className: 'imageviewer__topnav imageviewer__topnav__' + dir,
423 colors: _defaultStyles.buttonStyles.semiTransparentNeutral
424 }),
425 _react2.default.createElement(_SVGDir2.default, { size: 30, fill: '#666666', dir: cardinalDir })
426 );
427 };
428
429 var renderSmallNavButton = function renderSmallNavButton(dir) {
430 var cardinalDir = dir === NEXT ? 'Right' : 'Left';
431 return _react2.default.createElement(
432 SMALL_NAV_BUTTON,
433 (0, _extends3.default)({}, sharedButtonProps, {
434 onClick: function onClick() {
435 return goTo(dir);
436 },
437 className: 'imageviewer__bottomnav imageviewer__bottomnav__' + dir,
438 colors: _defaultStyles.buttonStyles.semiTransparentNeutral
439 }),
440 _react2.default.createElement(_SVGDir2.default, { size: '24', fill: '#666666', dir: cardinalDir })
441 );
442 };
443 var accordionFrameProps = {
444 layout: layout,
445 previewImageWidth: previewImageWidth,
446 mainImageWidth: mainImageWidth,
447 previewImageHeight: previewImageHeight,
448 mainImageMaxHeight: mainImageMaxHeight,
449 srcsLength: srcs.length
450 };
451 return _react2.default.createElement(
452 CONTAINER,
453 {
454 layout: layout,
455 onClick: onClick,
456 className: (0, _helperFunctions.advancedMulti)({
457 unflattenedBases: [className, 'imageviewer__container'],
458 flipVars: [[isComponentActive, 'active', 'inactive']]
459 }),
460 ref: elClickListenerRef,
461 style: style
462 },
463 _react2.default.createElement(
464 MAIN_FRAME,
465 null,
466 renderLargeNavButton(PREV),
467 _react2.default.createElement(
468 MAIN_IMAGE_FRAME,
469 (0, _extends3.default)({}, handlers, {
470 ref: mainImageRef,
471 imageWidth: mainImageWidth
472 }),
473 srcs.map(function (src, i) {
474 return _react2.default.createElement(
475 MAIN_IMAGE,
476 {
477 ref: arrayOfPrimaryRefs[i],
478 key: i,
479 imageMargin: imageMargin
480 },
481 renderImageZoom(src)
482 );
483 })
484 ),
485 renderLargeNavButton(NEXT)
486 ),
487 renderMidArea && renderMidArea(),
488 debug && renderDebugArea(),
489 renderOptions ? renderOptions({
490 getOptionProps: getOptionProps,
491 srcs: srcs,
492 pos: pos,
493 externalSwipeableRef: externalSwipeableRef,
494 accordionFrameProps: accordionFrameProps,
495 arrayOfSecondaryRefs: arrayOfSecondaryRefs
496 }) : _react2.default.createElement(
497 PREVIEW_FRAME,
498 { layout: layout },
499 renderSmallNavButton(PREV),
500 _react2.default.createElement(
501 _Accordion2.default,
502 {
503 externalSwipeableRef: externalSwipeableRef
504 },
505 function (_ref5) {
506 var handlers = _ref5.handlers,
507 swipeableRef = _ref5.swipeableRef;
508 return _react2.default.createElement(
509 PREVIEW_ACCORDION,
510 (0, _extends3.default)({}, accordionFrameProps, handlers, {
511 ref: swipeableRef
512 }, accordionProps),
513 srcs.map(function (src, i) {
514 return renderOption ? renderOption({
515 getOptionProps: getOptionProps(src, i),
516 isActive: pos === i,
517 containerRef: arrayOfSecondaryRefs[i]
518 }) : _react2.default.createElement(PREVIEW_BUTTON, (0, _extends3.default)({
519 isOn: pos === i,
520 colors: 'darken',
521 containerRef: arrayOfSecondaryRefs[i]
522 }, getOptionProps(src, i)()));
523 })
524 );
525 }
526 ),
527 renderSmallNavButton(NEXT)
528 )
529 );
530};
531
532exports.default = _react2.default.memo(ImageViewer);
\No newline at end of file