UNPKG

react-column-gallery

Version:
160 lines (150 loc) 6.9 kB
'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); /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var round = function (value, decimals) { if (!decimals) decimals = 0; return Number(Math.round(Number(value + 'e' + decimals)) + 'e-' + decimals); }; var computeColumnLayout = function (photos, columns, containerWidth, spacing, footerHeight) { var horizontalGap = 0; var verticalGap = 0; if (typeof spacing === 'number') { horizontalGap = spacing; verticalGap = spacing; } else { horizontalGap = spacing.horizontal; verticalGap = spacing.vertical; } // calculate each colWidth based on total width and column amount var colWidth = (containerWidth - horizontalGap * (columns - 1)) / columns; // map through each photo to assign adjusted height and width based on colWidth var photosWithSize = photos.map(function (photo) { var newHeight = (photo.height / photo.width) * colWidth; return __assign(__assign({}, photo), { width: round(colWidth, 1), height: round(newHeight, 1), itemHeight: round(newHeight + footerHeight, 1) }); }); // store all possible left positions // and current top positions for each column var colLeftPositions = []; var colCurrTopPositions = []; for (var i = 0; i < columns; i++) { colLeftPositions[i] = round(i * (colWidth + horizontalGap), 1); colCurrTopPositions[i] = 0; } var containerHeight = 0; // map through each photo, then reduce thru each "column" // find column with the smallest height and assign to photo's 'top' // update that column's height with this photo's height var photosPositioned = photosWithSize.map(function (photo) { var smallestCol = colCurrTopPositions.reduce(function (acc, item, i) { acc = item < colCurrTopPositions[acc] ? i : acc; return acc; }, 0); var top = colCurrTopPositions[smallestCol]; var left = colLeftPositions[smallestCol]; colCurrTopPositions[smallestCol] = colCurrTopPositions[smallestCol] + photo.itemHeight + verticalGap; var tallestCol = colCurrTopPositions.reduce(function (acc, item, i) { acc = item > colCurrTopPositions[acc] ? i : acc; return acc; }, 0); containerHeight = colCurrTopPositions[tallestCol]; return __assign(__assign({}, photo), { left: left, top: top }); }); return { photosPositioned: photosPositioned, containerHeight: containerHeight }; }; var defaultColumnsProvider = function (containerWidth) { if (containerWidth >= 1500) { return 4; } else if (containerWidth >= 900) { return 3; } else if (containerWidth > 500) { return 2; } else { return 1; } }; var defaultSpacingProvider = function (containerWidth) { if (containerWidth >= 1500) { return 16; } else if (containerWidth >= 900) { return 12; } else if (containerWidth > 500) { return 8; } else { return 4; } }; var Gallery = function (_a) { var photos = _a.photos, columns = _a.columns, spacing = _a.spacing, initialContainerWidth = _a.initialContainerWidth, footerHeight = _a.footerHeight, renderPhoto = _a.renderPhoto, renderFooter = _a.renderFooter; var _b = React.useState(initialContainerWidth || 0), containerWidth = _b[0], setContainerWidth = _b[1]; var measuredRef = React.useCallback(function (node) { var observer = null; if (node !== null) { setContainerWidth(Math.floor(node.getBoundingClientRect().height)); observer = new ResizeObserver(function (entries) { var newWidth = entries[0].contentRect.width; if (containerWidth !== newWidth) { window.requestAnimationFrame(function () { setContainerWidth(Math.floor(newWidth)); }); } }); observer.observe(node); } }, []); columns = columns || defaultColumnsProvider; if (typeof columns === "function") { columns = columns(containerWidth); } spacing = spacing || defaultSpacingProvider; if (typeof spacing === "function") { spacing = spacing(containerWidth); } var _c = computeColumnLayout(photos, columns, containerWidth, spacing, footerHeight || 0), photosPositioned = _c.photosPositioned, containerHeight = _c.containerHeight; return (React__default.createElement("div", { className: "react-column-gallery" }, React__default.createElement("div", { ref: measuredRef, style: { position: "relative", height: containerHeight, } }, photosPositioned.map(function (p, index) { return (React__default.createElement("div", { key: p.key, className: "photo-wrapper", style: { position: "absolute", left: p.left, top: p.top, width: p.width, height: p.height, } }, renderPhoto ? (renderPhoto(p, index)) : (React__default.createElement("div", { className: "photo-card" }, React__default.createElement("img", { src: p.src, alt: p.alt, loading: p.loading, width: p.width, height: p.height, style: { verticalAlign: 'bottom' } }), renderFooter && renderFooter(p, index))))); })))); }; module.exports = Gallery; //# sourceMappingURL=index.js.map