react-image
Version:
React Image is an <img> tag replacement for react, featuring preloader and multiple image fallback support
125 lines (118 loc) • 4.75 kB
JavaScript
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
var React = require('react');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
// returns a Promisized version of Image() api
var imagePromiseFactory = (function (_ref) {
var _ref$decode = _ref.decode,
decode = _ref$decode === void 0 ? true : _ref$decode,
_ref$crossOrigin = _ref.crossOrigin,
crossOrigin = _ref$crossOrigin === void 0 ? '' : _ref$crossOrigin;
return function (src) {
return new Promise(function (resolve, reject) {
var i = new Image();
if (crossOrigin) i.crossOrigin = crossOrigin;
i.onload = function () {
decode && i.decode ? i.decode().then(resolve)["catch"](reject) : resolve();
};
i.onerror = reject;
i.src = src;
});
};
});
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); 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 = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty__default["default"](target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
var removeBlankArrayElements = function removeBlankArrayElements(a) {
return a.filter(function (x) {
return x;
});
};
var stringToArray = function stringToArray(x) {
return Array.isArray(x) ? x : [x];
};
var cache = {};
// sequential map.find for promises
var promiseFind = function promiseFind(arr, promiseFactory) {
var done = false;
return new Promise(function (resolve, reject) {
var queueNext = function queueNext(src) {
return promiseFactory(src).then(function () {
done = true;
resolve(src);
});
};
arr.reduce(function (p, src) {
// ensure we aren't done before enqueuing the next source
return p["catch"](function () {
if (!done) return queueNext(src);
});
}, queueNext(arr.shift()))["catch"](reject);
});
};
function useImage(_ref) {
var srcList = _ref.srcList,
_ref$imgPromise = _ref.imgPromise,
imgPromise = _ref$imgPromise === void 0 ? imagePromiseFactory({
decode: true
}) : _ref$imgPromise,
_ref$useSuspense = _ref.useSuspense,
useSuspense = _ref$useSuspense === void 0 ? true : _ref$useSuspense;
var _useState = React.useState(false),
setIsSettled = _useState[1];
var sourceList = removeBlankArrayElements(stringToArray(srcList));
var sourceKey = sourceList.join('');
if (!cache[sourceKey]) {
// create promise to loop through sources and try to load one
cache[sourceKey] = {
promise: promiseFind(sourceList, imgPromise),
cache: 'pending',
error: null
};
}
// when promise resolves/reject, update cache & state
if (cache[sourceKey].cache === 'resolved') {
return {
src: cache[sourceKey].src,
isLoading: false,
error: null
};
}
if (cache[sourceKey].cache === 'rejected') {
if (useSuspense) throw cache[sourceKey].error;
return {
isLoading: false,
error: cache[sourceKey].error,
src: undefined
};
}
cache[sourceKey].promise
// if a source was found, update cache
// when not using suspense, update state to force a rerender
.then(function (src) {
cache[sourceKey] = _objectSpread(_objectSpread({}, cache[sourceKey]), {}, {
cache: 'resolved',
src: src
});
if (!useSuspense) setIsSettled(sourceKey);
})
// if no source was found, or if another error occurred, update cache
// when not using suspense, update state to force a rerender
["catch"](function (error) {
cache[sourceKey] = _objectSpread(_objectSpread({}, cache[sourceKey]), {}, {
cache: 'rejected',
error: error
});
if (!useSuspense) setIsSettled(sourceKey);
});
// cache[sourceKey].cache === 'pending')
if (useSuspense) throw cache[sourceKey].promise;
return {
isLoading: true,
src: undefined,
error: null
};
}
exports.imagePromiseFactory = imagePromiseFactory;
exports.useImage = useImage;
//# sourceMappingURL=useImage-10828d6c.js.map
;