react-fex-gallery
Version:
React gallery powered by FEX.net API
1,351 lines (1,135 loc) • 360 kB
JavaScript
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var React = require('react');
var React__default = _interopDefault(React);
var styled = require('styled-components');
var styled__default = _interopDefault(styled);
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function _taggedTemplateLiteralLoose(strings, raw) {
if (!raw) {
raw = strings.slice(0);
}
strings.raw = raw;
return strings;
}
// A type of promise-like that resolves synchronously and supports only one observer
const _iteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.iterator || (Symbol.iterator = Symbol("Symbol.iterator"))) : "@@iterator";
const _asyncIteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.asyncIterator || (Symbol.asyncIterator = Symbol("Symbol.asyncIterator"))) : "@@asyncIterator";
// Asynchronously call a function and send errors to recovery continuation
function _catch(body, recover) {
try {
var result = body();
} catch(e) {
return recover(e);
}
if (result && result.then) {
return result.then(void 0, recover);
}
return result;
}
// Asynchronously await a promise and pass the result to a finally continuation
function _finallyRethrows(body, finalizer) {
try {
var result = body();
} catch (e) {
return finalizer(true, e);
}
if (result && result.then) {
return result.then(finalizer.bind(null, false), finalizer.bind(null, true));
}
return finalizer(false, result);
}
var fetchData = function fetchData(_ref) {
var _ref$method = _ref.method,
method = _ref$method === void 0 ? 'GET' : _ref$method,
_ref$data = _ref.data,
data = _ref$data === void 0 ? {} : _ref$data,
url = _ref.url;
try {
var init = {
method: method,
mode: 'cors',
cache: 'no-cache',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json'
},
redirect: 'follow',
referrerPolicy: 'no-referrer'
};
if (method !== 'GET') {
init = _extends({}, init, {
body: JSON.stringify(data)
});
}
return Promise.resolve(_catch(function () {
return Promise.resolve(fetch(url, init)).then(function (response) {
return Promise.resolve(response.json());
});
}, function (e) {
throw e;
}));
} catch (e) {
return Promise.reject(e);
}
};
var defaultContentText = {
highlighted: 'Выделено',
clearHighlighted: 'Снять выделение',
pluralize: {
image: {
one: 'изображение',
two: 'изображения',
five: 'изображений'
}
},
showHighlighted: 'Показать выделенные',
showAll: 'Показать все',
show: 'Показать',
download: 'Скачать',
copy: 'Копировать',
print: 'Распечатать',
fileInfo: 'Информация о файле',
"delete": 'Удалить',
search: 'Поиск',
close: 'Закрыть',
highlightedSearch: 'Поиск по выделенным',
loadingImages: 'Загрузка изображений...',
fileProperties: 'Свойства файла',
size: 'Размер',
created: 'Создан',
fileExtension: 'Формат файла'
};
var initialState = {
currentIndex: 0,
images: [],
showInfo: false,
view: 'gallery',
imagesCount: 0,
selectedImages: [],
contentText: defaultContentText,
accessRights: 'read',
folderName: '',
methods: {},
searchQuery: ''
};
var toggleSelectedImage = function toggleSelectedImage(selectedImages, image, allImages) {
var exist = selectedImages.find(function (i) {
return i.id === image.id;
});
if (exist) {
return selectedImages.filter(function (i) {
return i.id !== image.id;
});
}
return [].concat(selectedImages, [image]).sort(function (a, b) {
return allImages.indexOf(a) - allImages.indexOf(b);
});
};
var reducer = function reducer(state, action) {
switch (action.type) {
case 'reset-gallery':
return initialState;
case 'unselect-all':
return _extends({}, state, {
selectedImages: [],
showOnlySelected: false
});
case 'switch-show-info':
return _extends({}, state, {
showInfo: !state.showInfo,
infoForImage: action.infoForImage
});
case 'change-show-info':
return _extends({}, state, {
showInfo: action.showInfo,
infoForImage: action.infoForImage
});
case 'switch-view':
return _extends({}, state, {
prevView: state.view,
view: action.view
});
case 'append-images':
return _extends({}, state, {
images: [].concat(state.images, action.images)
});
case 'set-images':
return _extends({}, state, {
images: [].concat(action.images)
});
case 'toggle-selected-item':
return _extends({}, state, {
selectedImages: toggleSelectedImage(state.selectedImages, action.image, state.images)
});
case 'toggle-show-only-selected':
return _extends({}, state, {
showOnlySelected: !state.showOnlySelected
});
case 'set-search-image-query':
return _extends({}, state, {
searchQuery: action.query
});
case 'clear-search-image-query':
return _extends({}, state, {
searchQuery: ''
});
case 'set-current-index':
return _extends({}, state, {
currentIndex: action.index <= state.imagesCount - 1 ? action.index : 0
});
case 'append-response':
return _extends({}, state, {
apiEndpointPagination: action.pagination,
images: [].concat(state.images, action.images),
apiEndpoint: action.endPoint,
currentIndex: action.setNextIndex ? state.currentIndex + 1 : action.setLastIndex ? [].concat(state.images, action.images).length - 1 : state.currentIndex
});
case 'show-notifier':
return _extends({}, state, {
notifier: action.message
});
case 'clear-notifier':
return _extends({}, state, {
notifier: undefined
});
case 'after-delete-images':
{
return _extends({}, state, {
currentIndex: action.newIndex ? action.newIndex : state.currentIndex,
imagesCount: action.count ? action.count : state.imagesCount,
images: action.images ? action.images : state.images
});
}
case 'set-images-count':
{
return _extends({}, state, {
imagesCount: action.imagesCount,
currentIndex: state.currentIndex <= action.imagesCount - 1 ? state.currentIndex : 0
});
}
}
return state;
};
var useStore = function useStore(_state) {
var _useReducer = React.useReducer(reducer, _extends({}, initialState, _state)),
state = _useReducer[0],
dispatch = _useReducer[1];
var withMiddleware = function withMiddleware(dispatch) {
return function (action) {
try {
var _temp5 = function _temp5(_result3) {
if (_exit2) return _result3;
if (action.type === 'after-delete-images') {
dispatch({
type: 'unselect-all'
});
}
};
var _exit2 = false;
dispatch(action);
if (action.type === 'toggle-selected-item') {
if (state.showOnlySelected && state.selectedImages.length <= 1) {
dispatch({
type: 'unselect-all'
});
}
if (state.view === 'grid' && state.selectedImages.length === 1 && state.selectedImages.find(function (i) {
return i.id === action.image.id;
})) {
dispatch({
type: 'change-show-info',
showInfo: false
});
}
}
if (action.type === 'unselect-all') {
if (state.view === 'grid' && state.showInfo) {
dispatch({
type: 'change-show-info',
showInfo: false
});
}
}
var _temp6 = function () {
if (action.type === 'fetch-more-images') {
return function () {
if (state.apiEndpoint) {
return _finallyRethrows(function () {
return _catch(function () {
var _state$apiEndpointPag;
function _temp2() {
anchor.remove();
}
var anchor = document.createElement('a');
anchor.href = state.apiEndpoint;
var search = new URLSearchParams(anchor.search);
if (((_state$apiEndpointPag = state.apiEndpointPagination) === null || _state$apiEndpointPag === void 0 ? void 0 : _state$apiEndpointPag.pages.toString()) === search.get('page') || window.FEX_GALLERY_QUEUE_BUSY) {
_exit2 = true;
return;
}
window.FEX_GALLERY_QUEUE_BUSY = true;
dispatch({
type: 'show-notifier',
message: state.contentText.loadingImages
});
var _temp = function () {
var _state$apiEndpointPag2;
if (action.fetchAll && ((_state$apiEndpointPag2 = state.apiEndpointPagination) === null || _state$apiEndpointPag2 === void 0 ? void 0 : _state$apiEndpointPag2.pages)) {
var currentPage = parseInt(!!search.get('page') ? search.get('page') : '1');
var array = [];
for (var i = currentPage + 1; i <= state.apiEndpointPagination.pages; i++) {
search.set('page', i.toString());
anchor.search = '?' + search;
array.push(anchor.href);
}
return Promise.resolve(Promise.all([].concat(array.map(function (i) {
return fetchData({
url: i
});
})))).then(function (promises) {
var images = [];
var pagination = {
count: 0,
page: 0,
pages: 0,
per_page: 0
};
promises.forEach(function (promise, index) {
if (index === promises.length - 1) {
pagination = promise.pagination;
}
images = [].concat(images, promise.children);
});
if (promises.length) {
dispatch({
type: 'append-response',
images: images,
pagination: pagination,
endPoint: anchor.href,
setLastIndex: true
});
}
});
} else {
search.forEach(function (value, key) {
if (key === 'page') {
search.set('page', (parseInt(value) + 1).toString());
}
});
anchor.search = '?' + search;
return Promise.resolve(fetchData({
url: anchor.href
})).then(function (response) {
if (response) {
dispatch({
type: 'append-response',
images: response.children,
pagination: response.pagination,
endPoint: anchor.href,
setNextIndex: action.setNextIndex
});
}
});
}
}();
return _temp && _temp.then ? _temp.then(_temp2) : _temp2(_temp);
}, function (e) {
console.error(e);
});
}, function (_wasThrown, _result) {
dispatch({
type: 'clear-notifier'
});
window.FEX_GALLERY_QUEUE_BUSY = false;
if (_wasThrown) throw _result;
return _result;
});
} else {
if (state.methods.onReachEnd) {
if (!window.FEX_GALLERY_QUEUE_BUSY) {
var _state$methods$onReac, _state$methods;
window.FEX_GALLERY_QUEUE_BUSY = true;
dispatch({
type: 'show-notifier',
message: state.contentText.loadingImages
});
(_state$methods$onReac = (_state$methods = state.methods).onReachEnd) === null || _state$methods$onReac === void 0 ? void 0 : _state$methods$onReac.call(_state$methods, action.fetchAll).then(function (images) {
if (images) {
dispatch({
type: 'set-images',
images: images
});
if (action.fetchAll) {
dispatch({
type: 'set-current-index',
index: images.length - 1
});
}
}
})["finally"](function () {
dispatch({
type: 'clear-notifier'
});
window.FEX_GALLERY_QUEUE_BUSY = false;
});
}
}
}
}();
}
}();
return Promise.resolve(_temp6 && _temp6.then ? _temp6.then(_temp5) : _temp5(_temp6));
} catch (e) {
return Promise.reject(e);
}
};
};
return [state, withMiddleware(dispatch)];
};
var AppContext = React__default.createContext({
state: initialState,
dispatch: {}
});
var useAppContext = function useAppContext() {
var _useContext = React.useContext(AppContext),
state = _useContext.state,
dispatch = _useContext.dispatch;
return {
state: state,
dispatch: dispatch
};
};
function _templateObject4() {
var data = _taggedTemplateLiteralLoose(["\n width: 100vw;\n height: 100vh;\n left: 0;\n right: 0;\n top: 0;\n bottom: 0;\n position: fixed;\n z-index: 99;\n display: flex;\n align-items: center;\n justify-content: center;\n"]);
_templateObject4 = function _templateObject4() {
return data;
};
return data;
}
function _templateObject3() {
var data = _taggedTemplateLiteralLoose(["\n color: #1facf7;\n font-size: 90px;\n text-indent: -9999em;\n overflow: hidden;\n width: 1em;\n height: 1em;\n border-radius: 50%;\n margin: 72px auto;\n position: relative;\n -webkit-transform: translateZ(0);\n -ms-transform: translateZ(0);\n transform: translateZ(0);\n animation: ", " 1.7s infinite ease, ", " 1.7s infinite ease;\n"]);
_templateObject3 = function _templateObject3() {
return data;
};
return data;
}
function _templateObject2() {
var data = _taggedTemplateLiteralLoose(["\n 0% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg);\n }\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n"]);
_templateObject2 = function _templateObject2() {
return data;
};
return data;
}
function _templateObject() {
var data = _taggedTemplateLiteralLoose(["\n 0% {\n box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em;\n }\n 5%,\n 95% {\n box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em;\n }\n 10%,\n 59% {\n box-shadow: 0 -0.83em 0 -0.4em, -0.087em -0.825em 0 -0.42em, -0.173em -0.812em 0 -0.44em, -0.256em -0.789em 0 -0.46em, -0.297em -0.775em 0 -0.477em;\n }\n 20% {\n box-shadow: 0 -0.83em 0 -0.4em, -0.338em -0.758em 0 -0.42em, -0.555em -0.617em 0 -0.44em, -0.671em -0.488em 0 -0.46em, -0.749em -0.34em 0 -0.477em;\n }\n 38% {\n box-shadow: 0 -0.83em 0 -0.4em, -0.377em -0.74em 0 -0.42em, -0.645em -0.522em 0 -0.44em, -0.775em -0.297em 0 -0.46em, -0.82em -0.09em 0 -0.477em;\n }\n 100% {\n box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em;\n }\n"]);
_templateObject = function _templateObject() {
return data;
};
return data;
}
var load6 = styled.keyframes(_templateObject());
var round = styled.keyframes(_templateObject2());
var Loader = styled__default.div(_templateObject3(), load6, round);
var FullscreenLoaderWrapper = styled__default.div(_templateObject4());
function _templateObject13() {
var data = _taggedTemplateLiteralLoose(["\n padding-right: 32px;\n padding-left: 0;\n justify-content: flex-end;\n"]);
_templateObject13 = function _templateObject13() {
return data;
};
return data;
}
function _templateObject12() {
var data = _taggedTemplateLiteralLoose(["\n width: 50%;\n height: 100%;\n cursor: pointer;\n display: flex;\n align-items: center;\n padding-left: 32px;\n justify-content: flex-start;\n\n svg {\n transition: fill .225s;\n fill: rgba(255, 255, 255, .25);\n }\n\n &:hover {\n svg {\n fill: #fff;\n }\n }\n"]);
_templateObject12 = function _templateObject12() {
return data;
};
return data;
}
function _templateObject11() {
var data = _taggedTemplateLiteralLoose(["\n position: absolute;\n width: 100%;\n height: 100%;\n left: 0;\n right: 0;\n top: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n z-index: 2;\n"]);
_templateObject11 = function _templateObject11() {
return data;
};
return data;
}
function _templateObject10() {
var data = _taggedTemplateLiteralLoose(["\n max-height: 90px;\n max-width: 768px;\n width: 100%;\n margin: 0 auto;\n overflow: hidden;\n position: relative;\n z-index: 2;\n"]);
_templateObject10 = function _templateObject10() {
return data;
};
return data;
}
function _templateObject9() {
var data = _taggedTemplateLiteralLoose(["\n height: 104px;\n min-height: 104px;\n position: relative;\n"]);
_templateObject9 = function _templateObject9() {
return data;
};
return data;
}
function _templateObject8() {
var data = _taggedTemplateLiteralLoose(["\n padding: 12px 16px;\n font-size: 13px;\n line-height: 16px;\n color: #828282;\n text-align: center;\n position: relative;\n transform: translateY(10px);\n"]);
_templateObject8 = function _templateObject8() {
return data;
};
return data;
}
function _templateObject7() {
var data = _taggedTemplateLiteralLoose(["\n padding: ", ";\n height: ", ";\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: column;\n\n img {\n max-width: 100%;\n max-height: 100%;\n width: auto;\n height: auto;\n display: block;\n margin: auto;\n position: relative;\n z-index: 1;\n opacity: 0;\n animation: ", " .35s ease-out forwards;\n user-select: none;\n\n &.next {\n animation-name: ", ";\n }\n\n &.prev {\n animation-name: ", ";\n }\n }\n\n ", " {\n position: absolute;\n }\n"]);
_templateObject7 = function _templateObject7() {
return data;
};
return data;
}
function _templateObject6() {
var data = _taggedTemplateLiteralLoose(["\n max-height: 90px;\n max-width: 768px;\n width: 100%;\n margin: 0 auto;\n overflow: hidden;\n position: relative;\n z-index: 2;\n"]);
_templateObject6 = function _templateObject6() {
return data;
};
return data;
}
function _templateObject5() {
var data = _taggedTemplateLiteralLoose(["\n height: calc(100% - 104px);\n position: relative;\n display: flex;\n flex-direction: column;\n"]);
_templateObject5 = function _templateObject5() {
return data;
};
return data;
}
function _templateObject4$1() {
var data = _taggedTemplateLiteralLoose(["\n height: 100%;\n display: flex;\n flex-direction: column;\n"]);
_templateObject4$1 = function _templateObject4() {
return data;
};
return data;
}
function _templateObject3$1() {
var data = _taggedTemplateLiteralLoose(["\n 0% {\n transform: translateX(-20px);\n opacity: .5;\n }\n\n 100% {\n transform: none;\n opacity: 1;\n }\n"]);
_templateObject3$1 = function _templateObject3() {
return data;
};
return data;
}
function _templateObject2$1() {
var data = _taggedTemplateLiteralLoose(["\n 0% {\n transform: scale(.9);\n opacity: .5;\n }\n\n 100% {\n transform: none;\n opacity: 1;\n }\n"]);
_templateObject2$1 = function _templateObject2() {
return data;
};
return data;
}
function _templateObject$1() {
var data = _taggedTemplateLiteralLoose(["\n 0% {\n transform: translateX(20px);\n opacity: .5;\n }\n\n 100% {\n transform: none;\n opacity: 1;\n }\n"]);
_templateObject$1 = function _templateObject() {
return data;
};
return data;
}
var slideImageNext = styled.keyframes(_templateObject$1());
var slideImageFirst = styled.keyframes(_templateObject2$1());
var slideImagePrev = styled.keyframes(_templateObject3$1());
var GalleryStyled = styled__default.div(_templateObject4$1());
var GalleryTop = styled__default.div(_templateObject5());
var GalleryTopPromo = styled__default.div(_templateObject6());
var GalleryImageHolder = styled__default.div(_templateObject7(), function (_ref) {
var additionalHeight = _ref.additionalHeight;
return additionalHeight > 0 ? '12px 80px' : '24px 80px 6px';
}, function (_ref2) {
var additionalHeight = _ref2.additionalHeight;
return "calc(100% - " + (40 + additionalHeight) + "px)";
}, slideImageFirst, slideImageNext, slideImagePrev, Loader);
var GalleryImageName = styled__default.div(_templateObject8());
var GalleryBottom = styled__default.div(_templateObject9());
var GalleryBottomPromo = styled__default.div(_templateObject10());
var GalleryTopDirectionWrapper = styled__default.div(_templateObject11());
var GalleryTopDirection = styled__default.div(_templateObject12());
var GalleryTopDirectionOpposite = styled__default(GalleryTopDirection)(_templateObject13());
function _extends$1() {
_extends$1 = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends$1.apply(this, arguments);
}
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
subClass.__proto__ = superClass;
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function areInputsEqual(newInputs, lastInputs) {
if (newInputs.length !== lastInputs.length) {
return false;
}
for (var i = 0; i < newInputs.length; i++) {
if (newInputs[i] !== lastInputs[i]) {
return false;
}
}
return true;
}
function memoizeOne(resultFn, isEqual) {
if (isEqual === void 0) { isEqual = areInputsEqual; }
var lastThis;
var lastArgs = [];
var lastResult;
var calledOnce = false;
function memoized() {
var newArgs = [];
for (var _i = 0; _i < arguments.length; _i++) {
newArgs[_i] = arguments[_i];
}
if (calledOnce && lastThis === this && isEqual(newArgs, lastArgs)) {
return lastResult;
}
lastResult = resultFn.apply(this, newArgs);
calledOnce = true;
lastThis = this;
lastArgs = newArgs;
return lastResult;
}
return memoized;
}
// Animation frame based implementation of setTimeout.
// Inspired by Joe Lambert, https://gist.github.com/joelambert/1002116#file-requesttimeout-js
var hasNativePerformanceNow = typeof performance === 'object' && typeof performance.now === 'function';
var now = hasNativePerformanceNow ? function () {
return performance.now();
} : function () {
return Date.now();
};
function cancelTimeout(timeoutID) {
cancelAnimationFrame(timeoutID.id);
}
function requestTimeout(callback, delay) {
var start = now();
function tick() {
if (now() - start >= delay) {
callback.call(null);
} else {
timeoutID.id = requestAnimationFrame(tick);
}
}
var timeoutID = {
id: requestAnimationFrame(tick)
};
return timeoutID;
}
var size = -1; // This utility copied from "dom-helpers" package.
function getScrollbarSize(recalculate) {
if (recalculate === void 0) {
recalculate = false;
}
if (size === -1 || recalculate) {
var div = document.createElement('div');
var style = div.style;
style.width = '50px';
style.height = '50px';
style.overflow = 'scroll';
document.body.appendChild(div);
size = div.offsetWidth - div.clientWidth;
document.body.removeChild(div);
}
return size;
}
var cachedRTLResult = null; // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
// Chrome does not seem to adhere; its scrollLeft values are positive (measured relative to the left).
// Safari's elastic bounce makes detecting this even more complicated wrt potential false positives.
// The safest way to check this is to intentionally set a negative offset,
// and then verify that the subsequent "scroll" event matches the negative offset.
// If it does not match, then we can assume a non-standard RTL scroll implementation.
function getRTLOffsetType(recalculate) {
if (recalculate === void 0) {
recalculate = false;
}
if (cachedRTLResult === null || recalculate) {
var outerDiv = document.createElement('div');
var outerStyle = outerDiv.style;
outerStyle.width = '50px';
outerStyle.height = '50px';
outerStyle.overflow = 'scroll';
outerStyle.direction = 'rtl';
var innerDiv = document.createElement('div');
var innerStyle = innerDiv.style;
innerStyle.width = '100px';
innerStyle.height = '100px';
outerDiv.appendChild(innerDiv);
document.body.appendChild(outerDiv);
if (outerDiv.scrollLeft > 0) {
cachedRTLResult = 'positive-descending';
} else {
outerDiv.scrollLeft = 1;
if (outerDiv.scrollLeft === 0) {
cachedRTLResult = 'negative';
} else {
cachedRTLResult = 'positive-ascending';
}
}
document.body.removeChild(outerDiv);
return cachedRTLResult;
}
return cachedRTLResult;
}
var IS_SCROLLING_DEBOUNCE_INTERVAL = 150;
var defaultItemKey = function defaultItemKey(_ref) {
var columnIndex = _ref.columnIndex,
rowIndex = _ref.rowIndex;
return rowIndex + ":" + columnIndex;
}; // In DEV mode, this Set helps us only log a warning once per component instance.
// This avoids spamming the console every time a render happens.
var devWarningsOverscanCount = null;
var devWarningsOverscanRowsColumnsCount = null;
var devWarningsTagName = null;
if (process.env.NODE_ENV !== 'production') {
if (typeof window !== 'undefined' && typeof window.WeakSet !== 'undefined') {
devWarningsOverscanCount =
/*#__PURE__*/
new WeakSet();
devWarningsOverscanRowsColumnsCount =
/*#__PURE__*/
new WeakSet();
devWarningsTagName =
/*#__PURE__*/
new WeakSet();
}
}
function createGridComponent(_ref2) {
var _class, _temp;
var getColumnOffset = _ref2.getColumnOffset,
getColumnStartIndexForOffset = _ref2.getColumnStartIndexForOffset,
getColumnStopIndexForStartIndex = _ref2.getColumnStopIndexForStartIndex,
getColumnWidth = _ref2.getColumnWidth,
getEstimatedTotalHeight = _ref2.getEstimatedTotalHeight,
getEstimatedTotalWidth = _ref2.getEstimatedTotalWidth,
getOffsetForColumnAndAlignment = _ref2.getOffsetForColumnAndAlignment,
getOffsetForRowAndAlignment = _ref2.getOffsetForRowAndAlignment,
getRowHeight = _ref2.getRowHeight,
getRowOffset = _ref2.getRowOffset,
getRowStartIndexForOffset = _ref2.getRowStartIndexForOffset,
getRowStopIndexForStartIndex = _ref2.getRowStopIndexForStartIndex,
initInstanceProps = _ref2.initInstanceProps,
shouldResetStyleCacheOnItemSizeChange = _ref2.shouldResetStyleCacheOnItemSizeChange,
validateProps = _ref2.validateProps;
return _temp = _class =
/*#__PURE__*/
function (_PureComponent) {
_inheritsLoose(Grid, _PureComponent);
// Always use explicit constructor for React components.
// It produces less code after transpilation. (#26)
// eslint-disable-next-line no-useless-constructor
function Grid(props) {
var _this;
_this = _PureComponent.call(this, props) || this;
_this._instanceProps = initInstanceProps(_this.props, _assertThisInitialized(_assertThisInitialized(_this)));
_this._resetIsScrollingTimeoutId = null;
_this._outerRef = void 0;
_this.state = {
instance: _assertThisInitialized(_assertThisInitialized(_this)),
isScrolling: false,
horizontalScrollDirection: 'forward',
scrollLeft: typeof _this.props.initialScrollLeft === 'number' ? _this.props.initialScrollLeft : 0,
scrollTop: typeof _this.props.initialScrollTop === 'number' ? _this.props.initialScrollTop : 0,
scrollUpdateWasRequested: false,
verticalScrollDirection: 'forward'
};
_this._callOnItemsRendered = void 0;
_this._callOnItemsRendered = memoizeOne(function (overscanColumnStartIndex, overscanColumnStopIndex, overscanRowStartIndex, overscanRowStopIndex, visibleColumnStartIndex, visibleColumnStopIndex, visibleRowStartIndex, visibleRowStopIndex) {
return _this.props.onItemsRendered({
overscanColumnStartIndex: overscanColumnStartIndex,
overscanColumnStopIndex: overscanColumnStopIndex,
overscanRowStartIndex: overscanRowStartIndex,
overscanRowStopIndex: overscanRowStopIndex,
visibleColumnStartIndex: visibleColumnStartIndex,
visibleColumnStopIndex: visibleColumnStopIndex,
visibleRowStartIndex: visibleRowStartIndex,
visibleRowStopIndex: visibleRowStopIndex
});
});
_this._callOnScroll = void 0;
_this._callOnScroll = memoizeOne(function (scrollLeft, scrollTop, horizontalScrollDirection, verticalScrollDirection, scrollUpdateWasRequested) {
return _this.props.onScroll({
horizontalScrollDirection: horizontalScrollDirection,
scrollLeft: scrollLeft,
scrollTop: scrollTop,
verticalScrollDirection: verticalScrollDirection,
scrollUpdateWasRequested: scrollUpdateWasRequested
});
});
_this._getItemStyle = void 0;
_this._getItemStyle = function (rowIndex, columnIndex) {
var _this$props = _this.props,
columnWidth = _this$props.columnWidth,
direction = _this$props.direction,
rowHeight = _this$props.rowHeight;
var itemStyleCache = _this._getItemStyleCache(shouldResetStyleCacheOnItemSizeChange && columnWidth, shouldResetStyleCacheOnItemSizeChange && direction, shouldResetStyleCacheOnItemSizeChange && rowHeight);
var key = rowIndex + ":" + columnIndex;
var style;
if (itemStyleCache.hasOwnProperty(key)) {
style = itemStyleCache[key];
} else {
var _style;
itemStyleCache[key] = style = (_style = {
position: 'absolute'
}, _style[direction === 'rtl' ? 'right' : 'left'] = getColumnOffset(_this.props, columnIndex, _this._instanceProps), _style.top = getRowOffset(_this.props, rowIndex, _this._instanceProps), _style.height = getRowHeight(_this.props, rowIndex, _this._instanceProps), _style.width = getColumnWidth(_this.props, columnIndex, _this._instanceProps), _style);
}
return style;
};
_this._getItemStyleCache = void 0;
_this._getItemStyleCache = memoizeOne(function (_, __, ___) {
return {};
});
_this._onScroll = function (event) {
var _event$currentTarget = event.currentTarget,
clientHeight = _event$currentTarget.clientHeight,
clientWidth = _event$currentTarget.clientWidth,
scrollLeft = _event$currentTarget.scrollLeft,
scrollTop = _event$currentTarget.scrollTop,
scrollHeight = _event$currentTarget.scrollHeight,
scrollWidth = _event$currentTarget.scrollWidth;
_this.setState(function (prevState) {
if (prevState.scrollLeft === scrollLeft && prevState.scrollTop === scrollTop) {
// Scroll position may have been updated by cDM/cDU,
// In which case we don't need to trigger another render,
// And we don't want to update state.isScrolling.
return null;
}
var direction = _this.props.direction; // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
// This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
// It's also easier for this component if we convert offsets to the same format as they would be in for ltr.
// So the simplest solution is to determine which browser behavior we're dealing with, and convert based on it.
var calculatedScrollLeft = scrollLeft;
if (direction === 'rtl') {
switch (getRTLOffsetType()) {
case 'negative':
calculatedScrollLeft = -scrollLeft;
break;
case 'positive-descending':
calculatedScrollLeft = scrollWidth - clientWidth - scrollLeft;
break;
}
} // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
calculatedScrollLeft = Math.max(0, Math.min(calculatedScrollLeft, scrollWidth - clientWidth));
var calculatedScrollTop = Math.max(0, Math.min(scrollTop, scrollHeight - clientHeight));
return {
isScrolling: true,
horizontalScrollDirection: prevState.scrollLeft < scrollLeft ? 'forward' : 'backward',
scrollLeft: calculatedScrollLeft,
scrollTop: calculatedScrollTop,
verticalScrollDirection: prevState.scrollTop < scrollTop ? 'forward' : 'backward',
scrollUpdateWasRequested: false
};
}, _this._resetIsScrollingDebounced);
};
_this._outerRefSetter = function (ref) {
var outerRef = _this.props.outerRef;
_this._outerRef = ref;
if (typeof outerRef === 'function') {
outerRef(ref);
} else if (outerRef != null && typeof outerRef === 'object' && outerRef.hasOwnProperty('current')) {
outerRef.current = ref;
}
};
_this._resetIsScrollingDebounced = function () {
if (_this._resetIsScrollingTimeoutId !== null) {
cancelTimeout(_this._resetIsScrollingTimeoutId);
}
_this._resetIsScrollingTimeoutId = requestTimeout(_this._resetIsScrolling, IS_SCROLLING_DEBOUNCE_INTERVAL);
};
_this._resetIsScrolling = function () {
_this._resetIsScrollingTimeoutId = null;
_this.setState({
isScrolling: false
}, function () {
// Clear style cache after state update has been committed.
// This way we don't break pure sCU for items that don't use isScrolling param.
_this._getItemStyleCache(-1);
});
};
return _this;
}
Grid.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, prevState) {
validateSharedProps(nextProps, prevState);
validateProps(nextProps);
return null;
};
var _proto = Grid.prototype;
_proto.scrollTo = function scrollTo(_ref3) {
var scrollLeft = _ref3.scrollLeft,
scrollTop = _ref3.scrollTop;
if (scrollLeft !== undefined) {
scrollLeft = Math.max(0, scrollLeft);
}
if (scrollTop !== undefined) {
scrollTop = Math.max(0, scrollTop);
}
this.setState(function (prevState) {
if (scrollLeft === undefined) {
scrollLeft = prevState.scrollLeft;
}
if (scrollTop === undefined) {
scrollTop = prevState.scrollTop;
}
if (prevState.scrollLeft === scrollLeft && prevState.scrollTop === scrollTop) {
return null;
}
return {
horizontalScrollDirection: prevState.scrollLeft < scrollLeft ? 'forward' : 'backward',
scrollLeft: scrollLeft,
scrollTop: scrollTop,
scrollUpdateWasRequested: true,
verticalScrollDirection: prevState.scrollTop < scrollTop ? 'forward' : 'backward'
};
}, this._resetIsScrollingDebounced);
};
_proto.scrollToItem = function scrollToItem(_ref4) {
var _ref4$align = _ref4.align,
align = _ref4$align === void 0 ? 'auto' : _ref4$align,
columnIndex = _ref4.columnIndex,
rowIndex = _ref4.rowIndex;
var _this$props2 = this.props,
columnCount = _this$props2.columnCount,
height = _this$props2.height,
rowCount = _this$props2.rowCount,
width = _this$props2.width;
var _this$state = this.state,
scrollLeft = _this$state.scrollLeft,
scrollTop = _this$state.scrollTop;
var scrollbarSize = getScrollbarSize();
if (columnIndex !== undefined) {
columnIndex = Math.max(0, Math.min(columnIndex, columnCount - 1));
}
if (rowIndex !== undefined) {
rowIndex = Math.max(0, Math.min(rowIndex, rowCount - 1));
}
var estimatedTotalHeight = getEstimatedTotalHeight(this.props, this._instanceProps);
var estimatedTotalWidth = getEstimatedTotalWidth(this.props, this._instanceProps); // The scrollbar size should be considered when scrolling an item into view,
// to ensure it's fully visible.
// But we only need to account for its size when it's actually visible.
var horizontalScrollbarSize = estimatedTotalWidth > width ? scrollbarSize : 0;
var verticalScrollbarSize = estimatedTotalHeight > height ? scrollbarSize : 0;
this.scrollTo({
scrollLeft: columnIndex !== undefined ? getOffsetForColumnAndAlignment(this.props, columnIndex, align, scrollLeft, this._instanceProps, verticalScrollbarSize) : scrollLeft,
scrollTop: rowIndex !== undefined ? getOffsetForRowAndAlignment(this.props, rowIndex, align, scrollTop, this._instanceProps, horizontalScrollbarSize) : scrollTop
});
};
_proto.componentDidMount = function componentDidMount() {
var _this$props3 = this.props,
initialScrollLeft = _this$props3.initialScrollLeft,
initialScrollTop = _this$props3.initialScrollTop;
if (this._outerRef != null) {
var outerRef = this._outerRef;
if (typeof initialScrollLeft === 'number') {
outerRef.scrollLeft = initialScrollLeft;
}
if (typeof initialScrollTop === 'number') {
outerRef.scrollTop = initialScrollTop;
}
}
this._callPropsCallbacks();
};
_proto.componentDidUpdate = function componentDidUpdate() {
var direction = this.props.direction;
var _this$state2 = this.state,
scrollLeft = _this$state2.scrollLeft,
scrollTop = _this$state2.scrollTop,
scrollUpdateWasRequested = _this$state2.scrollUpdateWasRequested;
if (scrollUpdateWasRequested && this._outerRef != null) {
// TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
// This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
// So we need to determine which browser behavior we're dealing with, and mimic it.
var outerRef = this._outerRef;
if (direction === 'rtl') {
switch (getRTLOffsetType()) {
case 'negative':
outerRef.scrollLeft = -scrollLeft;
break;
case 'positive-ascending':
outerRef.scrollLeft = scrollLeft;
break;
default:
var clientWidth = outerRef.clientWidth,
scrollWidth = outerRef.scrollWidth;
outerRef.scrollLeft = scrollWidth - clientWidth - scrollLeft;
break;
}
} else {
outerRef.scrollLeft = Math.max(0, scrollLeft);
}
outerRef.scrollTop = Math.max(0, scrollTop);
}
this._callPropsCallbacks();
};
_proto.componentWillUnmount = function componentWillUnmount() {
if (this._resetIsScrollingTimeoutId !== null) {
cancelTimeout(this._resetIsScrollingTimeoutId);
}
};
_proto.render = function render() {
var _this$props4 = this.props,
children = _this$props4.children,
className = _this$props4.className,
columnCount = _this$props4.columnCount,
direction = _this$props4.direction,
height = _this$props4.height,
innerRef = _this$props4.innerRef,
innerElementType = _this$props4.innerElementType,
innerTagName = _this$props4.innerTagName,
itemData = _this$props4.itemData,
_this$props4$itemKey = _this$props4.itemKey,
itemKey = _this$props4$itemKey === void 0 ? defaultItemKey : _this$props4$itemKey,
outerElementType = _this$props4.outerElementType,
outerTagName = _this$props4.outerTagName,
rowCount = _this$props4.rowCount,
style = _this$props4.style,
useIsScrolling = _this$props4.useIsScrolling,
width = _this$props4.width;
var isScrolling = this.state.isScrolling;
var _this$_getHorizontalR = this._getHorizontalRangeToRender(),
columnStartIndex = _this$_getHorizontalR[0],
columnStopIndex = _this$_getHorizontalR[1];
var _this$_getVerticalRan = this._getVerticalRangeToRender(),
rowStartIndex = _this$_getVerticalRan[0],
rowStopIndex = _this$_getVerticalRan[1];
var items = [];
if (columnCount > 0 && rowCount) {
for (var _rowIndex = rowStartIndex; _rowIndex <= rowStopIndex; _rowIndex++) {
for (var _columnIndex = columnStartIndex; _columnIndex <= columnStopIndex; _columnIndex++) {
items.push(React.createElement(children, {
columnIndex: _columnIndex,
data: itemData,
isScrolling: useIsScrolling ? isScrolling : undefined,
key: itemKey({
columnIndex: _columnIndex,
data: itemData,
rowIndex: _rowIndex
}),
rowIndex: _rowIndex,
style: this._getItemStyle(_rowIndex, _columnIndex)
}));
}
}
} // Read this value AFTER items have been created,
// So their actual sizes (if variable) are taken into consideration.
var estimatedTotalHeight = getEstimatedTotalHeight(this.props, this._instanceProps);
var estimatedTotalWidth = getEstimatedTotalWidth(this.props, this._instanceProps);
return React.createElement(outerElementType || outerTagName || 'div', {
className: className,
onScroll: this._onScroll,
ref: this._outerRefSetter,
style: _extends$1({
position: 'relative',
height: height,
width: width,
overflow: 'auto',
WebkitOverflowScrolling: 'touch',
willChange: 'transform',
direction: direction
}, style)
}, React.createElement(innerElementType || innerTagName || 'div', {
children: items,
ref: innerRef,
style: {
height: estimatedTotalHeight,
pointerEvents: isScrolling ? 'none' : undefined,
width: estimatedTotalWidth
}
}));
};
_proto._callPropsCallbacks = function _callPropsCallbacks() {
var _this$props5 = this.props,
columnCount = _this$props5.columnCount,
onItemsRendered = _this$props5.onItemsRendered,
onScroll = _this$props5.onScroll,
rowCount = _this$props5.rowCount;
if (typeof onItemsRendered === 'function') {
if (columnCount > 0 && rowCount > 0) {
var _this$_getHorizontalR2 = this._getHorizontalRangeToRender(),
_overscanColumnStartIndex = _this$_getHorizontalR2[0],
_overscanColumnStopIndex = _this$_getHorizontalR2[1],
_visibleColumnStartIndex = _this$_getHorizontalR2[2],
_visibleColumnStopIndex = _this$_getHorizontalR2[3];
var _this$_getVerticalRan2 = this._getVerticalRangeToRender(),
_overscanRowStartIndex = _this$_getVerticalRan2[0],
_overscanRowStopIndex = _this$_getVerticalRan2[1],
_visibleRowStartIndex = _this$_getVerticalRan2[2],
_visibleRowStopIndex = _this$_getVerticalRan2[3];
this._callOnItemsRendered(_overscanColumnStartIndex, _overscanColumnStopIndex, _overscanRowStartIndex, _overscanRowStopIndex, _visibleColumnStartIndex, _visibleColumnStopIndex, _visibleRowStartIndex, _visibleRowStopIndex);
}
}
if (typeof onScroll === 'function') {
var _this$state3 = this.state,
_horizontalScrollDirection = _this$state3.horizontalScrollDirection,
_scrollLeft = _this$state3.scrollLeft,
_scrollTop = _this$state3.scrollTop,
_scrollUpdateWasRequested = _this$state3.scrollUpdateWasRequested,
_verticalScrollDirection = _this$state3.verticalScrollDirection;
this._callOnScroll(_scrollLeft, _scrollTop, _horizontalScrollDirection, _verticalScrollDirection, _scrollUpdateWasRequested);
}
}; // Lazily create and cache item styles while scrolling,
// So that pure component sCU will prevent re-renders.
// We maintain this cache, and pass a style prop rather than index,
// So that List can clear cached styles and force item re-render if necessary.
_proto._getHorizontalRangeToRender = function _getHorizontalRangeToRender() {
var _this$props6 = this.props,
columnCount = _this$props6.columnCount,
overscanColumnCount = _this$props6.overscanColumnCount,
overscanColumnsCount = _this$props6.overscanColumnsCount,
overscanCount = _this$props6.overscanCount,
rowCount = _this$props6.rowCount;
var _this$state4 = this.state,
horizontalScrollDirection = _this$state4.horizontalScrollDirection,
isScrolling = _this$state4.isScrolling,
scrollLeft = _this$state4.scrollLeft;
var overscanCountResolved = overscanColumnCount || overscanColumnsCount || overscanCount || 1;
if (columnCount === 0 || rowCount === 0) {
return [0, 0, 0, 0];
}
var startIndex = getColumnStartIndexForOffset(this.props, scrollLeft, this._instanceProps);
var stopIndex = getColumnStopIndexForStartIndex(this.props, startIndex, scrollLeft, this._instanceProps); // Overscan by one item in each direction so that tab/focus works.
// If there isn't at least one extra item, tab loops back around.
var overscanBackward = !isScrolling || horizontalScrollDirection === 'backward' ? Math.max(1, overscanCountResolved) : 1;
var overscanForward = !isScrolling || horizontalScrollDirection === 'forward' ? Math.max(1, overscanCountResolved) : 1;
return [Math.max(0, startIndex - overscanBackward), Math.max(0, Math.min(columnCount - 1, stopIndex + overscanForward)), startIndex, stopIndex];
};
_proto._getVerticalRangeToRender = function _getVerticalRangeToRender() {
var _this$props7 = this.props,
columnCount = _this$props7.columnCount,
overscanCount = _this$props7.overscanCount,
overscanRowCount = _this$props7.overscanRowCount,
overscanRowsCount = _this$props7.overscanRowsCount,
rowCount = _this$props7.rowCount;
var _this$state5 = this.state,
isScrolling = _this$state5.isScrolling,
verticalScrollDirection = _this$state5.verticalScrollDirection,
scrollTop = _this$state5.scrollTop;
var overscanCountResolved = overscanRowCount || overscanRowsCount || overscanCount || 1;
if (columnCount === 0 || rowCount === 0) {
return [0, 0, 0, 0];
}
var startIndex = getRowStartIndexForOffset(this.props, scrollTop, this._instanceProps);
var stopIndex = getRowStopIndexForStartIndex(this.props, startIndex, scrollTop, this._instanceProps); // Overscan by one item in each direction so that tab/focus works.
// If there isn't at least one extra item, tab loops back around.
var overscanBackward = !isScrolling || verticalScrollDirection === 'backward' ? Math.max(1, overscanCountResolved) : 1;
var overscanForward = !isScrolling || verticalScrollDirection === 'fo