Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-spring-lightbox

Package Overview
Dependencies
Maintainers
1
Versions
88
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-spring-lightbox - npm Package Compare versions

Comparing version 1.4.9 to 1.4.10-beta.0

1004

dist/index.cjs.js

@@ -1,1004 +0,2 @@

'use strict';
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var React = require('react');
var React__default = _interopDefault(React);
var _taggedTemplateLiteral = _interopDefault(require('@babel/runtime/helpers/taggedTemplateLiteral'));
var styled = _interopDefault(require('styled-components'));
var _slicedToArray = _interopDefault(require('@babel/runtime/helpers/slicedToArray'));
var _toConsumableArray = _interopDefault(require('@babel/runtime/helpers/toConsumableArray'));
var web = require('@react-spring/web');
var reactUseGesture = require('react-use-gesture');
var _defineProperty = _interopDefault(require('@babel/runtime/helpers/defineProperty'));
var _classCallCheck = _interopDefault(require('@babel/runtime/helpers/classCallCheck'));
var _createClass = _interopDefault(require('@babel/runtime/helpers/createClass'));
var _assertThisInitialized = _interopDefault(require('@babel/runtime/helpers/assertThisInitialized'));
var _inherits = _interopDefault(require('@babel/runtime/helpers/inherits'));
var _possibleConstructorReturn = _interopDefault(require('@babel/runtime/helpers/possibleConstructorReturn'));
var _getPrototypeOf = _interopDefault(require('@babel/runtime/helpers/getPrototypeOf'));
var ReactDOM = _interopDefault(require('react-dom'));
/**
* Calculates the the translate(x,y) coordinates needed to zoom-in
* to a point in an image.
*
* @param {ref} imageRef The image dom node used as a reference to calculate translate offsets
* @param {number} scale The current transform scale of image
* @param {number} pinchDelta The amount of change in the new transform scale
* @param {array} touchOrigin The [x,y] coordinates of the zoom origin
* @param {array} currentTranslate The current [x,y] translate values of image
*
* @returns {array} The next [x,y] translate values to apply to image
*/
var getTranslateOffsetsFromScale = function getTranslateOffsetsFromScale(_ref) {
var imageRef = _ref.imageRef,
scale = _ref.scale,
pinchDelta = _ref.pinchDelta,
_ref$touchOrigin = _slicedToArray(_ref.touchOrigin, 2),
touchOriginX = _ref$touchOrigin[0],
touchOriginY = _ref$touchOrigin[1],
_ref$currentTranslate = _slicedToArray(_ref.currentTranslate, 2),
translateX = _ref$currentTranslate[0],
translateY = _ref$currentTranslate[1];
var _imageRef$current$get = imageRef.current.getBoundingClientRect(),
imageTopLeftY = _imageRef$current$get.top,
imageTopLeftX = _imageRef$current$get.left,
imageWidth = _imageRef$current$get.width,
imageHeight = _imageRef$current$get.height; // Get the (x,y) touch position relative to image origin at the current scale
var imageCoordX = (touchOriginX - imageTopLeftX - imageWidth / 2) / scale;
var imageCoordY = (touchOriginY - imageTopLeftY - imageHeight / 2) / scale; // Calculate translateX/Y offset at the next scale to zoom to touch position
var newTranslateX = -imageCoordX * pinchDelta + translateX;
var newTranslateY = -imageCoordY * pinchDelta + translateY;
return [newTranslateX, newTranslateY];
};
/**
* Determines if the provided image is within the viewport
*
* @param {ref} imageRef The image dom node to measure against the viewport
*
* @returns {boolean} True if image needs to be resized to fit viewport, otherwise false
*/
var imageIsOutOfBounds = function imageIsOutOfBounds(imageRef) {
var _imageRef$current$get = imageRef.current.getBoundingClientRect(),
topLeftY = _imageRef$current$get.top,
topLeftX = _imageRef$current$get.left,
bottomRightY = _imageRef$current$get.bottom,
bottomRightX = _imageRef$current$get.right;
var _window = window,
windowHeight = _window.innerHeight,
windowWidth = _window.innerWidth;
if (topLeftX > windowWidth * (1 / 2) || topLeftY > windowHeight * (1 / 2) || bottomRightX < windowWidth * (1 / 2) || bottomRightY < windowHeight * (1 / 2)) return true;
return false;
};
/**
* React Hook that returns the current window size
* and report updates from the 'resize' window event
*
* @param {node} ref Dom node to watch for double clicks
* @param {number} [latency=300] The amount of time (in milliseconds) to wait before differentiating a single from a double click
* @param {function} onSingleClick A callback function for single click events
* @param {function} onDoubleClick A callback function for double click events
*/
var useDoubleClick = function useDoubleClick(_ref) {
var ref = _ref.ref,
_ref$latency = _ref.latency,
latency = _ref$latency === void 0 ? 300 : _ref$latency,
_ref$onSingleClick = _ref.onSingleClick,
onSingleClick = _ref$onSingleClick === void 0 ? function () {
return null;
} : _ref$onSingleClick,
_ref$onDoubleClick = _ref.onDoubleClick,
onDoubleClick = _ref$onDoubleClick === void 0 ? function () {
return null;
} : _ref$onDoubleClick;
React.useEffect(function () {
var clickRef = ref.current;
var clickCount = 0;
var handleClick = function handleClick(e) {
clickCount += 1;
setTimeout(function () {
if (clickCount === 1) onSingleClick(e);else if (clickCount === 2) onDoubleClick(e);
clickCount = 0;
}, latency);
}; // Add event listener for click events
clickRef.addEventListener('click', handleClick); // Remove event listener
return function () {
clickRef.removeEventListener('click', handleClick);
};
});
};
/**
* React Hook that returns the current window size
* and report updates from the 'resize' window event
*
* @typedef {WindowSize} WindowSize
* @property {number} width Window width
* @property {number} height Window height
* @returns {WindowSize} An object container the window width and height
*/
var useWindowSize = function useWindowSize() {
var _useState = React.useState({
width: window.innerWidth,
height: window.innerHeight
}),
_useState2 = _slicedToArray(_useState, 2),
windowSize = _useState2[0],
setWindowSize = _useState2[1];
React.useEffect(function () {
var handleResize = function handleResize() {
if (window.innerHeight !== windowSize.height || window.innerWidth !== windowSize.width) {
setWindowSize({
width: window.innerWidth,
height: window.innerHeight
});
}
}; // Add event listener for window resize events
window.addEventListener('resize', handleResize);
window.addEventListener('orientationchange', handleResize); // Remove event listener
return function () {
window.removeEventListener('resize', handleResize);
window.addEventListener('orientationchange', handleResize);
};
});
return windowSize;
};
function _templateObject() {
var data = _taggedTemplateLiteral(["\n width: auto;\n max-width: 100%;\n user-select: none;\n ::selection {\n background: none;\n }\n"]);
_templateObject = function _templateObject() {
return data;
};
return data;
}
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
/**
* Animates pinch-zoom + panning on image using spring physics
*
* @param {string} src The source URL of this image
* @param {string} alt The alt attribute for this image
* @param {boolean} isCurrentImage True if this image is currently shown in pager, otherwise false
* @param {function} setDisableDrag Function that can be called to disable dragging in the pager
* @param {number} pagerHeight Fixed height of the image stage, used to restrict maximum height of images
* @param {boolean} singleClickToZoom Overrides the default behavior of double clicking causing an image zoom to a single click
* @param {boolean} pagerIsDragging Indicates parent ImagePager is in a state of dragging, if true click to zoom is disabled
*
* @see https://github.com/react-spring/react-use-gesture
* @see https://github.com/react-spring/react-spring
*/
var Image = function Image(_ref) {
var _useDoubleClick;
var src = _ref.src,
alt = _ref.alt,
pagerHeight = _ref.pagerHeight,
isCurrentImage = _ref.isCurrentImage,
setDisableDrag = _ref.setDisableDrag,
singleClickToZoom = _ref.singleClickToZoom,
pagerIsDragging = _ref.pagerIsDragging;
var _useState = React.useState(false),
_useState2 = _slicedToArray(_useState, 2),
isPanningImage = _useState2[0],
setIsPanningImage = _useState2[1];
var imageRef = React.useRef();
var defaultImageTransform = function defaultImageTransform() {
return {
scale: 1,
translateX: 0,
translateY: 0,
config: _objectSpread(_objectSpread({}, web.config["default"]), {}, {
precision: 0.01
})
};
};
/**
* Animates scale and translate offsets of Image as they change in gestures
*
* @see https://www.react-spring.io/docs/hooks/use-spring
*/
var _useSpring = web.useSpring(function () {
return _objectSpread(_objectSpread({}, defaultImageTransform()), {}, {
onFrame: function onFrame(f) {
if (f.scale < 1 || !f.pinching) set(defaultImageTransform); // Prevent dragging image out of viewport
if (f.scale > 1 && imageIsOutOfBounds(imageRef)) set(defaultImageTransform());
},
// Enable dragging in ImagePager if image is at the default size
onRest: function onRest(f) {
if (f.scale === 1) setDisableDrag(false);
}
});
}),
_useSpring2 = _slicedToArray(_useSpring, 2),
_useSpring2$ = _useSpring2[0],
scale = _useSpring2$.scale,
translateX = _useSpring2$.translateX,
translateY = _useSpring2$.translateY,
set = _useSpring2[1]; // Reset scale of this image when dragging to new image in ImagePager
React.useEffect(function () {
if (!isCurrentImage) set(defaultImageTransform);
});
/**
* Update Image scale and translate offsets during pinch/pan gestures
*
* @see https://github.com/react-spring/react-use-gesture#usegesture-hook-supporting-multiple-gestures-at-once
*/
var bind = reactUseGesture.useGesture({
onPinch: function onPinch(_ref2) {
var _ref2$movement = _slicedToArray(_ref2.movement, 1),
xMovement = _ref2$movement[0],
_ref2$origin = _slicedToArray(_ref2.origin, 2),
touchOriginX = _ref2$origin[0],
touchOriginY = _ref2$origin[1],
event = _ref2.event,
ctrlKey = _ref2.ctrlKey,
last = _ref2.last,
cancel = _ref2.cancel;
// Prevent ImagePager from registering isDragging
setDisableDrag(true); // Disable click to zoom during pinch
if (xMovement && !isPanningImage) setIsPanningImage(true); // Don't calculate new translate offsets on final frame
if (last) {
cancel();
return;
} // Speed up pinch zoom when using mouse versus touch
var SCALE_FACTOR = ctrlKey ? 1000 : 250;
var pinchScale = scale.value + xMovement / SCALE_FACTOR;
var pinchDelta = pinchScale - scale.value;
var clientX = event.clientX,
clientY = event.clientY; // Calculate the amount of x, y translate offset needed to
// zoom-in to point as image scale grows
var _getTranslateOffsetsF = getTranslateOffsetsFromScale({
imageRef: imageRef,
scale: scale.value,
pinchDelta: pinchDelta,
currentTranslate: [translateX.value, translateY.value],
// Use the [x, y] coords of mouse if a trackpad or ctrl + wheel event
// Otherwise use touch origin
touchOrigin: ctrlKey ? [clientX, clientY] : [touchOriginX, touchOriginY]
}),
_getTranslateOffsetsF2 = _slicedToArray(_getTranslateOffsetsF, 2),
newTranslateX = _getTranslateOffsetsF2[0],
newTranslateY = _getTranslateOffsetsF2[1]; // Restrict the amount of zoom between half and 3x image size
if (pinchScale < 0.5) set({
scale: 0.5,
pinching: true
});else if (pinchScale > 3.0) set({
scale: 3.0,
pinching: true
});else set({
scale: pinchScale,
translateX: newTranslateX,
translateY: newTranslateY,
pinching: true
});
},
onPinchEnd: function onPinchEnd() {
if (scale.value > 1) setDisableDrag(true);else set(defaultImageTransform);
setIsPanningImage(false);
},
onDragEnd: function onDragEnd() {
return setIsPanningImage(false);
},
onDrag: function onDrag(_ref3) {
var _ref3$movement = _slicedToArray(_ref3.movement, 2),
xMovement = _ref3$movement[0],
yMovement = _ref3$movement[1],
pinching = _ref3.pinching,
event = _ref3.event,
cancel = _ref3.cancel,
first = _ref3.first,
_ref3$memo = _ref3.memo,
memo = _ref3$memo === void 0 ? {
initialTranslateX: 0,
initialTranslateY: 0
} : _ref3$memo;
// Disable click to zoom during drag
if (xMovement && yMovement && !isPanningImage) setIsPanningImage(true);
if (event.touches && event.touches.length > 1) return;
if (pinching || scale.value <= 1) return; // Prevent dragging image out of viewport
if (scale.value > 1 && imageIsOutOfBounds(imageRef)) cancel();else {
if (first) {
return {
initialTranslateX: translateX.value,
initialTranslateY: translateY.value
};
} // Translate image from dragging
set({
translateX: memo.initialTranslateX + xMovement,
translateY: memo.initialTranslateY + yMovement
});
return memo;
}
}
},
/**
* useGesture config
* @see https://github.com/react-spring/react-use-gesture#usegesture-config
*/
{
domTarget: imageRef,
event: {
passive: false
}
});
/**
* @see https://github.com/react-spring/react-use-gesture#adding-gestures-to-dom-nodes
*/
React.useEffect(bind, [bind]); // Handle click/tap on image
useDoubleClick((_useDoubleClick = {}, _defineProperty(_useDoubleClick, singleClickToZoom ? 'onSingleClick' : 'onDoubleClick', function (e) {
if (pagerIsDragging || isPanningImage) {
e.stopPropagation();
return;
} // If tapped while already zoomed-in, zoom out to default scale
if (scale.value !== 1) {
set(defaultImageTransform);
return;
} // Zoom-in to origin of click on image
var touchOriginX = e.clientX,
touchOriginY = e.clientY;
var pinchScale = scale.value + 1;
var pinchDelta = pinchScale - scale.value; // Calculate the amount of x, y translate offset needed to
// zoom-in to point as image scale grows
var _getTranslateOffsetsF3 = getTranslateOffsetsFromScale({
imageRef: imageRef,
scale: scale.value,
pinchDelta: pinchDelta,
currentTranslate: [translateX.value, translateY.value],
touchOrigin: [touchOriginX, touchOriginY]
}),
_getTranslateOffsetsF4 = _slicedToArray(_getTranslateOffsetsF3, 2),
newTranslateX = _getTranslateOffsetsF4[0],
newTranslateY = _getTranslateOffsetsF4[1]; // Disable dragging in pager
setDisableDrag(true);
set({
scale: pinchScale,
translateX: newTranslateX,
translateY: newTranslateY,
pinching: true
});
}), _defineProperty(_useDoubleClick, "ref", imageRef), _defineProperty(_useDoubleClick, "latency", singleClickToZoom ? 0 : 200), _useDoubleClick));
return /*#__PURE__*/React__default.createElement(AnimatedImage, {
ref: imageRef,
className: "lightbox-image",
style: _objectSpread({
transform: web.to([scale, translateX, translateY], function (s, x, y) {
return "translate(".concat(x, "px, ").concat(y, "px) scale(").concat(s, ")");
}),
maxHeight: pagerHeight
}, isCurrentImage && {
willChange: 'transform'
}),
src: src,
alt: alt,
draggable: "false",
onDragStart: function onDragStart(e) {
// Disable image ghost dragging in firefox
e.preventDefault();
},
onClick: function onClick(e) {
// Don't close lighbox when clicking image
e.stopPropagation();
e.nativeEvent.stopImmediatePropagation();
}
});
};
var AnimatedImage = styled(web.animated.img)(_templateObject());
function _templateObject4() {
var data = _taggedTemplateLiteral(["\n position: relative;\n touch-action: none;\n user-select: none;\n"]);
_templateObject4 = function _templateObject4() {
return data;
};
return data;
}
function _templateObject3() {
var data = _taggedTemplateLiteral(["\n position: absolute;\n top: 0px;\n left: 0px;\n right: 0px;\n bottom: 0px;\n height: 100%;\n width: 100%;\n will-change: transform;\n touch-action: none;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n"]);
_templateObject3 = function _templateObject3() {
return data;
};
return data;
}
function _templateObject2() {
var data = _taggedTemplateLiteral(["\n width: 100%;\n display: flex;\n justify-content: center;\n"]);
_templateObject2 = function _templateObject2() {
return data;
};
return data;
}
function _templateObject$1() {
var data = _taggedTemplateLiteral(["\n display: flex;\n justify-content: center;\n align-items: center;\n"]);
_templateObject$1 = function _templateObject() {
return data;
};
return data;
}
/**
* Gesture controlled surface that animates prev/next page changes via spring physics.
*
* @param {array} images Array of image objects to be shown in Lightbox
* @param {number} currentIndex Index of image in images array that is currently shown
* @param {function} onPrev True if this image is currently shown in pager, otherwise false
* @param {function} onNext Function that can be called to disable dragging in the pager
* @param {function} onClose Function that closes the Lightbox
* @param {function} renderImageOverlay A React component that renders inside the image stage, useful for making overlays over the image
* @param {boolean} singleClickToZoom Overrides the default behavior of double clicking causing an image zoom to a single click
*
* @see https://github.com/react-spring/react-use-gesture
* @see https://github.com/react-spring/react-spring
*/
var ImagePager = function ImagePager(_ref) {
var images = _ref.images,
currentIndex = _ref.currentIndex,
onPrev = _ref.onPrev,
onNext = _ref.onNext,
onClose = _ref.onClose,
renderImageOverlay = _ref.renderImageOverlay,
singleClickToZoom = _ref.singleClickToZoom;
var firstRender = React.useRef(true);
var imageStageRef = React.useRef(_toConsumableArray(Array(images.length)).map(function () {
return React__default.createRef();
}));
var _useWindowSize = useWindowSize(),
windowHeight = _useWindowSize.height,
pageWidth = _useWindowSize.width;
var _useState = React.useState(false),
_useState2 = _slicedToArray(_useState, 2),
disableDrag = _useState2[0],
setDisableDrag = _useState2[1];
var _useState3 = React.useState('100%'),
_useState4 = _slicedToArray(_useState3, 2),
pagerHeight = _useState4[0],
setPagerHeight = _useState4[1];
var _useState5 = React.useState(false),
_useState6 = _slicedToArray(_useState5, 2),
isDragging = _useState6[0],
setIsDragging = _useState6[1]; // Generate page positions based on current index
var getPagePositions = function getPagePositions(i) {
var down = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var xDelta = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
var x = (i - currentIndex) * pageWidth + (down ? xDelta : 0);
if (i < currentIndex - 1 || i > currentIndex + 1) return {
x: x,
display: 'none'
};
return {
x: x,
display: 'flex'
};
};
/**
* Animates translateX of all images at the same time
*
* @see https://www.react-spring.io/docs/hooks/use-springs
*/
var _useSprings = web.useSprings(images.length, getPagePositions),
_useSprings2 = _slicedToArray(_useSprings, 2),
props = _useSprings2[0],
set = _useSprings2[1]; // Determine the absolute height of the image pager
React.useEffect(function () {
var currPagerHeight = imageStageRef.current[currentIndex].current.clientHeight - 50;
if (pagerHeight !== currPagerHeight) setPagerHeight(currPagerHeight);
}, [currentIndex, pagerHeight, windowHeight]); // Animate page change if currentIndex changes
React.useEffect(function () {
// No need to set page position for initial render
if (firstRender.current) {
firstRender.current = false;
return;
} // Update page positions after prev/next page state change
set(getPagePositions);
});
/**
* Update each Image's visibility and translateX offset during dragging
*
* @see https://github.com/react-spring/react-use-gesture
*/
var bind = reactUseGesture.useGesture({
onWheel: function onWheel(_ref2) {
var distance = _ref2.distance,
velocity = _ref2.velocity,
_ref2$direction = _slicedToArray(_ref2.direction, 2),
xDir = _ref2$direction[0],
yDir = _ref2$direction[1],
ctrlKey = _ref2.ctrlKey;
// Disable drag if Image has been zoomed in to allow for panning
if (ctrlKey || disableDrag || velocity === 0) return;
var draggedFarEnough = distance > pageWidth / 3;
var draggedFastEnough = velocity > 1.5 && distance <= pageWidth / 3; // Handle next/prev image from valid drag
if (draggedFarEnough || draggedFastEnough) {
var goToIndex = xDir + yDir > 0 ? -1 : 1;
if (goToIndex > 0) onNext();else if (goToIndex < 0) onPrev();
}
},
onWheelEnd: function onWheelEnd() {
set(function (i) {
return getPagePositions(i, false, 0);
});
setIsDragging(false);
},
onDrag: function onDrag(_ref3) {
var down = _ref3.down,
_ref3$movement = _slicedToArray(_ref3.movement, 1),
xMovement = _ref3$movement[0],
_ref3$direction = _slicedToArray(_ref3.direction, 1),
xDir = _ref3$direction[0],
velocity = _ref3.velocity,
distance = _ref3.distance,
cancel = _ref3.cancel,
touches = _ref3.touches;
// Disable drag if Image has been zoomed in to allow for panning
if (disableDrag || xMovement === 0) return;
if (!isDragging) setIsDragging(true);
var isHorizontalDrag = Math.abs(xDir) > 0.7;
var draggedFarEnough = down && isHorizontalDrag && distance > pageWidth / 3.5;
var draggedFastEnough = down && isHorizontalDrag && velocity > 2; // Handle next/prev image from valid drag
if (draggedFarEnough || draggedFastEnough) {
var goToIndex = xDir > 0 ? -1 : 1; // Cancel gesture animation
cancel();
if (goToIndex > 0) onNext();else if (goToIndex < 0) onPrev();
} // Don't move pager during two+ finger touch events, i.e. pinch-zoom
if (touches > 1) return; // Update page x-coordinates for single finger/mouse gestures
set(function (i) {
return getPagePositions(i, down, xMovement);
});
},
onDragEnd: function onDragEnd() {
return setIsDragging(false);
}
},
/**
* useGesture config
* @see https://github.com/react-spring/react-use-gesture#usegesture-config
*/
{
domTarget: imageStageRef.current[currentIndex],
event: {
passive: true,
capture: false
}
});
/**
* @see https://github.com/react-spring/react-use-gesture#adding-gestures-to-dom-nodes
*/
React.useEffect(bind, [bind, currentIndex]);
return props.map(function (_ref4, i) {
var x = _ref4.x,
display = _ref4.display;
return /*#__PURE__*/React__default.createElement(AnimatedImagePager, {
role: "presentation",
ref: imageStageRef.current[i],
key: i,
className: "lightbox-image-pager",
style: {
display: display,
transform: x.to(function (xInterp) {
return "translateX(".concat(xInterp, "px)");
})
},
onClick: function onClick() {
return Math.abs(x.value) < 1 && !disableDrag && onClose();
}
}, /*#__PURE__*/React__default.createElement(PagerContentWrapper, null, /*#__PURE__*/React__default.createElement(PagerInnerContentWrapper, null, /*#__PURE__*/React__default.createElement(ImageContainer, {
onClick: function onClick(e) {
e.stopPropagation();
e.nativeEvent.stopImmediatePropagation();
}
}, /*#__PURE__*/React__default.createElement(Image, {
setDisableDrag: setDisableDrag,
src: images[i].src,
alt: images[i].alt,
pagerHeight: pagerHeight,
isCurrentImage: i === currentIndex,
pagerIsDragging: isDragging,
singleClickToZoom: singleClickToZoom
}), renderImageOverlay()))));
});
};
var PagerInnerContentWrapper = styled.div(_templateObject$1());
var PagerContentWrapper = styled.div(_templateObject2());
var AnimatedImagePager = styled(web.animated.div)(_templateObject3());
var ImageContainer = styled.div(_templateObject4());
function _templateObject$2() {
var data = _taggedTemplateLiteral(["\n flex-grow: 1;\n position: relative;\n height: 100%;\n width: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n"]);
_templateObject$2 = function _templateObject() {
return data;
};
return data;
}
/**
* Containing element for ImagePager and prev/next button controls
*
* @param {array} images Array of image objects to be shown in Lightbox
* @param {number} currentIndex Index of image in images array that is currently shown
* @param {function} onPrev True if this image is currently shown in pager, otherwise false
* @param {function} onNext Function that can be called to disable dragging in the pager
* @param {function} renderPrevButton A React component that is used for previous button in image pager
* @param {function} renderNextButton A React component that is used for next button in image pager
* @param {function} renderImageOverlay A React component that renders inside the image stage, useful for making overlays over the image
* @param {boolean} singleClickToZoom Overrides the default behavior of double clicking causing an image zoom to a single click
*/
var ImageStage = function ImageStage(_ref) {
var images = _ref.images,
currentIndex = _ref.currentIndex,
onPrev = _ref.onPrev,
onNext = _ref.onNext,
onClose = _ref.onClose,
renderPrevButton = _ref.renderPrevButton,
renderNextButton = _ref.renderNextButton,
renderImageOverlay = _ref.renderImageOverlay,
singleClickToZoom = _ref.singleClickToZoom;
// Extra sanity check that the next/prev image exists before moving to it
var canPrev = currentIndex > 0;
var canNext = currentIndex + 1 < images.length;
return /*#__PURE__*/React__default.createElement(ImageStageContainer, {
className: "lightbox-image-stage"
}, renderPrevButton({
canPrev: canPrev
}), /*#__PURE__*/React__default.createElement(ImagePager, {
images: images,
currentIndex: currentIndex,
onClose: onClose,
onNext: onNext,
onPrev: onPrev,
renderImageOverlay: renderImageOverlay,
singleClickToZoom: singleClickToZoom
}), renderNextButton({
canNext: canNext
}));
};
var ImageStageContainer = styled.div(_templateObject$2());
function _templateObject$3() {
var data = _taggedTemplateLiteral(["\n display: flex;\n flex-direction: column;\n position: fixed;\n z-index: 400;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n"]);
_templateObject$3 = function _templateObject() {
return data;
};
return data;
}
function ownKeys$1(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread$1(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$1(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$1(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
/**
* Animates the lightbox as it opens/closes
*
* @param {ReactNode} children All child components of Lightbox
* @param {boolean} isOpen Flag that dictates if the lightbox is open or closed
* @param {string} className Classes are applied to the root lightbox component
* @param {object} style Inline styles are applied to the root lightbox component
* @param {object} pageTransitionConfig React-Spring useTransition config for page open/close animation
*
* @see https://www.react-spring.io/docs/hooks/use-transition
*/
var PageContainer = function PageContainer(_ref) {
var children = _ref.children,
isOpen = _ref.isOpen,
className = _ref.className,
style = _ref.style,
pageTransitionConfig = _ref.pageTransitionConfig;
var defaultTransition = {
from: {
transform: 'scale(0.75)',
opacity: 0
},
enter: {
transform: 'scale(1)',
opacity: 1
},
leave: {
transform: 'scale(0.75)',
opacity: 0
},
config: _objectSpread$1(_objectSpread$1({}, web.config["default"]), {}, {
mass: 1,
tension: 320,
friction: 32
})
};
var transitions = web.useTransition(isOpen, null, _objectSpread$1(_objectSpread$1({}, defaultTransition), pageTransitionConfig));
return transitions.map(function (_ref2) {
var item = _ref2.item,
key = _ref2.key,
props = _ref2.props;
return item && /*#__PURE__*/React__default.createElement(AnimatedPageContainer, {
key: key,
className: "lightbox-container".concat(className ? " ".concat(className) : ''),
style: _objectSpread$1(_objectSpread$1({}, props), style)
}, children);
});
};
var AnimatedPageContainer = styled(web.animated.div)(_templateObject$3());
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function () { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
/**
* Creates a SSR + next.js friendly React Portal inside <body />
*
* Child components are rendered on the client side only
*
* @param {array|node} children Child components will be rendered to the portal
* @see https://reactjs.org/docs/portals.html
*/
var CreatePortal = /*#__PURE__*/function (_React$Component) {
_inherits(CreatePortal, _React$Component);
var _super = _createSuper(CreatePortal);
function CreatePortal() {
var _this;
_classCallCheck(this, CreatePortal);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = _super.call.apply(_super, [this].concat(args));
_defineProperty(_assertThisInitialized(_this), "preventWheel", function (e) {
return e.preventDefault();
});
return _this;
}
_createClass(CreatePortal, [{
key: "componentDidMount",
// Only executes on the client-side
value: function componentDidMount() {
// Get the document body
this.body = document.body; // Create a container <div /> for React Portal
this.portalContainer = document.createElement('div');
this.portalContainer.setAttribute('class', 'lightbox-portal'); // Append the container to the document body
this.body.appendChild(this.portalContainer); // Force a re-render as we're on the client side now
// children prop will render to portalContainer
this.forceUpdate(); // Add event listener to prevent trackpad/ctrl+mousewheel zooming of lightbox
// Zooming is handled specifically within /ImageStage/components/Image
this.portalContainer.addEventListener('wheel', this.preventWheel);
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
// Remove wheel event listener
this.portalContainer.removeEventListener('wheel', this.preventWheel); // Cleanup Portal from DOM
this.body.removeChild(this.portalContainer);
}
}, {
key: "render",
value: function render() {
// Return null during SSR
if (this.portalContainer === undefined) return null;
var children = this.props.children;
return ReactDOM.createPortal(children, this.portalContainer);
}
}]);
return CreatePortal;
}(React__default.Component);
/**
* Gesture controlled lightbox that interpolates animations with spring physics.
*
* @param {boolean} isOpen Flag that dictates if the lightbox is open or closed
* @param {function} onClose Function that closes the Lightbox
* @param {function} onPrev Function that changes currentIndex to previous image in images
* @param {function} onNext Function that changes currentIndex to next image in images
* @param {number} currentIndex Index of image in images array that is currently shown
* @param {function} renderHeader A React component that renders above the image pager
* @param {function} renderFooter A React component that renders below the image pager
* @param {function} renderImageOverlay A React component that renders inside the image stage, useful for making overlays over the image
* @param {function} renderPrevButton A React component that is used for previous button in image pager
* @param {function} renderNextButton A React component that is used for next button in image pager
* @param {array} images Array of image objects to be shown in Lightbox
* @param {string} className Classes are applied to the root lightbox component
* @param {object} style Inline styles are applied to the root lightbox component
* @param {object} pageTransitionConfig React-Spring useTransition config for page open/close animation
* @param {boolean} singleClickToZoom Overrides the default behavior of double clicking causing an image zoom to a single click
*
* @see https://github.com/react-spring/react-use-gesture
* @see https://github.com/react-spring/react-spring
*/
var Lightbox = function Lightbox(_ref) {
var isOpen = _ref.isOpen,
onClose = _ref.onClose,
images = _ref.images,
currentIndex = _ref.currentIndex,
onPrev = _ref.onPrev,
onNext = _ref.onNext,
renderHeader = _ref.renderHeader,
renderFooter = _ref.renderFooter,
renderPrevButton = _ref.renderPrevButton,
renderNextButton = _ref.renderNextButton,
renderImageOverlay = _ref.renderImageOverlay,
className = _ref.className,
singleClickToZoom = _ref.singleClickToZoom,
style = _ref.style,
pageTransitionConfig = _ref.pageTransitionConfig;
// Handle event listeners for keyboard
React.useEffect(function () {
/**
* Prevent keyboard from controlling background page
* when lightbox is open
*/
var preventBackgroundScroll = function preventBackgroundScroll(e) {
var keysToIgnore = ['ArrowUp', 'ArrowDown', 'End', 'Home', 'PageUp', 'PageDown'];
if (isOpen && keysToIgnore.includes(e.key)) e.preventDefault();
};
/**
* Navigate images with arrow keys, close on Esc key
*/
var handleKeyboardInput = function handleKeyboardInput(e) {
if (isOpen) {
switch (e.key) {
case 'ArrowLeft':
onPrev();
break;
case 'ArrowRight':
onNext();
break;
case 'Escape':
onClose();
break;
default:
e.preventDefault();
break;
}
}
};
document.addEventListener('keyup', handleKeyboardInput);
document.addEventListener('keydown', preventBackgroundScroll);
return function () {
document.removeEventListener('keyup', handleKeyboardInput);
document.removeEventListener('keydown', preventBackgroundScroll);
};
});
return /*#__PURE__*/React__default.createElement(CreatePortal, null, /*#__PURE__*/React__default.createElement(PageContainer, {
isOpen: isOpen,
className: className,
style: style,
pageTransitionConfig: pageTransitionConfig
}, renderHeader(), /*#__PURE__*/React__default.createElement(ImageStage, {
images: images,
onClose: onClose,
currentIndex: currentIndex,
onPrev: onPrev,
onNext: onNext,
renderPrevButton: renderPrevButton,
renderNextButton: renderNextButton,
renderImageOverlay: renderImageOverlay,
singleClickToZoom: singleClickToZoom
}), renderFooter()));
};
Lightbox.defaultProps = {
pageTransitionConfig: null,
className: null,
style: null,
renderHeader: function renderHeader() {
return null;
},
renderFooter: function renderFooter() {
return null;
},
renderPrevButton: function renderPrevButton() {
return null;
},
renderNextButton: function renderNextButton() {
return null;
},
renderImageOverlay: function renderImageOverlay() {
return null;
},
singleClickToZoom: false
};
module.exports = Lightbox;
"use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}var t=require("react"),n=e(t),r=e(require("styled-components")),i=e(require("@babel/runtime/helpers/slicedToArray")),a=e(require("@babel/runtime/helpers/toConsumableArray")),o=require("@react-spring/web"),c=require("react-use-gesture"),l=e(require("@babel/runtime/helpers/defineProperty")),u=e(require("@babel/runtime/helpers/classCallCheck")),s=e(require("@babel/runtime/helpers/createClass")),f=e(require("@babel/runtime/helpers/assertThisInitialized")),g=e(require("@babel/runtime/helpers/inherits")),p=e(require("@babel/runtime/helpers/possibleConstructorReturn")),d=e(require("@babel/runtime/helpers/getPrototypeOf")),m=e(require("react-dom")),v=function(e){var t=e.imageRef,n=e.scale,r=e.pinchDelta,a=i(e.touchOrigin,2),o=a[0],c=a[1],l=i(e.currentTranslate,2),u=l[0],s=l[1],f=t.current.getBoundingClientRect(),g=f.top;return[-((o-f.left-f.width/2)/n)*r+u,-((c-g-f.height/2)/n)*r+s]},h=function(e){var t=e.current.getBoundingClientRect(),n=t.top,r=t.left,i=t.bottom,a=t.right,o=window,c=o.innerHeight,l=o.innerWidth;return r>.5*l||n>.5*c||a<.5*l||i<.5*c};function y(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function b(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?y(Object(n),!0).forEach((function(t){l(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):y(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}var w=function(e){var r,a=e.src,u=e.alt,s=e.pagerHeight,f=e.isCurrentImage,g=e.setDisableDrag,p=e.singleClickToZoom,d=e.pagerIsDragging,m=t.useState(!1),y=i(m,2),w=y[0],P=y[1],O=t.useRef(),x=function(){return{scale:1,translateX:0,translateY:0,config:b(b({},o.config.default),{},{precision:.01})}},E=o.useSpring((function(){return b(b({},x()),{},{onFrame:function(e){(e.scale<1||!e.pinching)&&N(x),e.scale>1&&h(O)&&N(x())},onRest:function(e){1===e.scale&&g(!1)}})})),k=i(E,2),I=k[0],D=I.scale,j=I.translateX,T=I.translateY,N=k[1];t.useEffect((function(){f||N(x)}));var R=c.useGesture({onPinch:function(e){var t=i(e.movement,1)[0],n=i(e.origin,2),r=n[0],a=n[1],o=e.event,c=e.ctrlKey,l=e.last,u=e.cancel;if(g(!0),t&&!w&&P(!0),l)u();else{var s=c?1e3:250,f=D.value+t/s,p=f-D.value,d=o.clientX,m=o.clientY,h=v({imageRef:O,scale:D.value,pinchDelta:p,currentTranslate:[j.value,T.value],touchOrigin:c?[d,m]:[r,a]}),y=i(h,2),b=y[0],C=y[1];N(f<.5?{scale:.5,pinching:!0}:f>3?{scale:3,pinching:!0}:{scale:f,translateX:b,translateY:C,pinching:!0})}},onPinchEnd:function(){D.value>1?g(!0):N(x),P(!1)},onDragEnd:function(){return P(!1)},onDrag:function(e){var t=i(e.movement,2),n=t[0],r=t[1],a=e.pinching,o=e.event,c=e.cancel,l=e.first,u=e.memo,s=void 0===u?{initialTranslateX:0,initialTranslateY:0}:u;if(n&&r&&!w&&P(!0),!(o.touches&&o.touches.length>1||a||D.value<=1))return D.value>1&&h(O)?void c():l?{initialTranslateX:j.value,initialTranslateY:T.value}:(N({translateX:s.initialTranslateX+n,translateY:s.initialTranslateY+r}),s)}},{domTarget:O,event:{passive:!1}});return t.useEffect(R,[R]),function(e){var n=e.ref,r=e.latency,i=void 0===r?300:r,a=e.onSingleClick,o=void 0===a?function(){return null}:a,c=e.onDoubleClick,l=void 0===c?function(){return null}:c;t.useEffect((function(){var e=n.current,t=0,r=function(e){t+=1,setTimeout((function(){1===t?o(e):2===t&&l(e),t=0}),i)};return e.addEventListener("click",r),function(){e.removeEventListener("click",r)}}))}((l(r={},p?"onSingleClick":"onDoubleClick",(function(e){if(d||w)e.stopPropagation();else if(1===D.value){var t=e.clientX,n=e.clientY,r=D.value+1,a=r-D.value,o=v({imageRef:O,scale:D.value,pinchDelta:a,currentTranslate:[j.value,T.value],touchOrigin:[t,n]}),c=i(o,2),l=c[0],u=c[1];g(!0),N({scale:r,translateX:l,translateY:u,pinching:!0})}else N(x)})),l(r,"ref",O),l(r,"latency",p?0:200),r)),n.createElement(C,{ref:O,className:"lightbox-image",style:b({transform:o.to([D,j,T],(function(e,t,n){return"translate(".concat(t,"px, ").concat(n,"px) scale(").concat(e,")")})),maxHeight:s},f&&{willChange:"transform"}),src:a,alt:u,draggable:"false",onDragStart:function(e){e.preventDefault()},onClick:function(e){e.stopPropagation(),e.nativeEvent.stopImmediatePropagation()}})},C=r(o.animated.img).withConfig({displayName:"Image__AnimatedImage",componentId:"sc-1k35vrn-0"})(["width:auto;max-width:100%;user-select:none;::selection{background:none;}"]),P=function(e){var r=e.images,l=e.currentIndex,u=e.onPrev,s=e.onNext,f=e.onClose,g=e.renderImageOverlay,p=e.singleClickToZoom,d=t.useRef(!0),m=t.useRef(a(Array(r.length)).map((function(){return n.createRef()}))),v=function(){var e=t.useState({width:window.innerWidth,height:window.innerHeight}),n=i(e,2),r=n[0],a=n[1];return t.useEffect((function(){var e=function(){window.innerHeight===r.height&&window.innerWidth===r.width||a({width:window.innerWidth,height:window.innerHeight})};return window.addEventListener("resize",e),window.addEventListener("orientationchange",e),function(){window.removeEventListener("resize",e),window.addEventListener("orientationchange",e)}})),r}(),h=v.height,y=v.width,b=t.useState(!1),C=i(b,2),P=C[0],I=C[1],D=t.useState("100%"),j=i(D,2),T=j[0],N=j[1],R=t.useState(!1),S=i(R,2),q=S[0],_=S[1],L=function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,r=(e-l)*y+(t?n:0);return e<l-1||e>l+1?{x:r,display:"none"}:{x:r,display:"flex"}},A=o.useSprings(r.length,L),W=i(A,2),H=W[0],X=W[1];t.useEffect((function(){var e=m.current[l].current.clientHeight-50;T!==e&&N(e)}),[l,T,h]),t.useEffect((function(){d.current?d.current=!1:X(L)}));var B=c.useGesture({onWheel:function(e){var t=e.distance,n=e.velocity,r=i(e.direction,2),a=r[0],o=r[1];if(!e.ctrlKey&&!P&&0!==n&&(t>y/3||n>1.5&&t<=y/3)){var c=a+o>0?-1:1;c>0?s():c<0&&u()}},onWheelEnd:function(){X((function(e){return L(e,!1,0)})),_(!1)},onDrag:function(e){var t=e.down,n=i(e.movement,1)[0],r=i(e.direction,1)[0],a=e.velocity,o=e.distance,c=e.cancel,l=e.touches;if(!P&&0!==n){q||_(!0);var f=Math.abs(r)>.7;if(t&&f&&o>y/3.5||t&&f&&a>2){var g=r>0?-1:1;c(),g>0?s():g<0&&u()}l>1||X((function(e){return L(e,t,n)}))}},onDragEnd:function(){return _(!1)}},{domTarget:m.current[l],event:{passive:!0,capture:!1}});return t.useEffect(B,[B,l]),H.map((function(e,t){var i=e.x,a=e.display;return n.createElement(E,{role:"presentation",ref:m.current[t],key:t,className:"lightbox-image-pager",style:{display:a,transform:i.to((function(e){return"translateX(".concat(e,"px)")}))},onClick:function(){return Math.abs(i.value)<1&&!P&&f()}},n.createElement(x,null,n.createElement(O,null,n.createElement(k,{onClick:function(e){e.stopPropagation(),e.nativeEvent.stopImmediatePropagation()}},n.createElement(w,{setDisableDrag:I,src:r[t].src,alt:r[t].alt,pagerHeight:T,isCurrentImage:t===l,pagerIsDragging:q,singleClickToZoom:p}),g()))))}))},O=r.div.withConfig({displayName:"ImagePager__PagerInnerContentWrapper",componentId:"a18fy4-0"})(["display:flex;justify-content:center;align-items:center;"]),x=r.div.withConfig({displayName:"ImagePager__PagerContentWrapper",componentId:"a18fy4-1"})(["width:100%;display:flex;justify-content:center;"]),E=r(o.animated.div).withConfig({displayName:"ImagePager__AnimatedImagePager",componentId:"a18fy4-2"})(["position:absolute;top:0px;left:0px;right:0px;bottom:0px;height:100%;width:100%;will-change:transform;touch-action:none;display:flex;flex-direction:column;justify-content:center;align-items:center;"]),k=r.div.withConfig({displayName:"ImagePager__ImageContainer",componentId:"a18fy4-3"})(["position:relative;touch-action:none;user-select:none;"]),I=function(e){var t=e.images,r=e.currentIndex,i=e.onPrev,a=e.onNext,o=e.onClose,c=e.renderPrevButton,l=e.renderNextButton,u=e.renderImageOverlay,s=e.singleClickToZoom,f=r>0,g=r+1<t.length;return n.createElement(D,{className:"lightbox-image-stage"},c({canPrev:f}),n.createElement(P,{images:t,currentIndex:r,onClose:o,onNext:a,onPrev:i,renderImageOverlay:u,singleClickToZoom:s}),l({canNext:g}))},D=r.div.withConfig({displayName:"ImageStage__ImageStageContainer",componentId:"m6g63l-0"})(["flex-grow:1;position:relative;height:100%;width:100%;display:flex;justify-content:center;align-items:center;"]);function j(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function T(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?j(Object(n),!0).forEach((function(t){l(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):j(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}var N=function(e){var t=e.children,r=e.isOpen,i=e.className,a=e.style,c=e.pageTransitionConfig,l={from:{transform:"scale(0.75)",opacity:0},enter:{transform:"scale(1)",opacity:1},leave:{transform:"scale(0.75)",opacity:0},config:T(T({},o.config.default),{},{mass:1,tension:320,friction:32})};return o.useTransition(r,null,T(T({},l),c)).map((function(e){var r=e.item,o=e.key,c=e.props;return r&&n.createElement(R,{key:o,className:"lightbox-container".concat(i?" ".concat(i):""),style:T(T({},c),a)},t)}))},R=r(o.animated.div).withConfig({displayName:"PageContainer__AnimatedPageContainer",componentId:"sc-19m9s01-0"})(["display:flex;flex-direction:column;position:fixed;z-index:400;top:0;bottom:0;left:0;right:0;"]);function S(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,r=d(e);if(t){var i=d(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return p(this,n)}}var q=function(e){g(n,e);var t=S(n);function n(){var e;u(this,n);for(var r=arguments.length,i=new Array(r),a=0;a<r;a++)i[a]=arguments[a];return e=t.call.apply(t,[this].concat(i)),l(f(e),"preventWheel",(function(e){return e.preventDefault()})),e}return s(n,[{key:"componentDidMount",value:function(){this.body=document.body,this.portalContainer=document.createElement("div"),this.portalContainer.setAttribute("class","lightbox-portal"),this.body.appendChild(this.portalContainer),this.forceUpdate(),this.portalContainer.addEventListener("wheel",this.preventWheel)}},{key:"componentWillUnmount",value:function(){this.portalContainer.removeEventListener("wheel",this.preventWheel),this.body.removeChild(this.portalContainer)}},{key:"render",value:function(){if(void 0===this.portalContainer)return null;var e=this.props.children;return m.createPortal(e,this.portalContainer)}}]),n}(n.Component),_=function(e){var r=e.isOpen,i=e.onClose,a=e.images,o=e.currentIndex,c=e.onPrev,l=e.onNext,u=e.renderHeader,s=e.renderFooter,f=e.renderPrevButton,g=e.renderNextButton,p=e.renderImageOverlay,d=e.className,m=e.singleClickToZoom,v=e.style,h=e.pageTransitionConfig;return t.useEffect((function(){var e=function(e){r&&["ArrowUp","ArrowDown","End","Home","PageUp","PageDown"].includes(e.key)&&e.preventDefault()},t=function(e){if(r)switch(e.key){case"ArrowLeft":c();break;case"ArrowRight":l();break;case"Escape":i();break;default:e.preventDefault()}};return document.addEventListener("keyup",t),document.addEventListener("keydown",e),function(){document.removeEventListener("keyup",t),document.removeEventListener("keydown",e)}})),n.createElement(q,null,n.createElement(N,{isOpen:r,className:d,style:v,pageTransitionConfig:h},u(),n.createElement(I,{images:a,onClose:i,currentIndex:o,onPrev:c,onNext:l,renderPrevButton:f,renderNextButton:g,renderImageOverlay:p,singleClickToZoom:m}),s()))};_.defaultProps={pageTransitionConfig:null,className:null,style:null,renderHeader:function(){return null},renderFooter:function(){return null},renderPrevButton:function(){return null},renderNextButton:function(){return null},renderImageOverlay:function(){return null},singleClickToZoom:!1},module.exports=_;
//# sourceMappingURL=index.cjs.js.map

@@ -1,999 +0,2 @@

import React, { useEffect, useState, useRef } from 'react';
import _taggedTemplateLiteral from '@babel/runtime/helpers/taggedTemplateLiteral';
import styled from 'styled-components';
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
import { useSpring, config, to, animated, useSprings, useTransition } from '@react-spring/web';
import { useGesture } from 'react-use-gesture';
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import _classCallCheck from '@babel/runtime/helpers/classCallCheck';
import _createClass from '@babel/runtime/helpers/createClass';
import _assertThisInitialized from '@babel/runtime/helpers/assertThisInitialized';
import _inherits from '@babel/runtime/helpers/inherits';
import _possibleConstructorReturn from '@babel/runtime/helpers/possibleConstructorReturn';
import _getPrototypeOf from '@babel/runtime/helpers/getPrototypeOf';
import ReactDOM from 'react-dom';
/**
* Calculates the the translate(x,y) coordinates needed to zoom-in
* to a point in an image.
*
* @param {ref} imageRef The image dom node used as a reference to calculate translate offsets
* @param {number} scale The current transform scale of image
* @param {number} pinchDelta The amount of change in the new transform scale
* @param {array} touchOrigin The [x,y] coordinates of the zoom origin
* @param {array} currentTranslate The current [x,y] translate values of image
*
* @returns {array} The next [x,y] translate values to apply to image
*/
var getTranslateOffsetsFromScale = function getTranslateOffsetsFromScale(_ref) {
var imageRef = _ref.imageRef,
scale = _ref.scale,
pinchDelta = _ref.pinchDelta,
_ref$touchOrigin = _slicedToArray(_ref.touchOrigin, 2),
touchOriginX = _ref$touchOrigin[0],
touchOriginY = _ref$touchOrigin[1],
_ref$currentTranslate = _slicedToArray(_ref.currentTranslate, 2),
translateX = _ref$currentTranslate[0],
translateY = _ref$currentTranslate[1];
var _imageRef$current$get = imageRef.current.getBoundingClientRect(),
imageTopLeftY = _imageRef$current$get.top,
imageTopLeftX = _imageRef$current$get.left,
imageWidth = _imageRef$current$get.width,
imageHeight = _imageRef$current$get.height; // Get the (x,y) touch position relative to image origin at the current scale
var imageCoordX = (touchOriginX - imageTopLeftX - imageWidth / 2) / scale;
var imageCoordY = (touchOriginY - imageTopLeftY - imageHeight / 2) / scale; // Calculate translateX/Y offset at the next scale to zoom to touch position
var newTranslateX = -imageCoordX * pinchDelta + translateX;
var newTranslateY = -imageCoordY * pinchDelta + translateY;
return [newTranslateX, newTranslateY];
};
/**
* Determines if the provided image is within the viewport
*
* @param {ref} imageRef The image dom node to measure against the viewport
*
* @returns {boolean} True if image needs to be resized to fit viewport, otherwise false
*/
var imageIsOutOfBounds = function imageIsOutOfBounds(imageRef) {
var _imageRef$current$get = imageRef.current.getBoundingClientRect(),
topLeftY = _imageRef$current$get.top,
topLeftX = _imageRef$current$get.left,
bottomRightY = _imageRef$current$get.bottom,
bottomRightX = _imageRef$current$get.right;
var _window = window,
windowHeight = _window.innerHeight,
windowWidth = _window.innerWidth;
if (topLeftX > windowWidth * (1 / 2) || topLeftY > windowHeight * (1 / 2) || bottomRightX < windowWidth * (1 / 2) || bottomRightY < windowHeight * (1 / 2)) return true;
return false;
};
/**
* React Hook that returns the current window size
* and report updates from the 'resize' window event
*
* @param {node} ref Dom node to watch for double clicks
* @param {number} [latency=300] The amount of time (in milliseconds) to wait before differentiating a single from a double click
* @param {function} onSingleClick A callback function for single click events
* @param {function} onDoubleClick A callback function for double click events
*/
var useDoubleClick = function useDoubleClick(_ref) {
var ref = _ref.ref,
_ref$latency = _ref.latency,
latency = _ref$latency === void 0 ? 300 : _ref$latency,
_ref$onSingleClick = _ref.onSingleClick,
onSingleClick = _ref$onSingleClick === void 0 ? function () {
return null;
} : _ref$onSingleClick,
_ref$onDoubleClick = _ref.onDoubleClick,
onDoubleClick = _ref$onDoubleClick === void 0 ? function () {
return null;
} : _ref$onDoubleClick;
useEffect(function () {
var clickRef = ref.current;
var clickCount = 0;
var handleClick = function handleClick(e) {
clickCount += 1;
setTimeout(function () {
if (clickCount === 1) onSingleClick(e);else if (clickCount === 2) onDoubleClick(e);
clickCount = 0;
}, latency);
}; // Add event listener for click events
clickRef.addEventListener('click', handleClick); // Remove event listener
return function () {
clickRef.removeEventListener('click', handleClick);
};
});
};
/**
* React Hook that returns the current window size
* and report updates from the 'resize' window event
*
* @typedef {WindowSize} WindowSize
* @property {number} width Window width
* @property {number} height Window height
* @returns {WindowSize} An object container the window width and height
*/
var useWindowSize = function useWindowSize() {
var _useState = useState({
width: window.innerWidth,
height: window.innerHeight
}),
_useState2 = _slicedToArray(_useState, 2),
windowSize = _useState2[0],
setWindowSize = _useState2[1];
useEffect(function () {
var handleResize = function handleResize() {
if (window.innerHeight !== windowSize.height || window.innerWidth !== windowSize.width) {
setWindowSize({
width: window.innerWidth,
height: window.innerHeight
});
}
}; // Add event listener for window resize events
window.addEventListener('resize', handleResize);
window.addEventListener('orientationchange', handleResize); // Remove event listener
return function () {
window.removeEventListener('resize', handleResize);
window.addEventListener('orientationchange', handleResize);
};
});
return windowSize;
};
function _templateObject() {
var data = _taggedTemplateLiteral(["\n width: auto;\n max-width: 100%;\n user-select: none;\n ::selection {\n background: none;\n }\n"]);
_templateObject = function _templateObject() {
return data;
};
return data;
}
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
/**
* Animates pinch-zoom + panning on image using spring physics
*
* @param {string} src The source URL of this image
* @param {string} alt The alt attribute for this image
* @param {boolean} isCurrentImage True if this image is currently shown in pager, otherwise false
* @param {function} setDisableDrag Function that can be called to disable dragging in the pager
* @param {number} pagerHeight Fixed height of the image stage, used to restrict maximum height of images
* @param {boolean} singleClickToZoom Overrides the default behavior of double clicking causing an image zoom to a single click
* @param {boolean} pagerIsDragging Indicates parent ImagePager is in a state of dragging, if true click to zoom is disabled
*
* @see https://github.com/react-spring/react-use-gesture
* @see https://github.com/react-spring/react-spring
*/
var Image = function Image(_ref) {
var _useDoubleClick;
var src = _ref.src,
alt = _ref.alt,
pagerHeight = _ref.pagerHeight,
isCurrentImage = _ref.isCurrentImage,
setDisableDrag = _ref.setDisableDrag,
singleClickToZoom = _ref.singleClickToZoom,
pagerIsDragging = _ref.pagerIsDragging;
var _useState = useState(false),
_useState2 = _slicedToArray(_useState, 2),
isPanningImage = _useState2[0],
setIsPanningImage = _useState2[1];
var imageRef = useRef();
var defaultImageTransform = function defaultImageTransform() {
return {
scale: 1,
translateX: 0,
translateY: 0,
config: _objectSpread(_objectSpread({}, config["default"]), {}, {
precision: 0.01
})
};
};
/**
* Animates scale and translate offsets of Image as they change in gestures
*
* @see https://www.react-spring.io/docs/hooks/use-spring
*/
var _useSpring = useSpring(function () {
return _objectSpread(_objectSpread({}, defaultImageTransform()), {}, {
onFrame: function onFrame(f) {
if (f.scale < 1 || !f.pinching) set(defaultImageTransform); // Prevent dragging image out of viewport
if (f.scale > 1 && imageIsOutOfBounds(imageRef)) set(defaultImageTransform());
},
// Enable dragging in ImagePager if image is at the default size
onRest: function onRest(f) {
if (f.scale === 1) setDisableDrag(false);
}
});
}),
_useSpring2 = _slicedToArray(_useSpring, 2),
_useSpring2$ = _useSpring2[0],
scale = _useSpring2$.scale,
translateX = _useSpring2$.translateX,
translateY = _useSpring2$.translateY,
set = _useSpring2[1]; // Reset scale of this image when dragging to new image in ImagePager
useEffect(function () {
if (!isCurrentImage) set(defaultImageTransform);
});
/**
* Update Image scale and translate offsets during pinch/pan gestures
*
* @see https://github.com/react-spring/react-use-gesture#usegesture-hook-supporting-multiple-gestures-at-once
*/
var bind = useGesture({
onPinch: function onPinch(_ref2) {
var _ref2$movement = _slicedToArray(_ref2.movement, 1),
xMovement = _ref2$movement[0],
_ref2$origin = _slicedToArray(_ref2.origin, 2),
touchOriginX = _ref2$origin[0],
touchOriginY = _ref2$origin[1],
event = _ref2.event,
ctrlKey = _ref2.ctrlKey,
last = _ref2.last,
cancel = _ref2.cancel;
// Prevent ImagePager from registering isDragging
setDisableDrag(true); // Disable click to zoom during pinch
if (xMovement && !isPanningImage) setIsPanningImage(true); // Don't calculate new translate offsets on final frame
if (last) {
cancel();
return;
} // Speed up pinch zoom when using mouse versus touch
var SCALE_FACTOR = ctrlKey ? 1000 : 250;
var pinchScale = scale.value + xMovement / SCALE_FACTOR;
var pinchDelta = pinchScale - scale.value;
var clientX = event.clientX,
clientY = event.clientY; // Calculate the amount of x, y translate offset needed to
// zoom-in to point as image scale grows
var _getTranslateOffsetsF = getTranslateOffsetsFromScale({
imageRef: imageRef,
scale: scale.value,
pinchDelta: pinchDelta,
currentTranslate: [translateX.value, translateY.value],
// Use the [x, y] coords of mouse if a trackpad or ctrl + wheel event
// Otherwise use touch origin
touchOrigin: ctrlKey ? [clientX, clientY] : [touchOriginX, touchOriginY]
}),
_getTranslateOffsetsF2 = _slicedToArray(_getTranslateOffsetsF, 2),
newTranslateX = _getTranslateOffsetsF2[0],
newTranslateY = _getTranslateOffsetsF2[1]; // Restrict the amount of zoom between half and 3x image size
if (pinchScale < 0.5) set({
scale: 0.5,
pinching: true
});else if (pinchScale > 3.0) set({
scale: 3.0,
pinching: true
});else set({
scale: pinchScale,
translateX: newTranslateX,
translateY: newTranslateY,
pinching: true
});
},
onPinchEnd: function onPinchEnd() {
if (scale.value > 1) setDisableDrag(true);else set(defaultImageTransform);
setIsPanningImage(false);
},
onDragEnd: function onDragEnd() {
return setIsPanningImage(false);
},
onDrag: function onDrag(_ref3) {
var _ref3$movement = _slicedToArray(_ref3.movement, 2),
xMovement = _ref3$movement[0],
yMovement = _ref3$movement[1],
pinching = _ref3.pinching,
event = _ref3.event,
cancel = _ref3.cancel,
first = _ref3.first,
_ref3$memo = _ref3.memo,
memo = _ref3$memo === void 0 ? {
initialTranslateX: 0,
initialTranslateY: 0
} : _ref3$memo;
// Disable click to zoom during drag
if (xMovement && yMovement && !isPanningImage) setIsPanningImage(true);
if (event.touches && event.touches.length > 1) return;
if (pinching || scale.value <= 1) return; // Prevent dragging image out of viewport
if (scale.value > 1 && imageIsOutOfBounds(imageRef)) cancel();else {
if (first) {
return {
initialTranslateX: translateX.value,
initialTranslateY: translateY.value
};
} // Translate image from dragging
set({
translateX: memo.initialTranslateX + xMovement,
translateY: memo.initialTranslateY + yMovement
});
return memo;
}
}
},
/**
* useGesture config
* @see https://github.com/react-spring/react-use-gesture#usegesture-config
*/
{
domTarget: imageRef,
event: {
passive: false
}
});
/**
* @see https://github.com/react-spring/react-use-gesture#adding-gestures-to-dom-nodes
*/
useEffect(bind, [bind]); // Handle click/tap on image
useDoubleClick((_useDoubleClick = {}, _defineProperty(_useDoubleClick, singleClickToZoom ? 'onSingleClick' : 'onDoubleClick', function (e) {
if (pagerIsDragging || isPanningImage) {
e.stopPropagation();
return;
} // If tapped while already zoomed-in, zoom out to default scale
if (scale.value !== 1) {
set(defaultImageTransform);
return;
} // Zoom-in to origin of click on image
var touchOriginX = e.clientX,
touchOriginY = e.clientY;
var pinchScale = scale.value + 1;
var pinchDelta = pinchScale - scale.value; // Calculate the amount of x, y translate offset needed to
// zoom-in to point as image scale grows
var _getTranslateOffsetsF3 = getTranslateOffsetsFromScale({
imageRef: imageRef,
scale: scale.value,
pinchDelta: pinchDelta,
currentTranslate: [translateX.value, translateY.value],
touchOrigin: [touchOriginX, touchOriginY]
}),
_getTranslateOffsetsF4 = _slicedToArray(_getTranslateOffsetsF3, 2),
newTranslateX = _getTranslateOffsetsF4[0],
newTranslateY = _getTranslateOffsetsF4[1]; // Disable dragging in pager
setDisableDrag(true);
set({
scale: pinchScale,
translateX: newTranslateX,
translateY: newTranslateY,
pinching: true
});
}), _defineProperty(_useDoubleClick, "ref", imageRef), _defineProperty(_useDoubleClick, "latency", singleClickToZoom ? 0 : 200), _useDoubleClick));
return /*#__PURE__*/React.createElement(AnimatedImage, {
ref: imageRef,
className: "lightbox-image",
style: _objectSpread({
transform: to([scale, translateX, translateY], function (s, x, y) {
return "translate(".concat(x, "px, ").concat(y, "px) scale(").concat(s, ")");
}),
maxHeight: pagerHeight
}, isCurrentImage && {
willChange: 'transform'
}),
src: src,
alt: alt,
draggable: "false",
onDragStart: function onDragStart(e) {
// Disable image ghost dragging in firefox
e.preventDefault();
},
onClick: function onClick(e) {
// Don't close lighbox when clicking image
e.stopPropagation();
e.nativeEvent.stopImmediatePropagation();
}
});
};
var AnimatedImage = styled(animated.img)(_templateObject());
function _templateObject4() {
var data = _taggedTemplateLiteral(["\n position: relative;\n touch-action: none;\n user-select: none;\n"]);
_templateObject4 = function _templateObject4() {
return data;
};
return data;
}
function _templateObject3() {
var data = _taggedTemplateLiteral(["\n position: absolute;\n top: 0px;\n left: 0px;\n right: 0px;\n bottom: 0px;\n height: 100%;\n width: 100%;\n will-change: transform;\n touch-action: none;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n"]);
_templateObject3 = function _templateObject3() {
return data;
};
return data;
}
function _templateObject2() {
var data = _taggedTemplateLiteral(["\n width: 100%;\n display: flex;\n justify-content: center;\n"]);
_templateObject2 = function _templateObject2() {
return data;
};
return data;
}
function _templateObject$1() {
var data = _taggedTemplateLiteral(["\n display: flex;\n justify-content: center;\n align-items: center;\n"]);
_templateObject$1 = function _templateObject() {
return data;
};
return data;
}
/**
* Gesture controlled surface that animates prev/next page changes via spring physics.
*
* @param {array} images Array of image objects to be shown in Lightbox
* @param {number} currentIndex Index of image in images array that is currently shown
* @param {function} onPrev True if this image is currently shown in pager, otherwise false
* @param {function} onNext Function that can be called to disable dragging in the pager
* @param {function} onClose Function that closes the Lightbox
* @param {function} renderImageOverlay A React component that renders inside the image stage, useful for making overlays over the image
* @param {boolean} singleClickToZoom Overrides the default behavior of double clicking causing an image zoom to a single click
*
* @see https://github.com/react-spring/react-use-gesture
* @see https://github.com/react-spring/react-spring
*/
var ImagePager = function ImagePager(_ref) {
var images = _ref.images,
currentIndex = _ref.currentIndex,
onPrev = _ref.onPrev,
onNext = _ref.onNext,
onClose = _ref.onClose,
renderImageOverlay = _ref.renderImageOverlay,
singleClickToZoom = _ref.singleClickToZoom;
var firstRender = useRef(true);
var imageStageRef = useRef(_toConsumableArray(Array(images.length)).map(function () {
return React.createRef();
}));
var _useWindowSize = useWindowSize(),
windowHeight = _useWindowSize.height,
pageWidth = _useWindowSize.width;
var _useState = useState(false),
_useState2 = _slicedToArray(_useState, 2),
disableDrag = _useState2[0],
setDisableDrag = _useState2[1];
var _useState3 = useState('100%'),
_useState4 = _slicedToArray(_useState3, 2),
pagerHeight = _useState4[0],
setPagerHeight = _useState4[1];
var _useState5 = useState(false),
_useState6 = _slicedToArray(_useState5, 2),
isDragging = _useState6[0],
setIsDragging = _useState6[1]; // Generate page positions based on current index
var getPagePositions = function getPagePositions(i) {
var down = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var xDelta = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
var x = (i - currentIndex) * pageWidth + (down ? xDelta : 0);
if (i < currentIndex - 1 || i > currentIndex + 1) return {
x: x,
display: 'none'
};
return {
x: x,
display: 'flex'
};
};
/**
* Animates translateX of all images at the same time
*
* @see https://www.react-spring.io/docs/hooks/use-springs
*/
var _useSprings = useSprings(images.length, getPagePositions),
_useSprings2 = _slicedToArray(_useSprings, 2),
props = _useSprings2[0],
set = _useSprings2[1]; // Determine the absolute height of the image pager
useEffect(function () {
var currPagerHeight = imageStageRef.current[currentIndex].current.clientHeight - 50;
if (pagerHeight !== currPagerHeight) setPagerHeight(currPagerHeight);
}, [currentIndex, pagerHeight, windowHeight]); // Animate page change if currentIndex changes
useEffect(function () {
// No need to set page position for initial render
if (firstRender.current) {
firstRender.current = false;
return;
} // Update page positions after prev/next page state change
set(getPagePositions);
});
/**
* Update each Image's visibility and translateX offset during dragging
*
* @see https://github.com/react-spring/react-use-gesture
*/
var bind = useGesture({
onWheel: function onWheel(_ref2) {
var distance = _ref2.distance,
velocity = _ref2.velocity,
_ref2$direction = _slicedToArray(_ref2.direction, 2),
xDir = _ref2$direction[0],
yDir = _ref2$direction[1],
ctrlKey = _ref2.ctrlKey;
// Disable drag if Image has been zoomed in to allow for panning
if (ctrlKey || disableDrag || velocity === 0) return;
var draggedFarEnough = distance > pageWidth / 3;
var draggedFastEnough = velocity > 1.5 && distance <= pageWidth / 3; // Handle next/prev image from valid drag
if (draggedFarEnough || draggedFastEnough) {
var goToIndex = xDir + yDir > 0 ? -1 : 1;
if (goToIndex > 0) onNext();else if (goToIndex < 0) onPrev();
}
},
onWheelEnd: function onWheelEnd() {
set(function (i) {
return getPagePositions(i, false, 0);
});
setIsDragging(false);
},
onDrag: function onDrag(_ref3) {
var down = _ref3.down,
_ref3$movement = _slicedToArray(_ref3.movement, 1),
xMovement = _ref3$movement[0],
_ref3$direction = _slicedToArray(_ref3.direction, 1),
xDir = _ref3$direction[0],
velocity = _ref3.velocity,
distance = _ref3.distance,
cancel = _ref3.cancel,
touches = _ref3.touches;
// Disable drag if Image has been zoomed in to allow for panning
if (disableDrag || xMovement === 0) return;
if (!isDragging) setIsDragging(true);
var isHorizontalDrag = Math.abs(xDir) > 0.7;
var draggedFarEnough = down && isHorizontalDrag && distance > pageWidth / 3.5;
var draggedFastEnough = down && isHorizontalDrag && velocity > 2; // Handle next/prev image from valid drag
if (draggedFarEnough || draggedFastEnough) {
var goToIndex = xDir > 0 ? -1 : 1; // Cancel gesture animation
cancel();
if (goToIndex > 0) onNext();else if (goToIndex < 0) onPrev();
} // Don't move pager during two+ finger touch events, i.e. pinch-zoom
if (touches > 1) return; // Update page x-coordinates for single finger/mouse gestures
set(function (i) {
return getPagePositions(i, down, xMovement);
});
},
onDragEnd: function onDragEnd() {
return setIsDragging(false);
}
},
/**
* useGesture config
* @see https://github.com/react-spring/react-use-gesture#usegesture-config
*/
{
domTarget: imageStageRef.current[currentIndex],
event: {
passive: true,
capture: false
}
});
/**
* @see https://github.com/react-spring/react-use-gesture#adding-gestures-to-dom-nodes
*/
useEffect(bind, [bind, currentIndex]);
return props.map(function (_ref4, i) {
var x = _ref4.x,
display = _ref4.display;
return /*#__PURE__*/React.createElement(AnimatedImagePager, {
role: "presentation",
ref: imageStageRef.current[i],
key: i,
className: "lightbox-image-pager",
style: {
display: display,
transform: x.to(function (xInterp) {
return "translateX(".concat(xInterp, "px)");
})
},
onClick: function onClick() {
return Math.abs(x.value) < 1 && !disableDrag && onClose();
}
}, /*#__PURE__*/React.createElement(PagerContentWrapper, null, /*#__PURE__*/React.createElement(PagerInnerContentWrapper, null, /*#__PURE__*/React.createElement(ImageContainer, {
onClick: function onClick(e) {
e.stopPropagation();
e.nativeEvent.stopImmediatePropagation();
}
}, /*#__PURE__*/React.createElement(Image, {
setDisableDrag: setDisableDrag,
src: images[i].src,
alt: images[i].alt,
pagerHeight: pagerHeight,
isCurrentImage: i === currentIndex,
pagerIsDragging: isDragging,
singleClickToZoom: singleClickToZoom
}), renderImageOverlay()))));
});
};
var PagerInnerContentWrapper = styled.div(_templateObject$1());
var PagerContentWrapper = styled.div(_templateObject2());
var AnimatedImagePager = styled(animated.div)(_templateObject3());
var ImageContainer = styled.div(_templateObject4());
function _templateObject$2() {
var data = _taggedTemplateLiteral(["\n flex-grow: 1;\n position: relative;\n height: 100%;\n width: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n"]);
_templateObject$2 = function _templateObject() {
return data;
};
return data;
}
/**
* Containing element for ImagePager and prev/next button controls
*
* @param {array} images Array of image objects to be shown in Lightbox
* @param {number} currentIndex Index of image in images array that is currently shown
* @param {function} onPrev True if this image is currently shown in pager, otherwise false
* @param {function} onNext Function that can be called to disable dragging in the pager
* @param {function} renderPrevButton A React component that is used for previous button in image pager
* @param {function} renderNextButton A React component that is used for next button in image pager
* @param {function} renderImageOverlay A React component that renders inside the image stage, useful for making overlays over the image
* @param {boolean} singleClickToZoom Overrides the default behavior of double clicking causing an image zoom to a single click
*/
var ImageStage = function ImageStage(_ref) {
var images = _ref.images,
currentIndex = _ref.currentIndex,
onPrev = _ref.onPrev,
onNext = _ref.onNext,
onClose = _ref.onClose,
renderPrevButton = _ref.renderPrevButton,
renderNextButton = _ref.renderNextButton,
renderImageOverlay = _ref.renderImageOverlay,
singleClickToZoom = _ref.singleClickToZoom;
// Extra sanity check that the next/prev image exists before moving to it
var canPrev = currentIndex > 0;
var canNext = currentIndex + 1 < images.length;
return /*#__PURE__*/React.createElement(ImageStageContainer, {
className: "lightbox-image-stage"
}, renderPrevButton({
canPrev: canPrev
}), /*#__PURE__*/React.createElement(ImagePager, {
images: images,
currentIndex: currentIndex,
onClose: onClose,
onNext: onNext,
onPrev: onPrev,
renderImageOverlay: renderImageOverlay,
singleClickToZoom: singleClickToZoom
}), renderNextButton({
canNext: canNext
}));
};
var ImageStageContainer = styled.div(_templateObject$2());
function _templateObject$3() {
var data = _taggedTemplateLiteral(["\n display: flex;\n flex-direction: column;\n position: fixed;\n z-index: 400;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n"]);
_templateObject$3 = function _templateObject() {
return data;
};
return data;
}
function ownKeys$1(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread$1(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$1(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$1(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
/**
* Animates the lightbox as it opens/closes
*
* @param {ReactNode} children All child components of Lightbox
* @param {boolean} isOpen Flag that dictates if the lightbox is open or closed
* @param {string} className Classes are applied to the root lightbox component
* @param {object} style Inline styles are applied to the root lightbox component
* @param {object} pageTransitionConfig React-Spring useTransition config for page open/close animation
*
* @see https://www.react-spring.io/docs/hooks/use-transition
*/
var PageContainer = function PageContainer(_ref) {
var children = _ref.children,
isOpen = _ref.isOpen,
className = _ref.className,
style = _ref.style,
pageTransitionConfig = _ref.pageTransitionConfig;
var defaultTransition = {
from: {
transform: 'scale(0.75)',
opacity: 0
},
enter: {
transform: 'scale(1)',
opacity: 1
},
leave: {
transform: 'scale(0.75)',
opacity: 0
},
config: _objectSpread$1(_objectSpread$1({}, config["default"]), {}, {
mass: 1,
tension: 320,
friction: 32
})
};
var transitions = useTransition(isOpen, null, _objectSpread$1(_objectSpread$1({}, defaultTransition), pageTransitionConfig));
return transitions.map(function (_ref2) {
var item = _ref2.item,
key = _ref2.key,
props = _ref2.props;
return item && /*#__PURE__*/React.createElement(AnimatedPageContainer, {
key: key,
className: "lightbox-container".concat(className ? " ".concat(className) : ''),
style: _objectSpread$1(_objectSpread$1({}, props), style)
}, children);
});
};
var AnimatedPageContainer = styled(animated.div)(_templateObject$3());
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function () { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
/**
* Creates a SSR + next.js friendly React Portal inside <body />
*
* Child components are rendered on the client side only
*
* @param {array|node} children Child components will be rendered to the portal
* @see https://reactjs.org/docs/portals.html
*/
var CreatePortal = /*#__PURE__*/function (_React$Component) {
_inherits(CreatePortal, _React$Component);
var _super = _createSuper(CreatePortal);
function CreatePortal() {
var _this;
_classCallCheck(this, CreatePortal);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = _super.call.apply(_super, [this].concat(args));
_defineProperty(_assertThisInitialized(_this), "preventWheel", function (e) {
return e.preventDefault();
});
return _this;
}
_createClass(CreatePortal, [{
key: "componentDidMount",
// Only executes on the client-side
value: function componentDidMount() {
// Get the document body
this.body = document.body; // Create a container <div /> for React Portal
this.portalContainer = document.createElement('div');
this.portalContainer.setAttribute('class', 'lightbox-portal'); // Append the container to the document body
this.body.appendChild(this.portalContainer); // Force a re-render as we're on the client side now
// children prop will render to portalContainer
this.forceUpdate(); // Add event listener to prevent trackpad/ctrl+mousewheel zooming of lightbox
// Zooming is handled specifically within /ImageStage/components/Image
this.portalContainer.addEventListener('wheel', this.preventWheel);
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
// Remove wheel event listener
this.portalContainer.removeEventListener('wheel', this.preventWheel); // Cleanup Portal from DOM
this.body.removeChild(this.portalContainer);
}
}, {
key: "render",
value: function render() {
// Return null during SSR
if (this.portalContainer === undefined) return null;
var children = this.props.children;
return ReactDOM.createPortal(children, this.portalContainer);
}
}]);
return CreatePortal;
}(React.Component);
/**
* Gesture controlled lightbox that interpolates animations with spring physics.
*
* @param {boolean} isOpen Flag that dictates if the lightbox is open or closed
* @param {function} onClose Function that closes the Lightbox
* @param {function} onPrev Function that changes currentIndex to previous image in images
* @param {function} onNext Function that changes currentIndex to next image in images
* @param {number} currentIndex Index of image in images array that is currently shown
* @param {function} renderHeader A React component that renders above the image pager
* @param {function} renderFooter A React component that renders below the image pager
* @param {function} renderImageOverlay A React component that renders inside the image stage, useful for making overlays over the image
* @param {function} renderPrevButton A React component that is used for previous button in image pager
* @param {function} renderNextButton A React component that is used for next button in image pager
* @param {array} images Array of image objects to be shown in Lightbox
* @param {string} className Classes are applied to the root lightbox component
* @param {object} style Inline styles are applied to the root lightbox component
* @param {object} pageTransitionConfig React-Spring useTransition config for page open/close animation
* @param {boolean} singleClickToZoom Overrides the default behavior of double clicking causing an image zoom to a single click
*
* @see https://github.com/react-spring/react-use-gesture
* @see https://github.com/react-spring/react-spring
*/
var Lightbox = function Lightbox(_ref) {
var isOpen = _ref.isOpen,
onClose = _ref.onClose,
images = _ref.images,
currentIndex = _ref.currentIndex,
onPrev = _ref.onPrev,
onNext = _ref.onNext,
renderHeader = _ref.renderHeader,
renderFooter = _ref.renderFooter,
renderPrevButton = _ref.renderPrevButton,
renderNextButton = _ref.renderNextButton,
renderImageOverlay = _ref.renderImageOverlay,
className = _ref.className,
singleClickToZoom = _ref.singleClickToZoom,
style = _ref.style,
pageTransitionConfig = _ref.pageTransitionConfig;
// Handle event listeners for keyboard
useEffect(function () {
/**
* Prevent keyboard from controlling background page
* when lightbox is open
*/
var preventBackgroundScroll = function preventBackgroundScroll(e) {
var keysToIgnore = ['ArrowUp', 'ArrowDown', 'End', 'Home', 'PageUp', 'PageDown'];
if (isOpen && keysToIgnore.includes(e.key)) e.preventDefault();
};
/**
* Navigate images with arrow keys, close on Esc key
*/
var handleKeyboardInput = function handleKeyboardInput(e) {
if (isOpen) {
switch (e.key) {
case 'ArrowLeft':
onPrev();
break;
case 'ArrowRight':
onNext();
break;
case 'Escape':
onClose();
break;
default:
e.preventDefault();
break;
}
}
};
document.addEventListener('keyup', handleKeyboardInput);
document.addEventListener('keydown', preventBackgroundScroll);
return function () {
document.removeEventListener('keyup', handleKeyboardInput);
document.removeEventListener('keydown', preventBackgroundScroll);
};
});
return /*#__PURE__*/React.createElement(CreatePortal, null, /*#__PURE__*/React.createElement(PageContainer, {
isOpen: isOpen,
className: className,
style: style,
pageTransitionConfig: pageTransitionConfig
}, renderHeader(), /*#__PURE__*/React.createElement(ImageStage, {
images: images,
onClose: onClose,
currentIndex: currentIndex,
onPrev: onPrev,
onNext: onNext,
renderPrevButton: renderPrevButton,
renderNextButton: renderNextButton,
renderImageOverlay: renderImageOverlay,
singleClickToZoom: singleClickToZoom
}), renderFooter()));
};
Lightbox.defaultProps = {
pageTransitionConfig: null,
className: null,
style: null,
renderHeader: function renderHeader() {
return null;
},
renderFooter: function renderFooter() {
return null;
},
renderPrevButton: function renderPrevButton() {
return null;
},
renderNextButton: function renderNextButton() {
return null;
},
renderImageOverlay: function renderImageOverlay() {
return null;
},
singleClickToZoom: false
};
export default Lightbox;
import e,{useEffect as t,useState as n,useRef as r}from"react";import i from"styled-components";import o from"@babel/runtime/helpers/slicedToArray";import a from"@babel/runtime/helpers/toConsumableArray";import{useSpring as l,config as c,to as s,animated as u,useSprings as f,useTransition as p}from"@react-spring/web";import{useGesture as m}from"react-use-gesture";import g from"@babel/runtime/helpers/defineProperty";import d from"@babel/runtime/helpers/classCallCheck";import v from"@babel/runtime/helpers/createClass";import h from"@babel/runtime/helpers/assertThisInitialized";import y from"@babel/runtime/helpers/inherits";import b from"@babel/runtime/helpers/possibleConstructorReturn";import w from"@babel/runtime/helpers/getPrototypeOf";import C from"react-dom";var P=function(e){var t=e.imageRef,n=e.scale,r=e.pinchDelta,i=o(e.touchOrigin,2),a=i[0],l=i[1],c=o(e.currentTranslate,2),s=c[0],u=c[1],f=t.current.getBoundingClientRect(),p=f.top;return[-((a-f.left-f.width/2)/n)*r+s,-((l-p-f.height/2)/n)*r+u]},O=function(e){var t=e.current.getBoundingClientRect(),n=t.top,r=t.left,i=t.bottom,o=t.right,a=window,l=a.innerHeight,c=a.innerWidth;return r>.5*c||n>.5*l||o<.5*c||i<.5*l};function x(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function k(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?x(Object(n),!0).forEach((function(t){g(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):x(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}var E=function(i){var a,u=i.src,f=i.alt,p=i.pagerHeight,d=i.isCurrentImage,v=i.setDisableDrag,h=i.singleClickToZoom,y=i.pagerIsDragging,b=n(!1),w=o(b,2),C=w[0],x=w[1],E=r(),D=function(){return{scale:1,translateX:0,translateY:0,config:k(k({},c.default),{},{precision:.01})}},j=l((function(){return k(k({},D()),{},{onFrame:function(e){(e.scale<1||!e.pinching)&&A(D),e.scale>1&&O(E)&&A(D())},onRest:function(e){1===e.scale&&v(!1)}})})),T=o(j,2),N=T[0],R=N.scale,_=N.translateX,L=N.translateY,A=T[1];t((function(){d||A(D)}));var W=m({onPinch:function(e){var t=o(e.movement,1)[0],n=o(e.origin,2),r=n[0],i=n[1],a=e.event,l=e.ctrlKey,c=e.last,s=e.cancel;if(v(!0),t&&!C&&x(!0),c)s();else{var u=l?1e3:250,f=R.value+t/u,p=f-R.value,m=a.clientX,g=a.clientY,d=P({imageRef:E,scale:R.value,pinchDelta:p,currentTranslate:[_.value,L.value],touchOrigin:l?[m,g]:[r,i]}),h=o(d,2),y=h[0],b=h[1];A(f<.5?{scale:.5,pinching:!0}:f>3?{scale:3,pinching:!0}:{scale:f,translateX:y,translateY:b,pinching:!0})}},onPinchEnd:function(){R.value>1?v(!0):A(D),x(!1)},onDragEnd:function(){return x(!1)},onDrag:function(e){var t=o(e.movement,2),n=t[0],r=t[1],i=e.pinching,a=e.event,l=e.cancel,c=e.first,s=e.memo,u=void 0===s?{initialTranslateX:0,initialTranslateY:0}:s;if(n&&r&&!C&&x(!0),!(a.touches&&a.touches.length>1||i||R.value<=1))return R.value>1&&O(E)?void l():c?{initialTranslateX:_.value,initialTranslateY:L.value}:(A({translateX:u.initialTranslateX+n,translateY:u.initialTranslateY+r}),u)}},{domTarget:E,event:{passive:!1}});return t(W,[W]),function(e){var n=e.ref,r=e.latency,i=void 0===r?300:r,o=e.onSingleClick,a=void 0===o?function(){return null}:o,l=e.onDoubleClick,c=void 0===l?function(){return null}:l;t((function(){var e=n.current,t=0,r=function(e){t+=1,setTimeout((function(){1===t?a(e):2===t&&c(e),t=0}),i)};return e.addEventListener("click",r),function(){e.removeEventListener("click",r)}}))}((g(a={},h?"onSingleClick":"onDoubleClick",(function(e){if(y||C)e.stopPropagation();else if(1===R.value){var t=e.clientX,n=e.clientY,r=R.value+1,i=r-R.value,a=P({imageRef:E,scale:R.value,pinchDelta:i,currentTranslate:[_.value,L.value],touchOrigin:[t,n]}),l=o(a,2),c=l[0],s=l[1];v(!0),A({scale:r,translateX:c,translateY:s,pinching:!0})}else A(D)})),g(a,"ref",E),g(a,"latency",h?0:200),a)),e.createElement(I,{ref:E,className:"lightbox-image",style:k({transform:s([R,_,L],(function(e,t,n){return"translate(".concat(t,"px, ").concat(n,"px) scale(").concat(e,")")})),maxHeight:p},d&&{willChange:"transform"}),src:u,alt:f,draggable:"false",onDragStart:function(e){e.preventDefault()},onClick:function(e){e.stopPropagation(),e.nativeEvent.stopImmediatePropagation()}})},I=i(u.img).withConfig({displayName:"Image__AnimatedImage",componentId:"sc-1k35vrn-0"})(["width:auto;max-width:100%;user-select:none;::selection{background:none;}"]),D=function(i){var l=i.images,c=i.currentIndex,s=i.onPrev,u=i.onNext,p=i.onClose,g=i.renderImageOverlay,d=i.singleClickToZoom,v=r(!0),h=r(a(Array(l.length)).map((function(){return e.createRef()}))),y=function(){var e=n({width:window.innerWidth,height:window.innerHeight}),r=o(e,2),i=r[0],a=r[1];return t((function(){var e=function(){window.innerHeight===i.height&&window.innerWidth===i.width||a({width:window.innerWidth,height:window.innerHeight})};return window.addEventListener("resize",e),window.addEventListener("orientationchange",e),function(){window.removeEventListener("resize",e),window.addEventListener("orientationchange",e)}})),i}(),b=y.height,w=y.width,C=n(!1),P=o(C,2),O=P[0],x=P[1],k=n("100%"),I=o(k,2),D=I[0],_=I[1],L=n(!1),A=o(L,2),W=A[0],H=A[1],X=function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,r=(e-c)*w+(t?n:0);return e<c-1||e>c+1?{x:r,display:"none"}:{x:r,display:"flex"}},B=f(l.length,X),S=o(B,2),Y=S[0],Z=S[1];t((function(){var e=h.current[c].current.clientHeight-50;D!==e&&_(e)}),[c,D,b]),t((function(){v.current?v.current=!1:Z(X)}));var z=m({onWheel:function(e){var t=e.distance,n=e.velocity,r=o(e.direction,2),i=r[0],a=r[1];if(!e.ctrlKey&&!O&&0!==n&&(t>w/3||n>1.5&&t<=w/3)){var l=i+a>0?-1:1;l>0?u():l<0&&s()}},onWheelEnd:function(){Z((function(e){return X(e,!1,0)})),H(!1)},onDrag:function(e){var t=e.down,n=o(e.movement,1)[0],r=o(e.direction,1)[0],i=e.velocity,a=e.distance,l=e.cancel,c=e.touches;if(!O&&0!==n){W||H(!0);var f=Math.abs(r)>.7;if(t&&f&&a>w/3.5||t&&f&&i>2){var p=r>0?-1:1;l(),p>0?u():p<0&&s()}c>1||Z((function(e){return X(e,t,n)}))}},onDragEnd:function(){return H(!1)}},{domTarget:h.current[c],event:{passive:!0,capture:!1}});return t(z,[z,c]),Y.map((function(t,n){var r=t.x,i=t.display;return e.createElement(N,{role:"presentation",ref:h.current[n],key:n,className:"lightbox-image-pager",style:{display:i,transform:r.to((function(e){return"translateX(".concat(e,"px)")}))},onClick:function(){return Math.abs(r.value)<1&&!O&&p()}},e.createElement(T,null,e.createElement(j,null,e.createElement(R,{onClick:function(e){e.stopPropagation(),e.nativeEvent.stopImmediatePropagation()}},e.createElement(E,{setDisableDrag:x,src:l[n].src,alt:l[n].alt,pagerHeight:D,isCurrentImage:n===c,pagerIsDragging:W,singleClickToZoom:d}),g()))))}))},j=i.div.withConfig({displayName:"ImagePager__PagerInnerContentWrapper",componentId:"a18fy4-0"})(["display:flex;justify-content:center;align-items:center;"]),T=i.div.withConfig({displayName:"ImagePager__PagerContentWrapper",componentId:"a18fy4-1"})(["width:100%;display:flex;justify-content:center;"]),N=i(u.div).withConfig({displayName:"ImagePager__AnimatedImagePager",componentId:"a18fy4-2"})(["position:absolute;top:0px;left:0px;right:0px;bottom:0px;height:100%;width:100%;will-change:transform;touch-action:none;display:flex;flex-direction:column;justify-content:center;align-items:center;"]),R=i.div.withConfig({displayName:"ImagePager__ImageContainer",componentId:"a18fy4-3"})(["position:relative;touch-action:none;user-select:none;"]),_=function(t){var n=t.images,r=t.currentIndex,i=t.onPrev,o=t.onNext,a=t.onClose,l=t.renderPrevButton,c=t.renderNextButton,s=t.renderImageOverlay,u=t.singleClickToZoom,f=r>0,p=r+1<n.length;return e.createElement(L,{className:"lightbox-image-stage"},l({canPrev:f}),e.createElement(D,{images:n,currentIndex:r,onClose:a,onNext:o,onPrev:i,renderImageOverlay:s,singleClickToZoom:u}),c({canNext:p}))},L=i.div.withConfig({displayName:"ImageStage__ImageStageContainer",componentId:"m6g63l-0"})(["flex-grow:1;position:relative;height:100%;width:100%;display:flex;justify-content:center;align-items:center;"]);function A(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function W(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?A(Object(n),!0).forEach((function(t){g(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):A(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}var H=function(t){var n=t.children,r=t.isOpen,i=t.className,o=t.style,a=t.pageTransitionConfig,l={from:{transform:"scale(0.75)",opacity:0},enter:{transform:"scale(1)",opacity:1},leave:{transform:"scale(0.75)",opacity:0},config:W(W({},c.default),{},{mass:1,tension:320,friction:32})};return p(r,null,W(W({},l),a)).map((function(t){var r=t.item,a=t.key,l=t.props;return r&&e.createElement(X,{key:a,className:"lightbox-container".concat(i?" ".concat(i):""),style:W(W({},l),o)},n)}))},X=i(u.div).withConfig({displayName:"PageContainer__AnimatedPageContainer",componentId:"sc-19m9s01-0"})(["display:flex;flex-direction:column;position:fixed;z-index:400;top:0;bottom:0;left:0;right:0;"]);function B(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,r=w(e);if(t){var i=w(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return b(this,n)}}var S=function(e){y(n,e);var t=B(n);function n(){var e;d(this,n);for(var r=arguments.length,i=new Array(r),o=0;o<r;o++)i[o]=arguments[o];return e=t.call.apply(t,[this].concat(i)),g(h(e),"preventWheel",(function(e){return e.preventDefault()})),e}return v(n,[{key:"componentDidMount",value:function(){this.body=document.body,this.portalContainer=document.createElement("div"),this.portalContainer.setAttribute("class","lightbox-portal"),this.body.appendChild(this.portalContainer),this.forceUpdate(),this.portalContainer.addEventListener("wheel",this.preventWheel)}},{key:"componentWillUnmount",value:function(){this.portalContainer.removeEventListener("wheel",this.preventWheel),this.body.removeChild(this.portalContainer)}},{key:"render",value:function(){if(void 0===this.portalContainer)return null;var e=this.props.children;return C.createPortal(e,this.portalContainer)}}]),n}(e.Component),Y=function(n){var r=n.isOpen,i=n.onClose,o=n.images,a=n.currentIndex,l=n.onPrev,c=n.onNext,s=n.renderHeader,u=n.renderFooter,f=n.renderPrevButton,p=n.renderNextButton,m=n.renderImageOverlay,g=n.className,d=n.singleClickToZoom,v=n.style,h=n.pageTransitionConfig;return t((function(){var e=function(e){r&&["ArrowUp","ArrowDown","End","Home","PageUp","PageDown"].includes(e.key)&&e.preventDefault()},t=function(e){if(r)switch(e.key){case"ArrowLeft":l();break;case"ArrowRight":c();break;case"Escape":i();break;default:e.preventDefault()}};return document.addEventListener("keyup",t),document.addEventListener("keydown",e),function(){document.removeEventListener("keyup",t),document.removeEventListener("keydown",e)}})),e.createElement(S,null,e.createElement(H,{isOpen:r,className:g,style:v,pageTransitionConfig:h},s(),e.createElement(_,{images:o,onClose:i,currentIndex:a,onPrev:l,onNext:c,renderPrevButton:f,renderNextButton:p,renderImageOverlay:m,singleClickToZoom:d}),u()))};Y.defaultProps={pageTransitionConfig:null,className:null,style:null,renderHeader:function(){return null},renderFooter:function(){return null},renderPrevButton:function(){return null},renderNextButton:function(){return null},renderImageOverlay:function(){return null},singleClickToZoom:!1};export default Y;
//# sourceMappingURL=index.es.js.map

4

package.json
{
"name": "react-spring-lightbox",
"version": "1.4.9",
"version": "1.4.10-beta.0",
"description": "A flexible image gallery lightbox with native-feeling touch gestures and buttery smooth animations, built with react-spring.",

@@ -77,2 +77,3 @@ "author": "Tim Ellenberger <timellenberger@gmail.com>",

"babel-eslint": "10.1.0",
"babel-plugin-styled-components": "1.10.5",
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",

@@ -99,2 +100,3 @@ "babel-polyfill": "^6.26.0",

"rollup-plugin-filesize": "^8.0.2",
"rollup-plugin-terser": "^5.3.0",
"styled-components": "^5.0.1"

@@ -101,0 +103,0 @@ },

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc